|
1
|
|
|
<?php |
|
2
|
|
|
/* For licensing terms, see /license.txt */ |
|
3
|
|
|
|
|
4
|
|
|
use Chamilo\CoreBundle\Entity\ExtraField as EntityExtraField; |
|
5
|
|
|
use Chamilo\CoreBundle\Entity\ExtraFieldValues as EntityExtraFieldValues; |
|
6
|
|
|
use Chamilo\CoreBundle\Entity\GradebookCategory; |
|
7
|
|
|
use Chamilo\CoreBundle\Entity\Session as SessionEntity; |
|
8
|
|
|
use Chamilo\CoreBundle\Entity\SessionRelCourse; |
|
9
|
|
|
use Chamilo\CoreBundle\Entity\User; |
|
10
|
|
|
use Chamilo\CoreBundle\Entity\UserAuthSource; |
|
11
|
|
|
use Chamilo\CoreBundle\Entity\UserRelUser; |
|
12
|
|
|
use Chamilo\CoreBundle\Event\AbstractEvent; |
|
13
|
|
|
use Chamilo\CoreBundle\Event\Events; |
|
14
|
|
|
use Chamilo\CoreBundle\Event\UserCreatedEvent; |
|
15
|
|
|
use Chamilo\CoreBundle\Event\UserUpdatedEvent; |
|
16
|
|
|
use Chamilo\CoreBundle\Framework\Container; |
|
17
|
|
|
use Chamilo\CoreBundle\Repository\LanguageRepository; |
|
18
|
|
|
use Chamilo\CoreBundle\Repository\Node\UserRepository; |
|
19
|
|
|
use Chamilo\CoreBundle\Helpers\NameConventionHelper; |
|
20
|
|
|
use ChamiloSession as Session; |
|
21
|
|
|
use Symfony\Component\HttpFoundation\File\UploadedFile; |
|
22
|
|
|
use Symfony\Contracts\Translation\TranslatorInterface; |
|
23
|
|
|
|
|
24
|
|
|
/** |
|
25
|
|
|
* This library provides functions for user management. |
|
26
|
|
|
* Include/require it in your code to use its functionality. |
|
27
|
|
|
* |
|
28
|
|
|
* @author Julio Montoya <[email protected]> Social network groups added 2009/12 |
|
29
|
|
|
*/ |
|
30
|
|
|
class UserManager |
|
31
|
|
|
{ |
|
32
|
|
|
// This constants are deprecated use the constants located in ExtraField |
|
33
|
|
|
public const USER_FIELD_TYPE_TEXT = 1; |
|
34
|
|
|
public const USER_FIELD_TYPE_TEXTAREA = 2; |
|
35
|
|
|
public const USER_FIELD_TYPE_RADIO = 3; |
|
36
|
|
|
public const USER_FIELD_TYPE_SELECT = 4; |
|
37
|
|
|
public const USER_FIELD_TYPE_SELECT_MULTIPLE = 5; |
|
38
|
|
|
public const USER_FIELD_TYPE_DATE = 6; |
|
39
|
|
|
public const USER_FIELD_TYPE_DATETIME = 7; |
|
40
|
|
|
public const USER_FIELD_TYPE_DOUBLE_SELECT = 8; |
|
41
|
|
|
public const USER_FIELD_TYPE_DIVIDER = 9; |
|
42
|
|
|
public const USER_FIELD_TYPE_TAG = 10; |
|
43
|
|
|
public const USER_FIELD_TYPE_TIMEZONE = 11; |
|
44
|
|
|
public const USER_FIELD_TYPE_SOCIAL_PROFILE = 12; |
|
45
|
|
|
public const USER_FIELD_TYPE_FILE = 13; |
|
46
|
|
|
public const USER_FIELD_TYPE_MOBILE_PHONE_NUMBER = 14; |
|
47
|
|
|
|
|
48
|
|
|
public function __construct() |
|
49
|
|
|
{ |
|
50
|
|
|
} |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* Repository is use to query the DB, selects, etc. |
|
54
|
|
|
* |
|
55
|
|
|
* @return UserRepository |
|
56
|
|
|
*/ |
|
57
|
|
|
public static function getRepository() |
|
58
|
|
|
{ |
|
59
|
|
|
return Container::getUserRepository(); |
|
60
|
|
|
} |
|
61
|
|
|
|
|
62
|
|
|
/** |
|
63
|
|
|
* Validates the password. |
|
64
|
|
|
*/ |
|
65
|
|
|
public static function isPasswordValid(User $user, string $plainPassword): bool |
|
66
|
|
|
{ |
|
67
|
|
|
/** |
|
68
|
|
|
* @psalm-suppress PrivateService |
|
69
|
|
|
*/ |
|
70
|
|
|
$hasher = Container::$container->get('security.user_password_hasher'); |
|
|
|
|
|
|
71
|
|
|
|
|
72
|
|
|
return $hasher->isPasswordValid($user, $plainPassword); |
|
73
|
|
|
} |
|
74
|
|
|
|
|
75
|
|
|
/** |
|
76
|
|
|
* @param int $userId |
|
77
|
|
|
* @param string $password |
|
78
|
|
|
*/ |
|
79
|
|
|
public static function updatePassword($userId, $password) |
|
80
|
|
|
{ |
|
81
|
|
|
$user = api_get_user_entity($userId); |
|
82
|
|
|
$userManager = self::getRepository(); |
|
83
|
|
|
$user->setPlainPassword($password); |
|
84
|
|
|
$userManager->updateUser($user, true); |
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
/** |
|
88
|
|
|
* Creates a new user for the platform. |
|
89
|
|
|
* |
|
90
|
|
|
* @param string $firstName |
|
91
|
|
|
* @param string $lastName |
|
92
|
|
|
* @param int $status (1 for course tutor, 5 for student, 6 for anonymous) |
|
93
|
|
|
* @param string $email |
|
94
|
|
|
* @param string $loginName |
|
95
|
|
|
* @param string $password |
|
96
|
|
|
* @param string $officialCode Any official code (optional) |
|
97
|
|
|
* @param string $language User language (optional) |
|
98
|
|
|
* @param string $phone Phone number (optional) |
|
99
|
|
|
* @param string $pictureUri Picture URI (optional) |
|
100
|
|
|
* @param string $authSources Authentication source (defaults to 'platform', dependind on constant) |
|
101
|
|
|
* @param string $expirationDate Account expiration date (optional, defaults to null) |
|
102
|
|
|
* @param int $active Whether the account is enabled or disabled by default |
|
103
|
|
|
* @param int $hrDeptId The department of HR in which the user is registered (defaults to 0) |
|
104
|
|
|
* @param array $extra Extra fields (labels must be prefixed by "extra_") |
|
105
|
|
|
* @param string $encryptMethod Used if password is given encrypted. Set to an empty string by default |
|
106
|
|
|
* @param bool $sendMail |
|
107
|
|
|
* @param bool $isAdmin |
|
108
|
|
|
* @param string $address |
|
109
|
|
|
* @param bool $sendEmailToAllAdmins |
|
110
|
|
|
* @param FormValidator $form |
|
111
|
|
|
* @param int $creatorId |
|
112
|
|
|
* @param array $emailTemplate |
|
113
|
|
|
* @param string $redirectToURLAfterLogin |
|
114
|
|
|
* |
|
115
|
|
|
* @return mixed new user id - if the new user creation succeeds, false otherwise |
|
116
|
|
|
* @desc The function tries to retrieve user id from the session. |
|
117
|
|
|
* If it exists, the current user id is the creator id. If a problem arises, |
|
118
|
|
|
* @assert ('Sam','Gamegie',5,'[email protected]','jo','jo') > 1 |
|
119
|
|
|
* @assert ('Pippin','Took',null,null,'jo','jo') === false |
|
120
|
|
|
*@author Hugues Peeters <[email protected]>, |
|
121
|
|
|
* @author Roan Embrechts <[email protected]> |
|
122
|
|
|
* |
|
123
|
|
|
*/ |
|
124
|
|
|
public static function create_user( |
|
125
|
|
|
$firstName, |
|
126
|
|
|
$lastName, |
|
127
|
|
|
$status, |
|
128
|
|
|
$email, |
|
129
|
|
|
$loginName, |
|
130
|
|
|
$password, |
|
131
|
|
|
$officialCode = '', |
|
132
|
|
|
$language = '', |
|
133
|
|
|
$phone = '', |
|
134
|
|
|
$pictureUri = '', |
|
135
|
|
|
?array $authSources = [], |
|
136
|
|
|
$expirationDate = null, |
|
137
|
|
|
$active = 1, |
|
138
|
|
|
$hrDeptId = 0, |
|
139
|
|
|
$extra = [], |
|
140
|
|
|
$encryptMethod = '', |
|
141
|
|
|
$sendMail = false, |
|
142
|
|
|
$isAdmin = false, |
|
143
|
|
|
$address = '', |
|
144
|
|
|
$sendEmailToAllAdmins = false, |
|
145
|
|
|
$form = null, |
|
146
|
|
|
$creatorId = 0, |
|
147
|
|
|
$emailTemplate = [], |
|
148
|
|
|
$redirectToURLAfterLogin = '' |
|
149
|
|
|
) { |
|
150
|
|
|
$authSources = !empty($authSources) ? $authSources : [UserAuthSource::PLATFORM]; |
|
151
|
|
|
$creatorId = empty($creatorId) ? api_get_user_id() : $creatorId; |
|
152
|
|
|
|
|
153
|
|
|
if (0 === $creatorId) { |
|
154
|
|
|
Display::addFlash( |
|
155
|
|
|
Display::return_message(get_lang('A user creator is required')) |
|
156
|
|
|
); |
|
157
|
|
|
|
|
158
|
|
|
return false; |
|
159
|
|
|
} |
|
160
|
|
|
|
|
161
|
|
|
$creatorInfo = api_get_user_info($creatorId); |
|
162
|
|
|
$creatorEmail = $creatorInfo['email'] ?? ''; |
|
163
|
|
|
|
|
164
|
|
|
// First check if the login exists. |
|
165
|
|
|
if (!Container::getUserRepository()->isUsernameAvailable($loginName)) { |
|
166
|
|
|
Display::addFlash( |
|
167
|
|
|
Display::return_message(get_lang('This login is already taken !')) |
|
168
|
|
|
); |
|
169
|
|
|
|
|
170
|
|
|
return false; |
|
171
|
|
|
} |
|
172
|
|
|
|
|
173
|
|
|
Container::getEventDispatcher() |
|
174
|
|
|
->dispatch( |
|
175
|
|
|
new UserCreatedEvent([], AbstractEvent::TYPE_PRE), |
|
176
|
|
|
Events::USER_CREATED |
|
177
|
|
|
) |
|
178
|
|
|
; |
|
179
|
|
|
|
|
180
|
|
|
$original_password = $password; |
|
181
|
|
|
|
|
182
|
|
|
$accessUrl = Container::getAccessUrlUtil()->getCurrent(); |
|
183
|
|
|
$access_url_id = $accessUrl->getId(); |
|
184
|
|
|
|
|
185
|
|
|
$hostingLimitUsers = get_hosting_limit($access_url_id, 'users'); |
|
186
|
|
|
|
|
187
|
|
|
if ($hostingLimitUsers !== null && $hostingLimitUsers > 0) { |
|
188
|
|
|
$num = self::get_number_of_users(); |
|
189
|
|
|
if ($num >= $hostingLimitUsers) { |
|
190
|
|
|
api_warn_hosting_contact('users'); |
|
191
|
|
|
Display::addFlash( |
|
192
|
|
|
Display::return_message( |
|
193
|
|
|
get_lang('Sorry, this installation has a users limit, which has now been reached. To increase the number of users allowed on this Chamilo installation, please contact your hosting provider or, if available, upgrade to a superior hosting plan.'), |
|
194
|
|
|
'warning' |
|
195
|
|
|
) |
|
196
|
|
|
); |
|
197
|
|
|
|
|
198
|
|
|
return false; |
|
199
|
|
|
} |
|
200
|
|
|
} |
|
201
|
|
|
|
|
202
|
|
|
if (1 === $status) { |
|
203
|
|
|
$hostingLimitTeachers = get_hosting_limit($access_url_id, 'teachers'); |
|
204
|
|
|
|
|
205
|
|
|
if ($hostingLimitTeachers !== null && $hostingLimitTeachers > 0) { |
|
206
|
|
|
$num = self::get_number_of_users(1); |
|
207
|
|
|
if ($num >= $hostingLimitTeachers) { |
|
208
|
|
|
Display::addFlash( |
|
209
|
|
|
Display::return_message( |
|
210
|
|
|
get_lang('Sorry, this installation has a teachers limit, which has now been reached. To increase the number of teachers allowed on this Chamilo installation, please contact your hosting provider or, if available, upgrade to a superior hosting plan.'), |
|
211
|
|
|
'warning' |
|
212
|
|
|
) |
|
213
|
|
|
); |
|
214
|
|
|
api_warn_hosting_contact('hosting_limit_teachers'); |
|
215
|
|
|
|
|
216
|
|
|
return false; |
|
217
|
|
|
} |
|
218
|
|
|
} |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
if (empty($password)) { |
|
222
|
|
|
if (in_array(UserAuthSource::PLATFORM, $authSources)) { |
|
223
|
|
|
Display::addFlash( |
|
224
|
|
|
Display::return_message( |
|
225
|
|
|
get_lang('Required field').': '.get_lang( |
|
226
|
|
|
'Password' |
|
227
|
|
|
), |
|
228
|
|
|
'warning' |
|
229
|
|
|
) |
|
230
|
|
|
); |
|
231
|
|
|
|
|
232
|
|
|
return false; |
|
233
|
|
|
} |
|
234
|
|
|
// Use authSource as pseudo-password (validated by external auth). |
|
235
|
|
|
$password = $authSources; |
|
236
|
|
|
} |
|
237
|
|
|
|
|
238
|
|
|
// Checking the user language |
|
239
|
|
|
$languages = api_get_languages(); |
|
240
|
|
|
if (!in_array($language, array_keys($languages), true)) { |
|
241
|
|
|
$language = 'en_US'; // default |
|
242
|
|
|
} |
|
243
|
|
|
|
|
244
|
|
|
$now = new DateTime(); |
|
245
|
|
|
if (empty($expirationDate) || '0000-00-00 00:00:00' === $expirationDate) { |
|
246
|
|
|
$expirationDate = null; |
|
247
|
|
|
} else { |
|
248
|
|
|
$expirationDate = api_get_utc_datetime($expirationDate, true, true); |
|
249
|
|
|
} |
|
250
|
|
|
|
|
251
|
|
|
$repo = Container::getUserRepository(); |
|
252
|
|
|
$user = $repo->createUser() |
|
253
|
|
|
->setLastname($lastName) |
|
254
|
|
|
->setFirstname($firstName) |
|
255
|
|
|
->setUsername($loginName) |
|
256
|
|
|
->setStatus($status) |
|
257
|
|
|
->setPlainPassword($password) |
|
258
|
|
|
->setEmail($email) |
|
259
|
|
|
->setOfficialCode($officialCode) |
|
260
|
|
|
->setCreatorId($creatorId) |
|
261
|
|
|
->setPhone($phone) |
|
262
|
|
|
->setAddress($address) |
|
263
|
|
|
->setLocale($language) |
|
264
|
|
|
->setHrDeptId($hrDeptId) |
|
265
|
|
|
->setActive($active) |
|
266
|
|
|
->setTimezone(api_get_timezone()) |
|
267
|
|
|
; |
|
268
|
|
|
|
|
269
|
|
|
foreach ($authSources as $authSource) { |
|
270
|
|
|
$user->addAuthSourceByAuthentication($authSource, $accessUrl); |
|
271
|
|
|
} |
|
272
|
|
|
|
|
273
|
|
|
if (null !== $expirationDate) { |
|
274
|
|
|
$user->setExpirationDate($expirationDate); |
|
275
|
|
|
} |
|
276
|
|
|
|
|
277
|
|
|
$user->setRoleFromStatus($status); |
|
278
|
|
|
$dobStr = $_POST['date_of_birth'] ?? null; |
|
279
|
|
|
if ($dobStr) { |
|
280
|
|
|
$dob = \DateTime::createFromFormat('Y-m-d', $dobStr) |
|
281
|
|
|
?: \DateTime::createFromFormat('d/m/Y', $dobStr) |
|
282
|
|
|
?: \DateTime::createFromFormat('d-m-Y', $dobStr); |
|
283
|
|
|
|
|
284
|
|
|
if ($dob instanceof \DateTime) { |
|
|
|
|
|
|
285
|
|
|
$user->setDateOfBirth($dob); |
|
286
|
|
|
} |
|
287
|
|
|
} |
|
288
|
|
|
|
|
289
|
|
|
$repo->updateUser($user, true); |
|
290
|
|
|
$userId = $user->getId(); |
|
291
|
|
|
|
|
292
|
|
|
if (empty($userId)) { |
|
293
|
|
|
Display::addFlash( |
|
294
|
|
|
Display::return_message(get_lang('There happened an unknown error. Please contact the platform administrator.')) |
|
295
|
|
|
); |
|
296
|
|
|
return false; |
|
297
|
|
|
} |
|
298
|
|
|
|
|
299
|
|
|
$userLocale = $user->getLocale(); |
|
300
|
|
|
if ($isAdmin) { |
|
301
|
|
|
self::addUserAsAdmin($user); |
|
302
|
|
|
} |
|
303
|
|
|
|
|
304
|
|
|
if (api_get_multiple_access_url()) { |
|
305
|
|
|
UrlManager::add_user_to_url($userId, api_get_current_access_url_id()); |
|
306
|
|
|
} else { |
|
307
|
|
|
UrlManager::add_user_to_url($userId, 1); |
|
308
|
|
|
} |
|
309
|
|
|
|
|
310
|
|
|
if (is_array($extra) && count($extra) > 0) { |
|
311
|
|
|
$extra['item_id'] = $userId; |
|
312
|
|
|
$userFieldValue = new ExtraFieldValue('user'); |
|
313
|
|
|
/* Force saving of extra fields (otherwise, if the current |
|
314
|
|
|
 user is not admin, fields not visible to the user - most |
|
315
|
|
|
 of them - are just ignored) */ |
|
316
|
|
|
$userFieldValue->saveFieldValues( |
|
317
|
|
|
$extra, |
|
318
|
|
|
true, |
|
319
|
|
|
false, |
|
320
|
|
|
[], |
|
321
|
|
|
[], |
|
322
|
|
|
true |
|
323
|
|
|
); |
|
324
|
|
|
} else { |
|
325
|
|
|
// Create notify settings by default |
|
326
|
|
|
self::update_extra_field_value( |
|
327
|
|
|
$userId, |
|
328
|
|
|
'mail_notify_invitation', |
|
329
|
|
|
'1' |
|
330
|
|
|
); |
|
331
|
|
|
self::update_extra_field_value( |
|
332
|
|
|
$userId, |
|
333
|
|
|
'mail_notify_message', |
|
334
|
|
|
'1' |
|
335
|
|
|
); |
|
336
|
|
|
self::update_extra_field_value( |
|
337
|
|
|
$userId, |
|
338
|
|
|
'mail_notify_group_message', |
|
339
|
|
|
'1' |
|
340
|
|
|
); |
|
341
|
|
|
} |
|
342
|
|
|
|
|
343
|
|
|
self::update_extra_field_value( |
|
344
|
|
|
$userId, |
|
345
|
|
|
'already_logged_in', |
|
346
|
|
|
'false' |
|
347
|
|
|
); |
|
348
|
|
|
|
|
349
|
|
|
if (!empty($redirectToURLAfterLogin) && ('true' === api_get_setting('workflows.plugin_redirection_enabled'))) { |
|
350
|
|
|
RedirectionPlugin::insert($userId, $redirectToURLAfterLogin); |
|
351
|
|
|
} |
|
352
|
|
|
|
|
353
|
|
|
if (!empty($email) && $sendMail) { |
|
354
|
|
|
$recipient_name = api_get_person_name( |
|
355
|
|
|
$firstName, |
|
356
|
|
|
$lastName, |
|
357
|
|
|
null, |
|
358
|
|
|
PERSON_NAME_EMAIL_ADDRESS |
|
359
|
|
|
); |
|
360
|
|
|
$tpl = Container::getTwig(); |
|
361
|
|
|
$emailSubject = $tpl->render('@ChamiloCore/Mailer/Legacy/subject_registration_platform.html.twig', ['locale' => $userLocale]); |
|
362
|
|
|
$sender_name = api_get_person_name( |
|
363
|
|
|
api_get_setting('administratorName'), |
|
364
|
|
|
api_get_setting('administratorSurname'), |
|
365
|
|
|
null, |
|
366
|
|
|
PERSON_NAME_EMAIL_ADDRESS |
|
367
|
|
|
); |
|
368
|
|
|
$email_admin = api_get_setting('emailAdministrator'); |
|
369
|
|
|
|
|
370
|
|
|
$url = api_get_path(WEB_PATH); |
|
371
|
|
|
if (api_is_multiple_url_enabled()) { |
|
|
|
|
|
|
372
|
|
|
$access_url_id = api_get_current_access_url_id(); |
|
373
|
|
|
if (-1 != $access_url_id) { |
|
374
|
|
|
$urlInfo = api_get_access_url($access_url_id); |
|
375
|
|
|
if ($urlInfo) { |
|
|
|
|
|
|
376
|
|
|
$url = $urlInfo['url']; |
|
377
|
|
|
} |
|
378
|
|
|
} |
|
379
|
|
|
} |
|
380
|
|
|
|
|
381
|
|
|
// variables for the default template |
|
382
|
|
|
$params = [ |
|
383
|
|
|
'complete_name' => stripslashes(api_get_person_name($firstName, $lastName)), |
|
384
|
|
|
'login_name' => $loginName, |
|
385
|
|
|
'original_password' => stripslashes($original_password), |
|
386
|
|
|
'mailWebPath' => $url, |
|
387
|
|
|
'new_user' => $user, |
|
388
|
|
|
'search_link' => $url, |
|
389
|
|
|
'locale' => $userLocale, |
|
390
|
|
|
]; |
|
391
|
|
|
|
|
392
|
|
|
// ofaj |
|
393
|
|
|
if ('true' === api_get_setting('session.allow_search_diagnostic')) { |
|
394
|
|
|
$urlSearch = api_get_path(WEB_CODE_PATH).'search/search.php'; |
|
395
|
|
|
$linkSearch = Display::url($urlSearch, $urlSearch); |
|
396
|
|
|
$params['search_link'] = $linkSearch; |
|
397
|
|
|
} |
|
398
|
|
|
|
|
399
|
|
|
$emailBody = $tpl->render( |
|
400
|
|
|
'@ChamiloCore/Mailer/Legacy/content_registration_platform.html.twig', |
|
401
|
|
|
$params |
|
402
|
|
|
); |
|
403
|
|
|
|
|
404
|
|
|
$userInfo = api_get_user_info($userId); |
|
405
|
|
|
$mailTemplateManager = new MailTemplateManager(); |
|
406
|
|
|
$phoneNumber = $extra['mobile_phone_number'] ?? null; |
|
407
|
|
|
|
|
408
|
|
|
$emailBodyTemplate = ''; |
|
409
|
|
|
if (!empty($emailTemplate)) { |
|
410
|
|
|
if (isset($emailTemplate['content_registration_platform.tpl']) && |
|
411
|
|
|
!empty($emailTemplate['content_registration_platform.tpl']) |
|
412
|
|
|
) { |
|
413
|
|
|
$emailBodyTemplate = $mailTemplateManager->parseTemplate( |
|
414
|
|
|
$emailTemplate['content_registration_platform.tpl'], |
|
415
|
|
|
$userInfo |
|
416
|
|
|
); |
|
417
|
|
|
} |
|
418
|
|
|
} |
|
419
|
|
|
|
|
420
|
|
|
$twoEmail = ('true' === api_get_setting('mail.send_two_inscription_confirmation_mail')); |
|
421
|
|
|
if (true === $twoEmail) { |
|
422
|
|
|
$emailBody = $tpl->render('@ChamiloCore/Mailer/Legacy/new_user_first_email_confirmation.html.twig'); |
|
423
|
|
|
if (!empty($emailBodyTemplate) && |
|
424
|
|
|
isset($emailTemplate['new_user_first_email_confirmation.tpl']) && |
|
425
|
|
|
!empty($emailTemplate['new_user_first_email_confirmation.tpl']) |
|
426
|
|
|
) { |
|
427
|
|
|
$emailBody = $mailTemplateManager->parseTemplate( |
|
428
|
|
|
$emailTemplate['new_user_first_email_confirmation.tpl'], |
|
429
|
|
|
$userInfo |
|
430
|
|
|
); |
|
431
|
|
|
} |
|
432
|
|
|
|
|
433
|
|
|
api_mail_html( |
|
434
|
|
|
$recipient_name, |
|
435
|
|
|
$email, |
|
436
|
|
|
$emailSubject, |
|
437
|
|
|
$emailBody, |
|
438
|
|
|
$sender_name, |
|
439
|
|
|
$email_admin, |
|
440
|
|
|
[], |
|
441
|
|
|
[], |
|
442
|
|
|
false, |
|
443
|
|
|
[], |
|
444
|
|
|
$creatorEmail |
|
445
|
|
|
); |
|
446
|
|
|
|
|
447
|
|
|
$emailBody = $tpl->render('@ChamiloCore/Mailer/Legacy/new_user_second_email_confirmation.html.twig'); |
|
448
|
|
|
if (!empty($emailBodyTemplate) && |
|
449
|
|
|
isset($emailTemplate['new_user_second_email_confirmation.tpl']) && |
|
450
|
|
|
!empty($emailTemplate['new_user_second_email_confirmation.tpl']) |
|
451
|
|
|
) { |
|
452
|
|
|
$emailBody = $mailTemplateManager->parseTemplate( |
|
453
|
|
|
$emailTemplate['new_user_second_email_confirmation.tpl'], |
|
454
|
|
|
$userInfo |
|
455
|
|
|
); |
|
456
|
|
|
} |
|
457
|
|
|
|
|
458
|
|
|
api_mail_html( |
|
459
|
|
|
$recipient_name, |
|
460
|
|
|
$email, |
|
461
|
|
|
$emailSubject, |
|
462
|
|
|
$emailBody, |
|
463
|
|
|
$sender_name, |
|
464
|
|
|
$email_admin, |
|
465
|
|
|
null, |
|
466
|
|
|
null, |
|
467
|
|
|
null, |
|
468
|
|
|
[], |
|
469
|
|
|
$creatorEmail |
|
470
|
|
|
); |
|
471
|
|
|
} else { |
|
472
|
|
|
if (!empty($emailBodyTemplate)) { |
|
473
|
|
|
$emailBody = $emailBodyTemplate; |
|
474
|
|
|
} |
|
475
|
|
|
$sendToInbox = ('true' === api_get_setting('registration.send_inscription_msg_to_inbox')); |
|
476
|
|
|
if ($sendToInbox) { |
|
477
|
|
|
$adminList = self::get_all_administrators(); |
|
478
|
|
|
$senderId = 1; |
|
479
|
|
|
if (!empty($adminList)) { |
|
480
|
|
|
$adminInfo = current($adminList); |
|
481
|
|
|
$senderId = $adminInfo['user_id']; |
|
482
|
|
|
} |
|
483
|
|
|
|
|
484
|
|
|
MessageManager::send_message_simple( |
|
485
|
|
|
$userId, |
|
486
|
|
|
$emailSubject, |
|
487
|
|
|
$emailBody, |
|
488
|
|
|
$senderId |
|
489
|
|
|
); |
|
490
|
|
|
} else { |
|
491
|
|
|
api_mail_html( |
|
492
|
|
|
$recipient_name, |
|
493
|
|
|
$email, |
|
494
|
|
|
$emailSubject, |
|
495
|
|
|
$emailBody, |
|
496
|
|
|
$sender_name, |
|
497
|
|
|
$email_admin, |
|
498
|
|
|
[], |
|
499
|
|
|
[], |
|
500
|
|
|
false, |
|
501
|
|
|
[], |
|
502
|
|
|
$creatorEmail |
|
503
|
|
|
); |
|
504
|
|
|
} |
|
505
|
|
|
} |
|
506
|
|
|
|
|
507
|
|
|
$notification = api_get_setting('profile.send_notification_when_user_added', true); |
|
508
|
|
|
if (!empty($notification) && isset($notification['admins']) && is_array($notification['admins'])) { |
|
509
|
|
|
foreach ($notification['admins'] as $adminId) { |
|
510
|
|
|
$emailSubjectToAdmin = get_lang('The user has been added').': '. |
|
511
|
|
|
api_get_person_name($firstName, $lastName); |
|
512
|
|
|
MessageManager::send_message_simple($adminId, $emailSubjectToAdmin, $emailBody, $userId); |
|
513
|
|
|
} |
|
514
|
|
|
} |
|
515
|
|
|
|
|
516
|
|
|
/** @var TranslatorInterface $translator */ |
|
517
|
|
|
$translator = Container::$container->get('translator'); |
|
518
|
|
|
$currentLocale = $translator->getLocale(); |
|
519
|
|
|
|
|
520
|
|
|
$visibleCoreFields = []; |
|
521
|
|
|
$visibleExtraVars = []; |
|
522
|
|
|
|
|
523
|
|
|
if ($form) { |
|
524
|
|
|
$formNames = []; |
|
525
|
|
|
if (property_exists($form, '_elements') && is_array($form->_elements)) { |
|
526
|
|
|
foreach ($form->_elements as $el) { |
|
527
|
|
|
if (is_object($el) && method_exists($el, 'getName')) { |
|
528
|
|
|
$formNames[] = (string) $el->getName(); |
|
529
|
|
|
} |
|
530
|
|
|
} |
|
531
|
|
|
} |
|
532
|
|
|
|
|
533
|
|
|
$cfg = api_get_setting('registration.allow_fields_inscription', true); |
|
534
|
|
|
$cfgCore = (is_array($cfg) && isset($cfg['fields']) && is_array($cfg['fields'])) |
|
535
|
|
|
? $cfg['fields'] |
|
536
|
|
|
: []; |
|
537
|
|
|
|
|
538
|
|
|
$visibleCoreFields = array_values(array_intersect($cfgCore, $formNames)); |
|
539
|
|
|
|
|
540
|
|
|
foreach ($formNames as $n) { |
|
541
|
|
|
if (strpos($n, 'extra_') === 0) { |
|
542
|
|
|
$visibleExtraVars[] = substr($n, 6); |
|
543
|
|
|
} |
|
544
|
|
|
} |
|
545
|
|
|
} |
|
546
|
|
|
|
|
547
|
|
|
if ($sendEmailToAllAdmins) { |
|
548
|
|
|
$adminList = self::get_all_administrators(); |
|
549
|
|
|
$url = api_get_path(WEB_CODE_PATH).'admin/user_information.php?user_id='.$user->getId(); |
|
550
|
|
|
|
|
551
|
|
|
foreach ($adminList as $adminId => $adminData) { |
|
552
|
|
|
$adminLocale = $adminData['locale'] ?? 'en_US'; |
|
553
|
|
|
$translator->setLocale($adminLocale); |
|
554
|
|
|
|
|
555
|
|
|
$profileHtml = self::renderRegistrationProfileHtml( |
|
556
|
|
|
$user, |
|
557
|
|
|
$extra ?? [], |
|
558
|
|
|
$adminLocale, |
|
559
|
|
|
$visibleCoreFields, |
|
560
|
|
|
$visibleExtraVars |
|
561
|
|
|
); |
|
562
|
|
|
$userLanguageName = self::resolveLanguageName($user->getLocale()); |
|
563
|
|
|
|
|
564
|
|
|
$paramsAdmin = [ |
|
565
|
|
|
'complete_name' => stripslashes(api_get_person_name($firstName, $lastName)), |
|
566
|
|
|
'user_added' => $user, |
|
567
|
|
|
'link' => Display::url($url, $url), |
|
568
|
|
|
'form' => $profileHtml, |
|
569
|
|
|
'user_language' => $userLanguageName, |
|
570
|
|
|
]; |
|
571
|
|
|
|
|
572
|
|
|
$emailBodyAdmin = $tpl->render( |
|
573
|
|
|
'@ChamiloCore/Mailer/Legacy/content_registration_platform_to_admin.html.twig', |
|
574
|
|
|
$paramsAdmin |
|
575
|
|
|
); |
|
576
|
|
|
|
|
577
|
|
|
$subject = get_lang('The user has been added', $adminLocale); |
|
578
|
|
|
MessageManager::send_message_simple( |
|
579
|
|
|
$adminId, |
|
580
|
|
|
$subject, |
|
581
|
|
|
$emailBodyAdmin, |
|
582
|
|
|
$userId |
|
583
|
|
|
); |
|
584
|
|
|
|
|
585
|
|
|
$translator->setLocale($currentLocale); |
|
586
|
|
|
} |
|
587
|
|
|
} |
|
588
|
|
|
} |
|
589
|
|
|
|
|
590
|
|
|
Container::getEventDispatcher() |
|
591
|
|
|
->dispatch( |
|
592
|
|
|
new UserCreatedEvent( |
|
593
|
|
|
['return' => $user, 'originalPassword' => $original_password], |
|
594
|
|
|
AbstractEvent::TYPE_POST |
|
595
|
|
|
), |
|
596
|
|
|
Events::USER_CREATED |
|
597
|
|
|
) |
|
598
|
|
|
; |
|
599
|
|
|
|
|
600
|
|
|
Event::addEvent(LOG_USER_CREATE, LOG_USER_ID, $userId, null, $creatorId); |
|
|
|
|
|
|
601
|
|
|
|
|
602
|
|
|
return $userId; |
|
603
|
|
|
} |
|
604
|
|
|
|
|
605
|
|
|
/** |
|
606
|
|
|
* Returns the human-readable language name for a given ISO code. |
|
607
|
|
|
* |
|
608
|
|
|
* Accepts ISO 639-1/2 codes (e.g. "en", "es", "eng"). If $iso is null or the |
|
609
|
|
|
* code is unknown, an empty string is returned. |
|
610
|
|
|
* |
|
611
|
|
|
* @param string|null $iso Two- or three-letter ISO 639 language code. |
|
612
|
|
|
* @return string Language name in English (e.g. "English", "Spanish"). |
|
613
|
|
|
*/ |
|
614
|
|
|
private static function resolveLanguageName(?string $iso): string |
|
615
|
|
|
{ |
|
616
|
|
|
if (empty($iso)) { |
|
617
|
|
|
return ''; |
|
618
|
|
|
} |
|
619
|
|
|
|
|
620
|
|
|
/** @var LanguageRepository $langRepo */ |
|
621
|
|
|
$langRepo = Container::$container->get(LanguageRepository::class); |
|
622
|
|
|
$entity = $langRepo->findOneBy(['isocode' => $iso]); |
|
623
|
|
|
|
|
624
|
|
|
return $entity ? $entity->getOriginalName() : $iso; |
|
625
|
|
|
} |
|
626
|
|
|
|
|
627
|
|
|
/** |
|
628
|
|
|
* Build the “profile” HTML (core + dynamic extra fields) for the admin email, located in $adminLocale. |
|
629
|
|
|
* |
|
630
|
|
|
* @param User $user |
|
631
|
|
|
* @param array $extraParams Raw POST values from registration (keys: "extra_*"). |
|
632
|
|
|
* @param string $adminLocale e.g. "es_ES", "fr_FR". |
|
633
|
|
|
* @param array $visibleCoreFields Visible core names (email, firstname, status, date_of_birth, etc.) |
|
634
|
|
|
* @param array $visibleExtraVars Visible extra variables (without the "extra_" prefix) |
|
635
|
|
|
*/ |
|
636
|
|
|
private static function renderRegistrationProfileHtml( |
|
637
|
|
|
User $user, |
|
638
|
|
|
array $extraParams, |
|
639
|
|
|
string $adminLocale, |
|
640
|
|
|
array $visibleCoreFields = [], |
|
641
|
|
|
array $visibleExtraVars = [] |
|
642
|
|
|
): string { |
|
643
|
|
|
$showAllCore = empty($visibleCoreFields); |
|
644
|
|
|
$showAllExtra = empty($visibleExtraVars); |
|
645
|
|
|
|
|
646
|
|
|
$coreVisible = array_fill_keys($visibleCoreFields, true); |
|
647
|
|
|
$extraVisible = array_fill_keys($visibleExtraVars, true); |
|
648
|
|
|
|
|
649
|
|
|
$languageName = self::resolveLanguageName($user->getLocale()); |
|
650
|
|
|
|
|
651
|
|
|
$corePairs = []; |
|
652
|
|
|
|
|
653
|
|
|
if ($showAllCore || !empty($coreVisible['email'])) { |
|
654
|
|
|
$corePairs[get_lang('E-mail', $adminLocale)] = $user->getEmail(); |
|
655
|
|
|
} |
|
656
|
|
|
if ($showAllCore || !empty($coreVisible['firstname'])) { |
|
657
|
|
|
$corePairs[get_lang('First name', $adminLocale)] = (string) $user->getFirstname(); |
|
658
|
|
|
} |
|
659
|
|
|
if ($showAllCore || !empty($coreVisible['lastname'])) { |
|
660
|
|
|
$corePairs[get_lang('Last name', $adminLocale)] = (string) $user->getLastname(); |
|
661
|
|
|
} |
|
662
|
|
|
if ($showAllCore || !empty($coreVisible['username'])) { |
|
663
|
|
|
$corePairs[get_lang('Username', $adminLocale)] = $user->getUsername(); |
|
664
|
|
|
} |
|
665
|
|
|
if ($showAllCore || !empty($coreVisible['official_code'])) { |
|
666
|
|
|
$corePairs[get_lang('Official code', $adminLocale)] = $user->getOfficialCode() ?? ''; |
|
667
|
|
|
} |
|
668
|
|
|
if ($showAllCore || !empty($coreVisible['phone'])) { |
|
669
|
|
|
$corePairs[get_lang('Phone', $adminLocale)] = $user->getPhone() ?? ''; |
|
670
|
|
|
} |
|
671
|
|
|
if ($showAllCore || !empty($coreVisible['address'])) { |
|
672
|
|
|
$corePairs[get_lang('User address', $adminLocale)] = $user->getAddress() ?? ''; |
|
673
|
|
|
} |
|
674
|
|
|
if ($showAllCore || !empty($coreVisible['language'])) { |
|
675
|
|
|
$corePairs[get_lang('Language', $adminLocale)] = $languageName; |
|
676
|
|
|
} |
|
677
|
|
|
|
|
678
|
|
|
if ($showAllCore || !empty($coreVisible['status'])) { |
|
679
|
|
|
$statusLabel = ((int) $user->getStatus() === COURSEMANAGER) |
|
680
|
|
|
? get_lang('Teach courses', $adminLocale) |
|
681
|
|
|
: get_lang('Follow courses', $adminLocale); |
|
682
|
|
|
$corePairs[get_lang('What do you want to do?', $adminLocale)] = $statusLabel; |
|
683
|
|
|
} |
|
684
|
|
|
|
|
685
|
|
|
if (($showAllCore || !empty($coreVisible['date_of_birth'])) && |
|
686
|
|
|
$user->getDateOfBirth() instanceof \DateTimeInterface |
|
687
|
|
|
) { |
|
688
|
|
|
$corePairs[get_lang('Date of birth', $adminLocale)] = $user->getDateOfBirth()->format('Y-m-d'); |
|
689
|
|
|
} |
|
690
|
|
|
|
|
691
|
|
|
$efv = new \ExtraFieldValue('user'); |
|
692
|
|
|
$ef = new \ExtraField('user'); |
|
693
|
|
|
|
|
694
|
|
|
$extraPairs = []; |
|
695
|
|
|
$presentVars = []; |
|
696
|
|
|
$rows = $efv->getAllValuesByItem((int) $user->getId()); |
|
697
|
|
|
|
|
698
|
|
|
if (is_array($rows)) { |
|
699
|
|
|
foreach ($rows as $row) { |
|
700
|
|
|
$fieldId = (int)$row['id']; |
|
701
|
|
|
$variable = (string)$row['variable']; |
|
702
|
|
|
$presentVars[$variable] = true; |
|
703
|
|
|
|
|
704
|
|
|
if (!$showAllExtra && empty($extraVisible[$variable])) { |
|
705
|
|
|
continue; |
|
706
|
|
|
} |
|
707
|
|
|
|
|
708
|
|
|
$tr = $efv->get_values_by_handler_and_field_id((int) $user->getId(), $fieldId, true); |
|
709
|
|
|
$val = null; |
|
710
|
|
|
|
|
711
|
|
|
if ($tr && array_key_exists('value', $tr)) { |
|
712
|
|
|
$val = $tr['value']; |
|
713
|
|
|
} else { |
|
714
|
|
|
$val = $row['value']; |
|
715
|
|
|
} |
|
716
|
|
|
|
|
717
|
|
|
$type = (int)$row['value_type']; |
|
718
|
|
|
if ($type === \ExtraField::FIELD_TYPE_CHECKBOX) { |
|
719
|
|
|
$val = ((string)$val === '1') ? get_lang('Yes', $adminLocale) : get_lang('No', $adminLocale); |
|
720
|
|
|
} |
|
721
|
|
|
if ($type === \ExtraField::FIELD_TYPE_TAG && is_array($val)) { |
|
722
|
|
|
$val = implode(', ', array_map(fn($t) => is_array($t) ? (string)($t['value'] ?? '') : (string)$t, $val)); |
|
723
|
|
|
} |
|
724
|
|
|
if (is_string($val)) { |
|
725
|
|
|
$val = str_replace(['<br />','<br>','<br/>'], ', ', $val); |
|
726
|
|
|
} |
|
727
|
|
|
|
|
728
|
|
|
$label = !empty($row['display_text']) |
|
729
|
|
|
? get_lang($row['display_text'], $adminLocale) |
|
730
|
|
|
: get_lang(ucwords(str_replace('_',' ',$variable)), $adminLocale); |
|
731
|
|
|
|
|
732
|
|
|
if ($val !== '' && $val !== null) { |
|
733
|
|
|
$extraPairs[$label] = (string)$val; |
|
734
|
|
|
} |
|
735
|
|
|
} |
|
736
|
|
|
} |
|
737
|
|
|
|
|
738
|
|
|
foreach ($extraParams as $k => $v) { |
|
739
|
|
|
if (strpos($k, 'extra_') !== 0) continue; |
|
740
|
|
|
$variable = substr($k, 6); |
|
741
|
|
|
if (isset($presentVars[$variable])) continue; |
|
742
|
|
|
if (!$showAllExtra && empty($extraVisible[$variable])) continue; |
|
743
|
|
|
|
|
744
|
|
|
$def = $ef->get_handler_field_info_by_field_variable($variable); |
|
745
|
|
|
$label = $def && !empty($def['display_text']) |
|
746
|
|
|
? get_lang($def['display_text'], $adminLocale) |
|
747
|
|
|
: get_lang(ucwords(str_replace('_',' ',$variable)), $adminLocale); |
|
748
|
|
|
|
|
749
|
|
|
$val = $v; |
|
750
|
|
|
if (is_array($val)) { |
|
751
|
|
|
$val = implode(', ', array_map('strval', $val)); |
|
752
|
|
|
} elseif ($val === '1') { |
|
753
|
|
|
$val = get_lang('Yes', $adminLocale); |
|
754
|
|
|
} elseif ($val === '0') { |
|
755
|
|
|
$val = get_lang('No', $adminLocale); |
|
756
|
|
|
} |
|
757
|
|
|
|
|
758
|
|
|
if ($val !== '' && $val !== null) { |
|
759
|
|
|
$extraPairs[$label] = (string)$val; |
|
760
|
|
|
} |
|
761
|
|
|
} |
|
762
|
|
|
|
|
763
|
|
|
$html = '<div class="form-horizontal">'; |
|
764
|
|
|
foreach ($corePairs as $k => $v) { |
|
765
|
|
|
if ($v === '' || $v === null) continue; |
|
766
|
|
|
$html .= '<div>'.$k.': '.\Security::remove_XSS((string)$v).'</div>'; |
|
767
|
|
|
} |
|
768
|
|
|
foreach ($extraPairs as $k => $v) { |
|
769
|
|
|
$html .= '<div>'.$k.': '.\Security::remove_XSS((string)$v).'</div>'; |
|
770
|
|
|
} |
|
771
|
|
|
$html .= '</div>'; |
|
772
|
|
|
|
|
773
|
|
|
return $html; |
|
774
|
|
|
} |
|
775
|
|
|
|
|
776
|
|
|
/** |
|
777
|
|
|
* Can user be deleted? This function checks whether there's a course |
|
778
|
|
|
* in which the given user is the |
|
779
|
|
|
* only course administrator. If that is the case, the user can't be |
|
780
|
|
|
* deleted because the course would remain without a course admin. |
|
781
|
|
|
* |
|
782
|
|
|
* @param int $user_id The user id |
|
783
|
|
|
* |
|
784
|
|
|
* @return bool true if user can be deleted |
|
785
|
|
|
* |
|
786
|
|
|
* @assert (null) === false |
|
787
|
|
|
* @assert (-1) === false |
|
788
|
|
|
* @assert ('abc') === false |
|
789
|
|
|
*/ |
|
790
|
|
|
public static function canDeleteUser($user_id) |
|
791
|
|
|
{ |
|
792
|
|
|
$deny = api_get_env_variable('DENY_DELETE_USERS', false); |
|
793
|
|
|
|
|
794
|
|
|
if ($deny) { |
|
795
|
|
|
return false; |
|
796
|
|
|
} |
|
797
|
|
|
|
|
798
|
|
|
$table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
|
799
|
|
|
$user_id = (int) $user_id; |
|
800
|
|
|
|
|
801
|
|
|
if (empty($user_id)) { |
|
802
|
|
|
return false; |
|
803
|
|
|
} |
|
804
|
|
|
|
|
805
|
|
|
$sql = "SELECT * FROM $table_course_user |
|
806
|
|
|
WHERE status = 1 AND user_id = ".$user_id; |
|
807
|
|
|
$res = Database::query($sql); |
|
808
|
|
|
while ($course = Database::fetch_object($res)) { |
|
809
|
|
|
$sql = "SELECT id FROM $table_course_user |
|
810
|
|
|
WHERE status=1 AND c_id = ".intval($course->c_id); |
|
811
|
|
|
$res2 = Database::query($sql); |
|
812
|
|
|
if (1 == Database::num_rows($res2)) { |
|
813
|
|
|
return false; |
|
814
|
|
|
} |
|
815
|
|
|
} |
|
816
|
|
|
|
|
817
|
|
|
return true; |
|
818
|
|
|
} |
|
819
|
|
|
|
|
820
|
|
|
/** |
|
821
|
|
|
* Deletes a user from the system or marks the user as deleted based on the $destroy flag. |
|
822
|
|
|
* If $destroy is false, the user is only marked as deleted (e.g., active = -1) but not actually removed from the database. |
|
823
|
|
|
* This allows for the possibility of restoring the user at a later time. If $destroy is true, the user and all their relations |
|
824
|
|
|
* are permanently removed from the database. |
|
825
|
|
|
* |
|
826
|
|
|
* Note: When $destroy is false, the user's relations are not removed, allowing for potential restoration. When $destroy is true, |
|
827
|
|
|
* the function proceeds to remove all the user's relations, effectively cleaning up all references to the user in the system. |
|
828
|
|
|
*/ |
|
829
|
|
|
public static function delete_user(int $user_id, bool $destroy = false): bool |
|
830
|
|
|
{ |
|
831
|
|
|
$user_id = (int) $user_id; |
|
832
|
|
|
|
|
833
|
|
|
if (empty($user_id)) { |
|
834
|
|
|
return false; |
|
835
|
|
|
} |
|
836
|
|
|
|
|
837
|
|
|
if (!self::canDeleteUser($user_id)) { |
|
838
|
|
|
return false; |
|
839
|
|
|
} |
|
840
|
|
|
|
|
841
|
|
|
$repository = Container::getUserRepository(); |
|
842
|
|
|
|
|
843
|
|
|
/** @var User $user */ |
|
844
|
|
|
$user = $repository->find($user_id); |
|
845
|
|
|
|
|
846
|
|
|
if (!$user) { |
|
|
|
|
|
|
847
|
|
|
return false; |
|
848
|
|
|
} |
|
849
|
|
|
|
|
850
|
|
|
$fallbackUser = $repository->getFallbackUser(); |
|
851
|
|
|
$fallbackId = (int) $fallbackUser->getId(); |
|
852
|
|
|
$affectedIds = []; |
|
853
|
|
|
if ($destroy && $fallbackId && $fallbackId !== $user_id) { |
|
854
|
|
|
$em = Database::getManager(); |
|
855
|
|
|
$rows = $em->createQuery( |
|
856
|
|
|
'SELECT u.id |
|
857
|
|
|
FROM ' . User::class . ' u |
|
858
|
|
|
WHERE u.creatorId = :oldCreator AND u.id <> :fallbackId' |
|
859
|
|
|
) |
|
860
|
|
|
->setParameter('oldCreator', $user_id) |
|
861
|
|
|
->setParameter('fallbackId', $fallbackId) |
|
862
|
|
|
->getScalarResult(); |
|
863
|
|
|
|
|
864
|
|
|
$affectedIds = array_map( |
|
865
|
|
|
static fn(array $r): int => (int) $r['id'], |
|
866
|
|
|
$rows |
|
867
|
|
|
); |
|
868
|
|
|
|
|
869
|
|
|
$em->createQuery( |
|
870
|
|
|
'UPDATE ' . User::class . ' u |
|
871
|
|
|
SET u.creatorId = :newCreator |
|
872
|
|
|
WHERE u.creatorId = :oldCreator AND u.id <> :fallbackId' |
|
873
|
|
|
) |
|
874
|
|
|
->setParameter('newCreator', $fallbackId) |
|
875
|
|
|
->setParameter('oldCreator', $user_id) |
|
876
|
|
|
->setParameter('fallbackId', $fallbackId) |
|
877
|
|
|
->execute(); |
|
878
|
|
|
} |
|
879
|
|
|
|
|
880
|
|
|
$repository->deleteUser($user, $destroy); |
|
881
|
|
|
|
|
882
|
|
|
if ($destroy) { |
|
883
|
|
|
Event::addEvent( |
|
884
|
|
|
LOG_USER_DELETE, |
|
885
|
|
|
LOG_USER_OBJECT, |
|
886
|
|
|
api_get_user_info($user_id), |
|
887
|
|
|
api_get_utc_datetime(), |
|
888
|
|
|
api_get_user_id() |
|
889
|
|
|
); |
|
890
|
|
|
|
|
891
|
|
|
// Log one event per affected user AFTER the deletion |
|
892
|
|
|
if (!empty($affectedIds) && $fallbackId && $fallbackId !== $user_id) { |
|
893
|
|
|
$nowUtc = api_get_utc_datetime(); |
|
894
|
|
|
$actor = api_get_user_id(); |
|
895
|
|
|
foreach ($affectedIds as $affectedId) { |
|
896
|
|
|
Event::addEvent( |
|
897
|
|
|
LOG_USER_CREATOR_DELETED, |
|
898
|
|
|
LOG_USER_ID, |
|
899
|
|
|
[ |
|
900
|
|
|
'user_id' => $affectedId, |
|
901
|
|
|
'old_creator_id' => $user_id, |
|
902
|
|
|
'new_creator_id' => $fallbackId, |
|
903
|
|
|
], |
|
904
|
|
|
$nowUtc, |
|
905
|
|
|
$actor |
|
906
|
|
|
); |
|
907
|
|
|
} |
|
908
|
|
|
} |
|
909
|
|
|
} |
|
910
|
|
|
|
|
911
|
|
|
return true; |
|
912
|
|
|
} |
|
913
|
|
|
|
|
914
|
|
|
/** |
|
915
|
|
|
* Deletes users completely. Can be called either as: |
|
916
|
|
|
* - UserManager::delete_users(1, 2, 3); or |
|
917
|
|
|
* - UserManager::delete_users(array(1, 2, 3));. |
|
918
|
|
|
* |
|
919
|
|
|
* @param array|int $ids |
|
920
|
|
|
* |
|
921
|
|
|
* @return bool True if at least one user was successfuly deleted. False otherwise. |
|
922
|
|
|
* |
|
923
|
|
|
* @author Laurent Opprecht |
|
924
|
|
|
* |
|
925
|
|
|
* @uses \UserManager::delete_user() to actually delete each user |
|
926
|
|
|
* @assert (null) === false |
|
927
|
|
|
* @assert (-1) === false |
|
928
|
|
|
* @assert (array(-1)) === false |
|
929
|
|
|
*/ |
|
930
|
|
|
public static function delete_users($ids = []) |
|
931
|
|
|
{ |
|
932
|
|
|
$result = false; |
|
933
|
|
|
$ids = is_array($ids) ? $ids : func_get_args(); |
|
934
|
|
|
if (!is_array($ids) || 0 == count($ids)) { |
|
935
|
|
|
return false; |
|
936
|
|
|
} |
|
937
|
|
|
$ids = array_map('intval', $ids); |
|
938
|
|
|
foreach ($ids as $id) { |
|
939
|
|
|
if (empty($id) || $id < 1) { |
|
940
|
|
|
continue; |
|
941
|
|
|
} |
|
942
|
|
|
$deleted = self::delete_user($id); |
|
943
|
|
|
$result = $deleted || $result; |
|
944
|
|
|
} |
|
945
|
|
|
|
|
946
|
|
|
return $result; |
|
947
|
|
|
} |
|
948
|
|
|
|
|
949
|
|
|
/** |
|
950
|
|
|
* Disable users. Can be called either as: |
|
951
|
|
|
* - UserManager::deactivate_users(1, 2, 3); |
|
952
|
|
|
* - UserManager::deactivate_users(array(1, 2, 3));. |
|
953
|
|
|
* |
|
954
|
|
|
* @param array|int $ids |
|
955
|
|
|
* |
|
956
|
|
|
* @return bool |
|
957
|
|
|
* |
|
958
|
|
|
* @author Laurent Opprecht |
|
959
|
|
|
* @assert (null) === false |
|
960
|
|
|
* @assert (array(-1)) === false |
|
961
|
|
|
*/ |
|
962
|
|
|
public static function deactivate_users($ids = []) |
|
963
|
|
|
{ |
|
964
|
|
|
if (empty($ids)) { |
|
965
|
|
|
return false; |
|
966
|
|
|
} |
|
967
|
|
|
|
|
968
|
|
|
$table_user = Database::get_main_table(TABLE_MAIN_USER); |
|
969
|
|
|
|
|
970
|
|
|
$ids = is_array($ids) ? $ids : func_get_args(); |
|
971
|
|
|
$ids = array_map('intval', $ids); |
|
972
|
|
|
$ids = implode(',', $ids); |
|
973
|
|
|
|
|
974
|
|
|
$sql = "UPDATE $table_user SET active = 0 WHERE id IN ($ids)"; |
|
975
|
|
|
$r = Database::query($sql); |
|
976
|
|
|
if (false !== $r) { |
|
977
|
|
|
Event::addEvent(LOG_USER_DISABLE, LOG_USER_ID, $ids); |
|
978
|
|
|
|
|
979
|
|
|
return true; |
|
980
|
|
|
} |
|
981
|
|
|
|
|
982
|
|
|
return false; |
|
983
|
|
|
} |
|
984
|
|
|
|
|
985
|
|
|
/** |
|
986
|
|
|
* Enable users. Can be called either as: |
|
987
|
|
|
* - UserManager::activate_users(1, 2, 3); |
|
988
|
|
|
* - UserManager::activate_users(array(1, 2, 3));. |
|
989
|
|
|
* |
|
990
|
|
|
* @param array|int IDs of the users to enable |
|
991
|
|
|
* |
|
992
|
|
|
* @return bool |
|
993
|
|
|
* |
|
994
|
|
|
* @author Laurent Opprecht |
|
995
|
|
|
* @assert (null) === false |
|
996
|
|
|
* @assert (array(-1)) === false |
|
997
|
|
|
*/ |
|
998
|
|
|
public static function activate_users($ids = []) |
|
999
|
|
|
{ |
|
1000
|
|
|
if (empty($ids)) { |
|
1001
|
|
|
return false; |
|
1002
|
|
|
} |
|
1003
|
|
|
|
|
1004
|
|
|
$table_user = Database::get_main_table(TABLE_MAIN_USER); |
|
1005
|
|
|
|
|
1006
|
|
|
$ids = is_array($ids) ? $ids : func_get_args(); |
|
1007
|
|
|
$ids = array_map('intval', $ids); |
|
1008
|
|
|
$ids = implode(',', $ids); |
|
1009
|
|
|
|
|
1010
|
|
|
$sql = "UPDATE $table_user SET active = 1 WHERE id IN ($ids)"; |
|
1011
|
|
|
$r = Database::query($sql); |
|
1012
|
|
|
if (false !== $r) { |
|
1013
|
|
|
Event::addEvent(LOG_USER_ENABLE, LOG_USER_ID, $ids); |
|
1014
|
|
|
|
|
1015
|
|
|
return true; |
|
1016
|
|
|
} |
|
1017
|
|
|
|
|
1018
|
|
|
return false; |
|
1019
|
|
|
} |
|
1020
|
|
|
|
|
1021
|
|
|
/** |
|
1022
|
|
|
* Update user information with all the parameters passed to this function. |
|
1023
|
|
|
* |
|
1024
|
|
|
* @param int $user_id The ID of the user to be updated |
|
1025
|
|
|
* @param string $firstname The user's firstname |
|
1026
|
|
|
* @param string $lastname The user's lastname |
|
1027
|
|
|
* @param string $username The user's username (login) |
|
1028
|
|
|
* @param string $password The user's password |
|
1029
|
|
|
* @param string $auth_sources The authentication source (default: "platform") |
|
1030
|
|
|
* @param string $email The user's e-mail address |
|
1031
|
|
|
* @param int $status The user's status |
|
1032
|
|
|
* @param string $official_code The user's official code (usually just an internal institutional code) |
|
1033
|
|
|
* @param string $phone The user's phone number |
|
1034
|
|
|
* @param string $picture_uri The user's picture URL (internal to the Chamilo directory) |
|
1035
|
|
|
* @param string $expiration_date The date at which this user will be automatically disabled |
|
1036
|
|
|
* @param int $active Whether this account needs to be enabled (1) or disabled (0) |
|
1037
|
|
|
* @param int $creator_id The user ID of the person who registered this user (optional, defaults to null) |
|
1038
|
|
|
* @param int $hr_dept_id The department of HR in which the user is registered (optional, defaults to 0) |
|
1039
|
|
|
* @param array $extra Additional fields to add to this user as extra fields (defaults to null) |
|
1040
|
|
|
* @param string $language The language to which the user account will be set |
|
1041
|
|
|
* @param string $encrypt_method The cipher method. This parameter is deprecated. It will use the system's default |
|
1042
|
|
|
* @param bool $send_email Whether to send an e-mail to the user after the update is complete |
|
1043
|
|
|
* @param int $reset_password Method used to reset password (0, 1, 2 or 3 - see usage examples for details) |
|
1044
|
|
|
* @param string $address |
|
1045
|
|
|
* @param array $emailTemplate |
|
1046
|
|
|
* |
|
1047
|
|
|
* @return bool|int False on error, or the user ID if the user information was updated |
|
1048
|
|
|
* @assert (false, false, false, false, false, false, false, false, false, false, false, false, false) === false |
|
1049
|
|
|
*/ |
|
1050
|
|
|
public static function update_user( |
|
1051
|
|
|
$user_id, |
|
1052
|
|
|
$firstname, |
|
1053
|
|
|
$lastname, |
|
1054
|
|
|
$username, |
|
1055
|
|
|
$password, |
|
1056
|
|
|
array $auth_sources, |
|
1057
|
|
|
$email, |
|
1058
|
|
|
$status, |
|
1059
|
|
|
$official_code, |
|
1060
|
|
|
$phone, |
|
1061
|
|
|
$picture_uri, |
|
1062
|
|
|
$expiration_date, |
|
1063
|
|
|
$active, |
|
1064
|
|
|
$creator_id = null, |
|
1065
|
|
|
$hr_dept_id = 0, |
|
1066
|
|
|
$extra = null, |
|
1067
|
|
|
$language = 'en_US', |
|
1068
|
|
|
$encrypt_method = '', |
|
1069
|
|
|
$send_email = false, |
|
1070
|
|
|
$reset_password = 0, |
|
1071
|
|
|
$address = null, |
|
1072
|
|
|
$emailTemplate = [] |
|
1073
|
|
|
) { |
|
1074
|
|
|
$eventDispatcher = Container::getEventDispatcher(); |
|
1075
|
|
|
|
|
1076
|
|
|
$eventDispatcher->dispatch( |
|
1077
|
|
|
new UserUpdatedEvent([], AbstractEvent::TYPE_PRE), |
|
1078
|
|
|
Events::USER_UPDATED |
|
1079
|
|
|
); |
|
1080
|
|
|
|
|
1081
|
|
|
$original_password = $password; |
|
1082
|
|
|
$user_id = (int) $user_id; |
|
1083
|
|
|
$creator_id = (int) $creator_id; |
|
1084
|
|
|
|
|
1085
|
|
|
if (empty($user_id)) { |
|
1086
|
|
|
return false; |
|
1087
|
|
|
} |
|
1088
|
|
|
|
|
1089
|
|
|
$userManager = self::getRepository(); |
|
1090
|
|
|
$user = api_get_user_entity($user_id); |
|
1091
|
|
|
|
|
1092
|
|
|
if (null === $user) { |
|
1093
|
|
|
return false; |
|
1094
|
|
|
} |
|
1095
|
|
|
|
|
1096
|
|
|
$accessUrl = Container::getAccessUrlUtil()->getCurrent(); |
|
1097
|
|
|
|
|
1098
|
|
|
if (0 == $reset_password) { |
|
1099
|
|
|
$password = null; |
|
1100
|
|
|
$auth_sources = $user->getAuthSourcesAuthentications($accessUrl); |
|
1101
|
|
|
} elseif (1 == $reset_password) { |
|
1102
|
|
|
$original_password = $password = api_generate_password(); |
|
1103
|
|
|
$auth_sources = [UserAuthSource::PLATFORM]; |
|
1104
|
|
|
} elseif (2 == $reset_password) { |
|
1105
|
|
|
$auth_sources = [UserAuthSource::PLATFORM]; |
|
1106
|
|
|
} |
|
1107
|
|
|
|
|
1108
|
|
|
// Checking the user language |
|
1109
|
|
|
$languages = array_keys(api_get_languages()); |
|
1110
|
|
|
if (!in_array($language, $languages)) { |
|
1111
|
|
|
$language = api_get_setting('platformLanguage'); |
|
1112
|
|
|
} |
|
1113
|
|
|
|
|
1114
|
|
|
$change_active = 0; |
|
1115
|
|
|
$isUserActive = $user->isActive(); |
|
1116
|
|
|
if ($active != USER_SOFT_DELETED) { |
|
1117
|
|
|
if ($isUserActive != $active) { |
|
1118
|
|
|
$change_active = 1; |
|
1119
|
|
|
} |
|
1120
|
|
|
} |
|
1121
|
|
|
|
|
1122
|
|
|
$originalUsername = $user->getUsername(); |
|
1123
|
|
|
|
|
1124
|
|
|
// If username is different from original then check if it exists. |
|
1125
|
|
|
if ($originalUsername !== $username) { |
|
1126
|
|
|
$available = Container::getUserRepository()->isUsernameAvailable($username); |
|
1127
|
|
|
if (false === $available) { |
|
1128
|
|
|
return false; |
|
1129
|
|
|
} |
|
1130
|
|
|
} |
|
1131
|
|
|
|
|
1132
|
|
|
if (!empty($expiration_date)) { |
|
1133
|
|
|
$expiration_date = api_get_utc_datetime($expiration_date); |
|
1134
|
|
|
$expiration_date = new \DateTime($expiration_date, new DateTimeZone('UTC')); |
|
1135
|
|
|
} |
|
1136
|
|
|
|
|
1137
|
|
|
$previousStatus = $user->getStatus(); |
|
1138
|
|
|
$previousRole = $user->getRoleFromStatus($previousStatus); |
|
1139
|
|
|
|
|
1140
|
|
|
$user |
|
1141
|
|
|
->removeRole($previousRole) |
|
1142
|
|
|
->setLastname($lastname) |
|
1143
|
|
|
->setFirstname($firstname) |
|
1144
|
|
|
->setUsername($username) |
|
1145
|
|
|
->setStatus($status) |
|
1146
|
|
|
->setLocale($language) |
|
1147
|
|
|
->setEmail($email) |
|
1148
|
|
|
->setOfficialCode($official_code) |
|
1149
|
|
|
->setPhone($phone) |
|
1150
|
|
|
->setAddress($address) |
|
1151
|
|
|
->setExpirationDate($expiration_date) |
|
1152
|
|
|
->setActive($active) |
|
1153
|
|
|
->setHrDeptId((int) $hr_dept_id) |
|
1154
|
|
|
->removeAuthSources() |
|
1155
|
|
|
; |
|
1156
|
|
|
|
|
1157
|
|
|
foreach ($auth_sources as $authSource) { |
|
1158
|
|
|
$user->addAuthSourceByAuthentication($authSource, $accessUrl); |
|
1159
|
|
|
} |
|
1160
|
|
|
|
|
1161
|
|
|
if (!is_null($password)) { |
|
1162
|
|
|
$user->setPlainPassword($password); |
|
1163
|
|
|
} |
|
1164
|
|
|
|
|
1165
|
|
|
$user->setRoleFromStatus($status); |
|
1166
|
|
|
$userManager->updateUser($user, true); |
|
1167
|
|
|
Event::addEvent(LOG_USER_UPDATE, LOG_USER_ID, $user_id); |
|
1168
|
|
|
|
|
1169
|
|
|
if (1 == $change_active) { |
|
1170
|
|
|
$event_title = LOG_USER_DISABLE; |
|
1171
|
|
|
if (1 == $active) { |
|
1172
|
|
|
$event_title = LOG_USER_ENABLE; |
|
1173
|
|
|
} |
|
1174
|
|
|
Event::addEvent($event_title, LOG_USER_ID, $user_id); |
|
1175
|
|
|
} |
|
1176
|
|
|
|
|
1177
|
|
|
if (is_array($extra) && count($extra) > 0) { |
|
1178
|
|
|
$res = true; |
|
1179
|
|
|
foreach ($extra as $fname => $fvalue) { |
|
1180
|
|
|
$res = $res && self::update_extra_field_value( |
|
1181
|
|
|
$user_id, |
|
1182
|
|
|
$fname, |
|
1183
|
|
|
$fvalue |
|
1184
|
|
|
); |
|
1185
|
|
|
} |
|
1186
|
|
|
} |
|
1187
|
|
|
|
|
1188
|
|
|
if (!empty($email) && $send_email) { |
|
1189
|
|
|
$recipient_name = api_get_person_name($firstname, $lastname, null, PERSON_NAME_EMAIL_ADDRESS); |
|
1190
|
|
|
$emailsubject = '['.api_get_setting('siteName').'] '.get_lang('Your registration on').' '.api_get_setting('siteName'); |
|
|
|
|
|
|
1191
|
|
|
$sender_name = api_get_person_name( |
|
1192
|
|
|
api_get_setting('administratorName'), |
|
1193
|
|
|
api_get_setting('administratorSurname'), |
|
1194
|
|
|
null, |
|
1195
|
|
|
PERSON_NAME_EMAIL_ADDRESS |
|
1196
|
|
|
); |
|
1197
|
|
|
$email_admin = api_get_setting('emailAdministrator'); |
|
1198
|
|
|
$url = api_get_path(WEB_PATH); |
|
1199
|
|
|
if (api_is_multiple_url_enabled()) { |
|
|
|
|
|
|
1200
|
|
|
$access_url_id = api_get_current_access_url_id(); |
|
1201
|
|
|
if (-1 != $access_url_id) { |
|
1202
|
|
|
$url = api_get_access_url($access_url_id); |
|
1203
|
|
|
$url = $url['url']; |
|
1204
|
|
|
} |
|
1205
|
|
|
} |
|
1206
|
|
|
|
|
1207
|
|
|
$tplContent = new Template( |
|
1208
|
|
|
null, |
|
1209
|
|
|
false, |
|
1210
|
|
|
false, |
|
1211
|
|
|
false, |
|
1212
|
|
|
false, |
|
1213
|
|
|
false |
|
1214
|
|
|
); |
|
1215
|
|
|
// variables for the default template |
|
1216
|
|
|
$tplContent->assign('complete_name', stripslashes(api_get_person_name($firstname, $lastname))); |
|
1217
|
|
|
$tplContent->assign('login_name', $username); |
|
1218
|
|
|
|
|
1219
|
|
|
$originalPassword = ''; |
|
1220
|
|
|
if ($reset_password > 0) { |
|
1221
|
|
|
$originalPassword = stripslashes($original_password); |
|
1222
|
|
|
} |
|
1223
|
|
|
$tplContent->assign('original_password', $originalPassword); |
|
1224
|
|
|
$tplContent->assign('portal_url', $url); |
|
1225
|
|
|
|
|
1226
|
|
|
$emailBody = $tplContent->fetch('@ChamiloCore/Mailer/Legacy/user_edit_content.html.twig'); |
|
1227
|
|
|
|
|
1228
|
|
|
$mailTemplateManager = new MailTemplateManager(); |
|
1229
|
|
|
|
|
1230
|
|
|
if (!empty($emailTemplate) && |
|
1231
|
|
|
isset($emailTemplate['user_edit_content.tpl']) && |
|
1232
|
|
|
!empty($emailTemplate['user_edit_content.tpl']) |
|
1233
|
|
|
) { |
|
1234
|
|
|
$userInfo = api_get_user_info($user_id); |
|
1235
|
|
|
$emailBody = $mailTemplateManager->parseTemplate($emailTemplate['user_edit_content.tpl'], $userInfo); |
|
1236
|
|
|
} |
|
1237
|
|
|
|
|
1238
|
|
|
$creatorInfo = api_get_user_info($creator_id); |
|
1239
|
|
|
$creatorEmail = $creatorInfo['email'] ?? ''; |
|
1240
|
|
|
|
|
1241
|
|
|
api_mail_html( |
|
1242
|
|
|
$recipient_name, |
|
1243
|
|
|
$email, |
|
1244
|
|
|
$emailsubject, |
|
1245
|
|
|
$emailBody, |
|
1246
|
|
|
$sender_name, |
|
1247
|
|
|
$email_admin, |
|
1248
|
|
|
null, |
|
1249
|
|
|
null, |
|
1250
|
|
|
null, |
|
1251
|
|
|
null, |
|
1252
|
|
|
$creatorEmail |
|
1253
|
|
|
); |
|
1254
|
|
|
} |
|
1255
|
|
|
|
|
1256
|
|
|
$eventDispatcher->dispatch( |
|
1257
|
|
|
new UserUpdatedEvent(['user' => $user], AbstractEvent::TYPE_POST), |
|
1258
|
|
|
Events::USER_UPDATED |
|
1259
|
|
|
); |
|
1260
|
|
|
|
|
1261
|
|
|
return $user->getId(); |
|
1262
|
|
|
} |
|
1263
|
|
|
|
|
1264
|
|
|
/** |
|
1265
|
|
|
* Disables a user. |
|
1266
|
|
|
* |
|
1267
|
|
|
* @param int User id |
|
1268
|
|
|
* |
|
1269
|
|
|
* @return bool |
|
1270
|
|
|
* |
|
1271
|
|
|
* @uses \UserManager::change_active_state() to actually disable the user |
|
1272
|
|
|
* @assert (0) === false |
|
1273
|
|
|
*/ |
|
1274
|
|
|
public static function disable($user_id) |
|
1275
|
|
|
{ |
|
1276
|
|
|
if (empty($user_id)) { |
|
1277
|
|
|
return false; |
|
1278
|
|
|
} |
|
1279
|
|
|
self::change_active_state($user_id, 0); |
|
1280
|
|
|
|
|
1281
|
|
|
return true; |
|
1282
|
|
|
} |
|
1283
|
|
|
|
|
1284
|
|
|
/** |
|
1285
|
|
|
* Enable a user. |
|
1286
|
|
|
* |
|
1287
|
|
|
* @param int User id |
|
1288
|
|
|
* |
|
1289
|
|
|
* @return bool |
|
1290
|
|
|
* |
|
1291
|
|
|
* @uses \UserManager::change_active_state() to actually disable the user |
|
1292
|
|
|
* @assert (0) === false |
|
1293
|
|
|
*/ |
|
1294
|
|
|
public static function enable($user_id) |
|
1295
|
|
|
{ |
|
1296
|
|
|
if (empty($user_id)) { |
|
1297
|
|
|
return false; |
|
1298
|
|
|
} |
|
1299
|
|
|
self::change_active_state($user_id, 1); |
|
1300
|
|
|
|
|
1301
|
|
|
return true; |
|
1302
|
|
|
} |
|
1303
|
|
|
|
|
1304
|
|
|
/** |
|
1305
|
|
|
* Returns the user's id based on the original id and field name in |
|
1306
|
|
|
* the extra fields. Returns 0 if no user was found. This function is |
|
1307
|
|
|
* mostly useful in the context of a web services-based sinchronization. |
|
1308
|
|
|
* |
|
1309
|
|
|
* @param string Original user id |
|
1310
|
|
|
* @param string Original field name |
|
1311
|
|
|
* |
|
1312
|
|
|
* @return int User id |
|
1313
|
|
|
* @assert ('0','---') === 0 |
|
1314
|
|
|
*/ |
|
1315
|
|
|
public static function get_user_id_from_original_id( |
|
1316
|
|
|
$original_user_id_value, |
|
1317
|
|
|
$original_user_id_name |
|
1318
|
|
|
) { |
|
1319
|
|
|
$t_uf = Database::get_main_table(TABLE_EXTRA_FIELD); |
|
1320
|
|
|
$t_ufv = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
|
1321
|
|
|
$extraFieldType = EntityExtraField::USER_FIELD_TYPE; |
|
1322
|
|
|
|
|
1323
|
|
|
$original_user_id_name = Database::escape_string($original_user_id_name); |
|
1324
|
|
|
$original_user_id_value = Database::escape_string($original_user_id_value); |
|
1325
|
|
|
|
|
1326
|
|
|
$sql = "SELECT item_id as user_id |
|
1327
|
|
|
FROM $t_uf uf |
|
1328
|
|
|
INNER JOIN $t_ufv ufv |
|
1329
|
|
|
ON ufv.field_id = uf.id |
|
1330
|
|
|
WHERE |
|
1331
|
|
|
variable = '$original_user_id_name' AND |
|
1332
|
|
|
field_value = '$original_user_id_value' AND |
|
1333
|
|
|
item_type = $extraFieldType |
|
1334
|
|
|
"; |
|
1335
|
|
|
$res = Database::query($sql); |
|
1336
|
|
|
$row = Database::fetch_object($res); |
|
1337
|
|
|
if ($row) { |
|
1338
|
|
|
return $row->user_id; |
|
1339
|
|
|
} |
|
1340
|
|
|
|
|
1341
|
|
|
return 0; |
|
1342
|
|
|
} |
|
1343
|
|
|
|
|
1344
|
|
|
/** |
|
1345
|
|
|
* Creates a username using person's names, i.e. creates jmontoya from Julio Montoya. |
|
1346
|
|
|
* |
|
1347
|
|
|
* @param string $firstname the first name of the user |
|
1348
|
|
|
* @param string $lastname the last name of the user |
|
1349
|
|
|
* |
|
1350
|
|
|
* @return string suggests a username that contains only ASCII-letters and digits, |
|
1351
|
|
|
* without check for uniqueness within the system |
|
1352
|
|
|
* |
|
1353
|
|
|
* @author Julio Montoya Armas |
|
1354
|
|
|
* @author Ivan Tcholakov, 2009 - rework about internationalization. |
|
1355
|
|
|
* @assert ('','') === false |
|
1356
|
|
|
* @assert ('a','b') === 'ab' |
|
1357
|
|
|
*/ |
|
1358
|
|
|
public static function create_username($firstname, $lastname) |
|
1359
|
|
|
{ |
|
1360
|
|
|
if (empty($firstname) && empty($lastname)) { |
|
1361
|
|
|
return false; |
|
1362
|
|
|
} |
|
1363
|
|
|
|
|
1364
|
|
|
// The first letter only. |
|
1365
|
|
|
$firstname = api_substr( |
|
1366
|
|
|
preg_replace(USERNAME_PURIFIER, '', $firstname), |
|
1367
|
|
|
0, |
|
1368
|
|
|
1 |
|
1369
|
|
|
); |
|
1370
|
|
|
//Looking for a space in the lastname |
|
1371
|
|
|
$pos = api_strpos($lastname, ' '); |
|
1372
|
|
|
if (false !== $pos) { |
|
1373
|
|
|
$lastname = api_substr($lastname, 0, $pos); |
|
1374
|
|
|
} |
|
1375
|
|
|
|
|
1376
|
|
|
$lastname = preg_replace(USERNAME_PURIFIER, '', $lastname); |
|
1377
|
|
|
$username = $firstname.$lastname; |
|
1378
|
|
|
if (empty($username)) { |
|
1379
|
|
|
$username = 'user'; |
|
1380
|
|
|
} |
|
1381
|
|
|
|
|
1382
|
|
|
$username = URLify::transliterate($username); |
|
1383
|
|
|
|
|
1384
|
|
|
return strtolower(substr($username, 0, User::USERNAME_MAX_LENGTH - 3)); |
|
1385
|
|
|
} |
|
1386
|
|
|
|
|
1387
|
|
|
/** |
|
1388
|
|
|
* Creates a unique username, using: |
|
1389
|
|
|
* 1. the first name and the last name of a user; |
|
1390
|
|
|
* 2. an already created username but not checked for uniqueness yet. |
|
1391
|
|
|
* |
|
1392
|
|
|
* @param string $firstname The first name of a given user. If the second parameter $lastname is NULL, then this |
|
1393
|
|
|
* parameter is treated as username which is to be checked f |
|
1394
|
|
|
* or uniqueness and to be modified when it is necessary. |
|
1395
|
|
|
* @param string $lastname the last name of the user |
|
1396
|
|
|
* |
|
1397
|
|
|
* @return string Returns a username that contains only ASCII-letters and digits and that is unique in the system. |
|
1398
|
|
|
* Note: When the method is called several times with same parameters, |
|
1399
|
|
|
* its results look like the following sequence: ivan, ivan2, ivan3, ivan4, ... |
|
1400
|
|
|
* |
|
1401
|
|
|
* @author Ivan Tcholakov, 2009 |
|
1402
|
|
|
*/ |
|
1403
|
|
|
public static function create_unique_username($firstname, $lastname = null) |
|
1404
|
|
|
{ |
|
1405
|
|
|
if (is_null($lastname)) { |
|
1406
|
|
|
// In this case the actual input parameter $firstname should contain ASCII-letters and digits only. |
|
1407
|
|
|
// For making this method tolerant of mistakes, |
|
1408
|
|
|
// let us transliterate and purify the suggested input username anyway. |
|
1409
|
|
|
// So, instead of the sentence $username = $firstname; we place the following: |
|
1410
|
|
|
$username = strtolower(preg_replace(USERNAME_PURIFIER, '', $firstname)); |
|
1411
|
|
|
} else { |
|
1412
|
|
|
$username = self::create_username($firstname, $lastname); |
|
1413
|
|
|
} |
|
1414
|
|
|
if (!Container::getUserRepository()->isUsernameAvailable($username)) { |
|
1415
|
|
|
$i = 2; |
|
1416
|
|
|
$temp_username = substr($username, 0, User::USERNAME_MAX_LENGTH - strlen((string) $i)).$i; |
|
1417
|
|
|
while (!Container::getUserRepository()->isUsernameAvailable($temp_username)) { |
|
1418
|
|
|
$i++; |
|
1419
|
|
|
$temp_username = substr($username, 0, User::USERNAME_MAX_LENGTH - strlen((string) $i)).$i; |
|
1420
|
|
|
} |
|
1421
|
|
|
$username = $temp_username; |
|
1422
|
|
|
} |
|
1423
|
|
|
|
|
1424
|
|
|
$username = URLify::transliterate($username); |
|
1425
|
|
|
|
|
1426
|
|
|
return $username; |
|
1427
|
|
|
} |
|
1428
|
|
|
|
|
1429
|
|
|
/** |
|
1430
|
|
|
* Modifies a given username accordingly to the specification for valid characters and length. |
|
1431
|
|
|
* |
|
1432
|
|
|
* @param $username string The input username |
|
1433
|
|
|
* @param bool $strict (optional) When this flag is TRUE, the result is guaranteed for full compliance, |
|
1434
|
|
|
* otherwise compliance may be partial. The default value is FALSE. |
|
1435
|
|
|
* |
|
1436
|
|
|
* @return string the resulting purified username |
|
1437
|
|
|
*/ |
|
1438
|
|
|
public static function purify_username($username, $strict = false) |
|
1439
|
|
|
{ |
|
1440
|
|
|
if ($strict) { |
|
1441
|
|
|
// 1. Conversion of unacceptable letters (latinian letters with accents for example) |
|
1442
|
|
|
// into ASCII letters in order they not to be totally removed. |
|
1443
|
|
|
// 2. Applying the strict purifier. |
|
1444
|
|
|
// 3. Length limitation. |
|
1445
|
|
|
$return = 'true' === api_get_setting('login_is_email') ? substr(preg_replace(USERNAME_PURIFIER_MAIL, '', $username), 0, User::USERNAME_MAX_LENGTH) : substr(preg_replace(USERNAME_PURIFIER, '', $username), 0, User::USERNAME_MAX_LENGTH); |
|
1446
|
|
|
$return = URLify::transliterate($return); |
|
1447
|
|
|
|
|
1448
|
|
|
// We want everything transliterate() does except converting @ to '(at)'. This is a hack to avoid this. |
|
1449
|
|
|
$return = str_replace(' (at) ', '@', $return); |
|
1450
|
|
|
|
|
1451
|
|
|
return $return; |
|
1452
|
|
|
} |
|
1453
|
|
|
|
|
1454
|
|
|
// 1. Applying the shallow purifier. |
|
1455
|
|
|
// 2. Length limitation. |
|
1456
|
|
|
return substr( |
|
1457
|
|
|
preg_replace(USERNAME_PURIFIER_SHALLOW, '', $username), |
|
1458
|
|
|
0, |
|
1459
|
|
|
User::USERNAME_MAX_LENGTH |
|
1460
|
|
|
); |
|
1461
|
|
|
} |
|
1462
|
|
|
|
|
1463
|
|
|
/** |
|
1464
|
|
|
* Checks whether the user id exists in the database. |
|
1465
|
|
|
* |
|
1466
|
|
|
* @param int $userId User id |
|
1467
|
|
|
* |
|
1468
|
|
|
* @return bool True if user id was found, false otherwise |
|
1469
|
|
|
*/ |
|
1470
|
|
|
public static function is_user_id_valid($userId) |
|
1471
|
|
|
{ |
|
1472
|
|
|
$resultData = Database::select( |
|
1473
|
|
|
'COUNT(1) AS count', |
|
1474
|
|
|
Database::get_main_table(TABLE_MAIN_USER), |
|
1475
|
|
|
[ |
|
1476
|
|
|
'where' => ['id = ?' => (int) $userId], |
|
1477
|
|
|
], |
|
1478
|
|
|
'first' |
|
1479
|
|
|
); |
|
1480
|
|
|
|
|
1481
|
|
|
if (false === $resultData) { |
|
1482
|
|
|
return false; |
|
1483
|
|
|
} |
|
1484
|
|
|
|
|
1485
|
|
|
return $resultData['count'] > 0; |
|
1486
|
|
|
} |
|
1487
|
|
|
|
|
1488
|
|
|
/** |
|
1489
|
|
|
* Checks whether a given username matches to the specification strictly. |
|
1490
|
|
|
* The empty username is assumed here as invalid. |
|
1491
|
|
|
* Mostly this function is to be used in the user interface built-in validation routines |
|
1492
|
|
|
* for providing feedback while usernames are enterd manually. |
|
1493
|
|
|
* |
|
1494
|
|
|
* @param string $username the input username |
|
1495
|
|
|
* |
|
1496
|
|
|
* @return bool returns TRUE if the username is valid, FALSE otherwise |
|
1497
|
|
|
*/ |
|
1498
|
|
|
public static function is_username_valid($username) |
|
1499
|
|
|
{ |
|
1500
|
|
|
return !empty($username) && $username == self::purify_username($username, true); |
|
1501
|
|
|
} |
|
1502
|
|
|
|
|
1503
|
|
|
/** |
|
1504
|
|
|
* Checks whether a username is empty. If the username contains whitespace characters, |
|
1505
|
|
|
* such as spaces, tabulators, newlines, etc., |
|
1506
|
|
|
* it is assumed as empty too. This function is safe for validation unpurified data (during importing). |
|
1507
|
|
|
* |
|
1508
|
|
|
* @param string $username the given username |
|
1509
|
|
|
* |
|
1510
|
|
|
* @return bool returns TRUE if length of the username exceeds the limit, FALSE otherwise |
|
1511
|
|
|
*/ |
|
1512
|
|
|
public static function is_username_empty($username) |
|
1513
|
|
|
{ |
|
1514
|
|
|
return 0 == strlen(self::purify_username($username, false)); |
|
1515
|
|
|
} |
|
1516
|
|
|
|
|
1517
|
|
|
/** |
|
1518
|
|
|
* Checks whether a username is too long or not. |
|
1519
|
|
|
* |
|
1520
|
|
|
* @param string $username the given username, it should contain only ASCII-letters and digits |
|
1521
|
|
|
* |
|
1522
|
|
|
* @return bool returns TRUE if length of the username exceeds the limit, FALSE otherwise |
|
1523
|
|
|
*/ |
|
1524
|
|
|
public static function is_username_too_long($username) |
|
1525
|
|
|
{ |
|
1526
|
|
|
return strlen($username) > User::USERNAME_MAX_LENGTH; |
|
1527
|
|
|
} |
|
1528
|
|
|
|
|
1529
|
|
|
/** |
|
1530
|
|
|
* Get the users by ID. |
|
1531
|
|
|
* |
|
1532
|
|
|
* @param array $ids student ids |
|
1533
|
|
|
* @param bool $active |
|
1534
|
|
|
* @param string $order |
|
1535
|
|
|
* @param string $limit |
|
1536
|
|
|
* |
|
1537
|
|
|
* @return array $result student information |
|
1538
|
|
|
*/ |
|
1539
|
|
|
public static function get_user_list_by_ids($ids = [], $active = null, $order = null, $limit = null) |
|
1540
|
|
|
{ |
|
1541
|
|
|
if (empty($ids)) { |
|
1542
|
|
|
return []; |
|
1543
|
|
|
} |
|
1544
|
|
|
|
|
1545
|
|
|
$ids = is_array($ids) ? $ids : [$ids]; |
|
1546
|
|
|
$ids = array_map('intval', $ids); |
|
1547
|
|
|
$ids = implode(',', $ids); |
|
1548
|
|
|
|
|
1549
|
|
|
$tbl_user = Database::get_main_table(TABLE_MAIN_USER); |
|
1550
|
|
|
$sql = "SELECT * FROM $tbl_user WHERE id IN ($ids)"; |
|
1551
|
|
|
if (!is_null($active)) { |
|
1552
|
|
|
$sql .= ' AND active='.($active ? '1' : '0'); |
|
1553
|
|
|
} |
|
1554
|
|
|
|
|
1555
|
|
|
if (!is_null($order)) { |
|
1556
|
|
|
$order = Database::escape_string($order); |
|
1557
|
|
|
$sql .= ' ORDER BY '.$order; |
|
1558
|
|
|
} |
|
1559
|
|
|
|
|
1560
|
|
|
if (!is_null($limit)) { |
|
1561
|
|
|
$limit = Database::escape_string($limit); |
|
1562
|
|
|
$sql .= ' LIMIT '.$limit; |
|
1563
|
|
|
} |
|
1564
|
|
|
|
|
1565
|
|
|
$rs = Database::query($sql); |
|
1566
|
|
|
$result = []; |
|
1567
|
|
|
while ($row = Database::fetch_array($rs)) { |
|
1568
|
|
|
$result[] = $row; |
|
1569
|
|
|
} |
|
1570
|
|
|
|
|
1571
|
|
|
return $result; |
|
1572
|
|
|
} |
|
1573
|
|
|
|
|
1574
|
|
|
/** |
|
1575
|
|
|
* Get a list of users of which the given conditions match with an = 'cond'. |
|
1576
|
|
|
* |
|
1577
|
|
|
* @param array $conditions a list of condition (example : status=>STUDENT) |
|
1578
|
|
|
* @param array $order_by a list of fields on which sort |
|
1579
|
|
|
* |
|
1580
|
|
|
* @return array an array with all users of the platform |
|
1581
|
|
|
* |
|
1582
|
|
|
* @todo security filter order by |
|
1583
|
|
|
*/ |
|
1584
|
|
|
public static function get_user_list( |
|
1585
|
|
|
$conditions = [], |
|
1586
|
|
|
$order_by = [], |
|
1587
|
|
|
$limit_from = false, |
|
1588
|
|
|
$limit_to = false, |
|
1589
|
|
|
$idCampus = null |
|
1590
|
|
|
) { |
|
1591
|
|
|
$user_table = Database::get_main_table(TABLE_MAIN_USER); |
|
1592
|
|
|
$userUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
|
1593
|
|
|
$return_array = []; |
|
1594
|
|
|
$sql = "SELECT user.*, user.id as user_id FROM $user_table user "; |
|
1595
|
|
|
|
|
1596
|
|
|
if (api_is_multiple_url_enabled()) { |
|
|
|
|
|
|
1597
|
|
|
if ($idCampus) { |
|
1598
|
|
|
$urlId = $idCampus; |
|
1599
|
|
|
} else { |
|
1600
|
|
|
$urlId = api_get_current_access_url_id(); |
|
1601
|
|
|
} |
|
1602
|
|
|
$sql .= " INNER JOIN $userUrlTable url_user |
|
1603
|
|
|
ON (user.id = url_user.user_id) |
|
1604
|
|
|
WHERE url_user.access_url_id = $urlId"; |
|
1605
|
|
|
} else { |
|
1606
|
|
|
$sql .= " WHERE 1=1 "; |
|
1607
|
|
|
} |
|
1608
|
|
|
|
|
1609
|
|
|
if (count($conditions) > 0) { |
|
1610
|
|
|
foreach ($conditions as $field => $value) { |
|
1611
|
|
|
$field = Database::escape_string($field); |
|
1612
|
|
|
$value = Database::escape_string($value); |
|
1613
|
|
|
$sql .= " AND $field = '$value'"; |
|
1614
|
|
|
} |
|
1615
|
|
|
} |
|
1616
|
|
|
|
|
1617
|
|
|
if (count($order_by) > 0) { |
|
1618
|
|
|
$sql .= ' ORDER BY '.Database::escape_string(implode(',', $order_by)); |
|
1619
|
|
|
} |
|
1620
|
|
|
|
|
1621
|
|
|
if (is_numeric($limit_from) && is_numeric($limit_from)) { |
|
1622
|
|
|
$limit_from = (int) $limit_from; |
|
1623
|
|
|
$limit_to = (int) $limit_to; |
|
1624
|
|
|
$sql .= " LIMIT $limit_from, $limit_to"; |
|
1625
|
|
|
} |
|
1626
|
|
|
$sql_result = Database::query($sql); |
|
1627
|
|
|
while ($result = Database::fetch_array($sql_result)) { |
|
1628
|
|
|
$result['complete_name'] = api_get_person_name($result['firstname'], $result['lastname']); |
|
1629
|
|
|
$return_array[] = $result; |
|
1630
|
|
|
} |
|
1631
|
|
|
|
|
1632
|
|
|
return $return_array; |
|
1633
|
|
|
} |
|
1634
|
|
|
|
|
1635
|
|
|
public static function getUserListExtraConditions( |
|
1636
|
|
|
$conditions = [], |
|
1637
|
|
|
$order_by = [], |
|
1638
|
|
|
$limit_from = false, |
|
1639
|
|
|
$limit_to = false, |
|
1640
|
|
|
$idCampus = null, |
|
1641
|
|
|
$extraConditions = '', |
|
1642
|
|
|
$getCount = false |
|
1643
|
|
|
) { |
|
1644
|
|
|
$user_table = Database::get_main_table(TABLE_MAIN_USER); |
|
1645
|
|
|
$userUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
|
1646
|
|
|
$return_array = []; |
|
1647
|
|
|
$sql = "SELECT user.*, user.id as user_id FROM $user_table user "; |
|
1648
|
|
|
|
|
1649
|
|
|
if ($getCount) { |
|
1650
|
|
|
$sql = "SELECT count(user.id) count FROM $user_table user "; |
|
1651
|
|
|
} |
|
1652
|
|
|
|
|
1653
|
|
|
if (api_is_multiple_url_enabled()) { |
|
|
|
|
|
|
1654
|
|
|
if ($idCampus) { |
|
1655
|
|
|
$urlId = $idCampus; |
|
1656
|
|
|
} else { |
|
1657
|
|
|
$urlId = api_get_current_access_url_id(); |
|
1658
|
|
|
} |
|
1659
|
|
|
$sql .= " INNER JOIN $userUrlTable url_user |
|
1660
|
|
|
ON (user.id = url_user.user_id) |
|
1661
|
|
|
WHERE url_user.access_url_id = $urlId"; |
|
1662
|
|
|
} else { |
|
1663
|
|
|
$sql .= " WHERE 1=1 "; |
|
1664
|
|
|
} |
|
1665
|
|
|
|
|
1666
|
|
|
$sql .= " AND status <> ".ANONYMOUS." "; |
|
1667
|
|
|
|
|
1668
|
|
|
if (count($conditions) > 0) { |
|
1669
|
|
|
foreach ($conditions as $field => $value) { |
|
1670
|
|
|
$field = Database::escape_string($field); |
|
1671
|
|
|
$value = Database::escape_string($value); |
|
1672
|
|
|
$sql .= " AND $field = '$value'"; |
|
1673
|
|
|
} |
|
1674
|
|
|
} |
|
1675
|
|
|
|
|
1676
|
|
|
$sql .= str_replace("\'", "'", Database::escape_string($extraConditions)); |
|
1677
|
|
|
|
|
1678
|
|
|
if (!empty($order_by) && count($order_by) > 0) { |
|
1679
|
|
|
$sql .= ' ORDER BY '.Database::escape_string(implode(',', $order_by)); |
|
1680
|
|
|
} |
|
1681
|
|
|
|
|
1682
|
|
|
if (is_numeric($limit_from) && is_numeric($limit_from)) { |
|
1683
|
|
|
$limit_from = (int) $limit_from; |
|
1684
|
|
|
$limit_to = (int) $limit_to; |
|
1685
|
|
|
$sql .= " LIMIT $limit_from, $limit_to"; |
|
1686
|
|
|
} |
|
1687
|
|
|
|
|
1688
|
|
|
$sql_result = Database::query($sql); |
|
1689
|
|
|
|
|
1690
|
|
|
if ($getCount) { |
|
1691
|
|
|
$result = Database::fetch_array($sql_result); |
|
1692
|
|
|
|
|
1693
|
|
|
return $result['count']; |
|
1694
|
|
|
} |
|
1695
|
|
|
|
|
1696
|
|
|
while ($result = Database::fetch_array($sql_result)) { |
|
1697
|
|
|
$result['complete_name'] = api_get_person_name($result['firstname'], $result['lastname']); |
|
1698
|
|
|
$return_array[] = $result; |
|
1699
|
|
|
} |
|
1700
|
|
|
|
|
1701
|
|
|
return $return_array; |
|
1702
|
|
|
} |
|
1703
|
|
|
|
|
1704
|
|
|
/** |
|
1705
|
|
|
* Get a list of users of which the given conditions match with a LIKE '%cond%'. |
|
1706
|
|
|
* |
|
1707
|
|
|
* @param array $conditions a list of condition (exemple : status=>STUDENT) |
|
1708
|
|
|
* @param array $order_by a list of fields on which sort |
|
1709
|
|
|
* @param bool $simple_like Whether we want a simple LIKE 'abc' or a LIKE '%abc%' |
|
1710
|
|
|
* @param string $condition Whether we want the filters to be combined by AND or OR |
|
1711
|
|
|
* @param array $onlyThisUserList |
|
1712
|
|
|
* |
|
1713
|
|
|
* @return array an array with all users of the platform |
|
1714
|
|
|
* |
|
1715
|
|
|
* @todo optional course code parameter, optional sorting parameters... |
|
1716
|
|
|
* @todo security filter order_by |
|
1717
|
|
|
*/ |
|
1718
|
|
|
public static function getUserListLike( |
|
1719
|
|
|
$conditions = [], |
|
1720
|
|
|
$order_by = [], |
|
1721
|
|
|
$simple_like = false, |
|
1722
|
|
|
$condition = 'AND', |
|
1723
|
|
|
$onlyThisUserList = [], |
|
1724
|
|
|
int $limit = 0, |
|
1725
|
|
|
int $offset = 0 |
|
1726
|
|
|
) { |
|
1727
|
|
|
$user_table = Database::get_main_table(TABLE_MAIN_USER); |
|
1728
|
|
|
$tblAccessUrlRelUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
|
1729
|
|
|
$return_array = []; |
|
1730
|
|
|
$sql_query = "SELECT user.id, user.username, user.firstname, user.lastname, user.official_code, user.status |
|
1731
|
|
|
FROM $user_table user "; |
|
1732
|
|
|
|
|
1733
|
|
|
if (api_get_multiple_access_url()) { |
|
1734
|
|
|
$sql_query .= " INNER JOIN $tblAccessUrlRelUser auru ON auru.user_id = user.id "; |
|
1735
|
|
|
} |
|
1736
|
|
|
|
|
1737
|
|
|
$sql_query .= ' WHERE 1 = 1 '; |
|
1738
|
|
|
if (count($conditions) > 0) { |
|
1739
|
|
|
$temp_conditions = []; |
|
1740
|
|
|
foreach ($conditions as $field => $value) { |
|
1741
|
|
|
$field = Database::escape_string($field); |
|
1742
|
|
|
$value = Database::escape_string($value); |
|
1743
|
|
|
if ($simple_like) { |
|
1744
|
|
|
$temp_conditions[] = "$field LIKE '$value%'"; |
|
1745
|
|
|
} else { |
|
1746
|
|
|
if (in_array($field, ['user.id', 'user.status'])) { |
|
1747
|
|
|
$temp_conditions[] = "$field = '$value'"; |
|
1748
|
|
|
} else { |
|
1749
|
|
|
$temp_conditions[] = "$field LIKE '%$value%'"; |
|
1750
|
|
|
} |
|
1751
|
|
|
} |
|
1752
|
|
|
} |
|
1753
|
|
|
if (!empty($temp_conditions)) { |
|
1754
|
|
|
$sql_query .= ' AND '.implode(" $condition ", $temp_conditions); |
|
1755
|
|
|
} |
|
1756
|
|
|
|
|
1757
|
|
|
if (api_get_multiple_access_url()) { |
|
1758
|
|
|
$sql_query .= ' AND auru.access_url_id = '.api_get_current_access_url_id(); |
|
1759
|
|
|
} |
|
1760
|
|
|
} else { |
|
1761
|
|
|
if (api_get_multiple_access_url()) { |
|
1762
|
|
|
$sql_query .= ' AND auru.access_url_id = '.api_get_current_access_url_id(); |
|
1763
|
|
|
} |
|
1764
|
|
|
} |
|
1765
|
|
|
|
|
1766
|
|
|
if (!empty($onlyThisUserList)) { |
|
1767
|
|
|
$onlyThisUserListToString = implode("','", array_map('intval', $onlyThisUserList)); |
|
1768
|
|
|
$sql_query .= " AND user.id IN ('$onlyThisUserListToString') "; |
|
1769
|
|
|
} |
|
1770
|
|
|
|
|
1771
|
|
|
if (!empty($order_by)) { |
|
1772
|
|
|
$sql_query .= ' ORDER BY '.Database::escape_string(implode(',', $order_by)); |
|
1773
|
|
|
} |
|
1774
|
|
|
|
|
1775
|
|
|
if ($limit > 0) { |
|
1776
|
|
|
$sql_query .= ' LIMIT '.intval($limit); |
|
1777
|
|
|
if ($offset > 0) { |
|
1778
|
|
|
$sql_query .= ' OFFSET '.intval($offset); |
|
1779
|
|
|
} |
|
1780
|
|
|
} |
|
1781
|
|
|
|
|
1782
|
|
|
$sql_result = Database::query($sql_query); |
|
1783
|
|
|
while ($result = Database::fetch_array($sql_result)) { |
|
1784
|
|
|
$return_array[] = $result; |
|
1785
|
|
|
} |
|
1786
|
|
|
|
|
1787
|
|
|
return $return_array; |
|
1788
|
|
|
} |
|
1789
|
|
|
|
|
1790
|
|
|
/** |
|
1791
|
|
|
* Get user path from user ID (returns an array). |
|
1792
|
|
|
* The return format is a complete path to a folder ending with "/" |
|
1793
|
|
|
* In case the first level of subdirectory of users/ does not exist, the |
|
1794
|
|
|
* function will attempt to create it. Probably not the right place to do it |
|
1795
|
|
|
* but at least it avoids headaches in many other places. |
|
1796
|
|
|
* |
|
1797
|
|
|
* @param int $id User ID |
|
1798
|
|
|
* @param string $type Type of path to return (can be 'system', 'web', 'last') |
|
1799
|
|
|
* |
|
1800
|
|
|
* @return string User folder path (i.e. /var/www/chamilo/app/upload/users/1/1/) |
|
1801
|
|
|
*/ |
|
1802
|
|
|
public static function getUserPathById($id, $type) |
|
1803
|
|
|
{ |
|
1804
|
|
|
$id = (int) $id; |
|
1805
|
|
|
if (!$id) { |
|
1806
|
|
|
return null; |
|
1807
|
|
|
} |
|
1808
|
|
|
|
|
1809
|
|
|
$userPath = "users/$id/"; |
|
1810
|
|
|
if (api_get_setting('split_users_upload_directory') === 'true') { |
|
1811
|
|
|
$userPath = 'users/'.substr((string) $id, 0, 1).'/'.$id.'/'; |
|
1812
|
|
|
// In exceptional cases, on some portals, the intermediate base user |
|
1813
|
|
|
// directory might not have been created. Make sure it is before |
|
1814
|
|
|
// going further. |
|
1815
|
|
|
|
|
1816
|
|
|
$rootPath = api_get_path(SYS_PATH).'../app/upload/users/'.substr((string) $id, 0, 1); |
|
1817
|
|
|
if (!is_dir($rootPath)) { |
|
1818
|
|
|
$perm = api_get_permissions_for_new_directories(); |
|
1819
|
|
|
try { |
|
1820
|
|
|
mkdir($rootPath, $perm); |
|
1821
|
|
|
} catch (Exception $e) { |
|
1822
|
|
|
error_log($e->getMessage()); |
|
1823
|
|
|
} |
|
1824
|
|
|
} |
|
1825
|
|
|
} |
|
1826
|
|
|
switch ($type) { |
|
1827
|
|
|
case 'system': // Base: absolute system path. |
|
1828
|
|
|
$userPath = api_get_path(SYS_PATH).'../app/upload/'.$userPath; |
|
1829
|
|
|
break; |
|
1830
|
|
|
case 'web': // Base: absolute web path. |
|
1831
|
|
|
$userPath = api_get_path(WEB_PATH).'../app/upload/'.$userPath; |
|
1832
|
|
|
break; |
|
1833
|
|
|
case 'last': // Only the last part starting with users/ |
|
1834
|
|
|
break; |
|
1835
|
|
|
} |
|
1836
|
|
|
|
|
1837
|
|
|
return $userPath; |
|
1838
|
|
|
} |
|
1839
|
|
|
|
|
1840
|
|
|
/** |
|
1841
|
|
|
* Gets the current user image. |
|
1842
|
|
|
* |
|
1843
|
|
|
* @param string $userId |
|
1844
|
|
|
* @param int $size it can be USER_IMAGE_SIZE_SMALL, |
|
1845
|
|
|
* USER_IMAGE_SIZE_MEDIUM, USER_IMAGE_SIZE_BIG or USER_IMAGE_SIZE_ORIGINAL |
|
1846
|
|
|
* @param bool $addRandomId |
|
1847
|
|
|
* @param array $userInfo to avoid query the DB |
|
1848
|
|
|
* |
|
1849
|
|
|
* @todo add gravatar support |
|
1850
|
|
|
* @todo replace $userId with User entity |
|
1851
|
|
|
* |
|
1852
|
|
|
* @return string |
|
1853
|
|
|
*/ |
|
1854
|
|
|
public static function getUserPicture( |
|
1855
|
|
|
$userId, |
|
1856
|
|
|
int $size = USER_IMAGE_SIZE_MEDIUM, |
|
1857
|
|
|
$addRandomId = true, |
|
1858
|
|
|
$userInfo = [] |
|
1859
|
|
|
) { |
|
1860
|
|
|
$user = api_get_user_entity($userId); |
|
1861
|
|
|
$illustrationRepo = Container::getIllustrationRepository(); |
|
1862
|
|
|
|
|
1863
|
|
|
switch ($size) { |
|
1864
|
|
|
case USER_IMAGE_SIZE_SMALL: |
|
1865
|
|
|
$width = 32; |
|
1866
|
|
|
break; |
|
1867
|
|
|
case USER_IMAGE_SIZE_MEDIUM: |
|
1868
|
|
|
$width = 64; |
|
1869
|
|
|
break; |
|
1870
|
|
|
case USER_IMAGE_SIZE_BIG: |
|
1871
|
|
|
$width = 128; |
|
1872
|
|
|
break; |
|
1873
|
|
|
case USER_IMAGE_SIZE_ORIGINAL: |
|
1874
|
|
|
default: |
|
1875
|
|
|
$width = 0; |
|
1876
|
|
|
break; |
|
1877
|
|
|
} |
|
1878
|
|
|
|
|
1879
|
|
|
$url = $illustrationRepo->getIllustrationUrl($user); |
|
1880
|
|
|
$params = []; |
|
1881
|
|
|
if (!empty($width)) { |
|
1882
|
|
|
$params['w'] = $width; |
|
1883
|
|
|
} |
|
1884
|
|
|
|
|
1885
|
|
|
if ($addRandomId) { |
|
1886
|
|
|
$params['rand'] = uniqid('u_', true); |
|
1887
|
|
|
} |
|
1888
|
|
|
|
|
1889
|
|
|
$paramsToString = ''; |
|
1890
|
|
|
if (!empty($params)) { |
|
1891
|
|
|
$paramsToString = '?'.http_build_query($params); |
|
1892
|
|
|
} |
|
1893
|
|
|
|
|
1894
|
|
|
return $url.$paramsToString; |
|
1895
|
|
|
|
|
1896
|
|
|
/* |
|
1897
|
|
|
// Make sure userInfo is defined. Otherwise, define it! |
|
1898
|
|
|
if (empty($userInfo) || !is_array($userInfo) || 0 == count($userInfo)) { |
|
1899
|
|
|
if (empty($user_id)) { |
|
1900
|
|
|
return ''; |
|
1901
|
|
|
} else { |
|
1902
|
|
|
$userInfo = api_get_user_info($user_id); |
|
1903
|
|
|
} |
|
1904
|
|
|
} |
|
1905
|
|
|
|
|
1906
|
|
|
$imageWebPath = self::get_user_picture_path_by_id( |
|
1907
|
|
|
$user_id, |
|
1908
|
|
|
'web', |
|
1909
|
|
|
$userInfo |
|
1910
|
|
|
); |
|
1911
|
|
|
$pictureWebFile = $imageWebPath['file']; |
|
1912
|
|
|
$pictureWebDir = $imageWebPath['dir']; |
|
1913
|
|
|
|
|
1914
|
|
|
$pictureAnonymousSize = '128'; |
|
1915
|
|
|
$gravatarSize = 22; |
|
1916
|
|
|
$realSizeName = 'small_'; |
|
1917
|
|
|
|
|
1918
|
|
|
switch ($size) { |
|
1919
|
|
|
case USER_IMAGE_SIZE_SMALL: |
|
1920
|
|
|
$pictureAnonymousSize = '32'; |
|
1921
|
|
|
$realSizeName = 'small_'; |
|
1922
|
|
|
$gravatarSize = 32; |
|
1923
|
|
|
break; |
|
1924
|
|
|
case USER_IMAGE_SIZE_MEDIUM: |
|
1925
|
|
|
$pictureAnonymousSize = '64'; |
|
1926
|
|
|
$realSizeName = 'medium_'; |
|
1927
|
|
|
$gravatarSize = 64; |
|
1928
|
|
|
break; |
|
1929
|
|
|
case USER_IMAGE_SIZE_ORIGINAL: |
|
1930
|
|
|
$pictureAnonymousSize = '128'; |
|
1931
|
|
|
$realSizeName = ''; |
|
1932
|
|
|
$gravatarSize = 128; |
|
1933
|
|
|
break; |
|
1934
|
|
|
case USER_IMAGE_SIZE_BIG: |
|
1935
|
|
|
$pictureAnonymousSize = '128'; |
|
1936
|
|
|
$realSizeName = 'big_'; |
|
1937
|
|
|
$gravatarSize = 128; |
|
1938
|
|
|
break; |
|
1939
|
|
|
} |
|
1940
|
|
|
|
|
1941
|
|
|
$gravatarEnabled = api_get_setting('gravatar_enabled'); |
|
1942
|
|
|
$anonymousPath = Display::returnIconPath('unknown.png', $pictureAnonymousSize); |
|
1943
|
|
|
if ('unknown.jpg' == $pictureWebFile || empty($pictureWebFile)) { |
|
1944
|
|
|
if ('true' === $gravatarEnabled) { |
|
1945
|
|
|
$file = self::getGravatar( |
|
1946
|
|
|
$imageWebPath['email'], |
|
1947
|
|
|
$gravatarSize, |
|
1948
|
|
|
api_get_setting('gravatar_type') |
|
1949
|
|
|
); |
|
1950
|
|
|
|
|
1951
|
|
|
if ($addRandomId) { |
|
1952
|
|
|
$file .= '&rand='.uniqid(); |
|
1953
|
|
|
} |
|
1954
|
|
|
|
|
1955
|
|
|
return $file; |
|
1956
|
|
|
} |
|
1957
|
|
|
|
|
1958
|
|
|
return $anonymousPath; |
|
1959
|
|
|
} |
|
1960
|
|
|
|
|
1961
|
|
|
if ($addRandomId) { |
|
1962
|
|
|
$picture .= '?rand='.uniqid(); |
|
1963
|
|
|
} |
|
1964
|
|
|
|
|
1965
|
|
|
return $picture;*/ |
|
1966
|
|
|
} |
|
1967
|
|
|
|
|
1968
|
|
|
/** |
|
1969
|
|
|
* Creates new user photos in various sizes of a user, or deletes user photos. |
|
1970
|
|
|
* Note: This method relies on configuration setting from main/inc/conf/profile.conf.php. |
|
1971
|
|
|
* |
|
1972
|
|
|
* @param int $user_id the user internal identification number |
|
1973
|
|
|
* @param string $file The common file name for the newly created photos. |
|
1974
|
|
|
* It will be checked and modified for compatibility with the file system. |
|
1975
|
|
|
* If full name is provided, path component is ignored. |
|
1976
|
|
|
* If an empty name is provided, then old user photos are deleted only, |
|
1977
|
|
|
* |
|
1978
|
|
|
* @see UserManager::delete_user_picture() as the prefered way for deletion. |
|
1979
|
|
|
* |
|
1980
|
|
|
* @param string $source_file the full system name of the image from which user photos will be created |
|
1981
|
|
|
* @param string $cropParameters Optional string that contents "x,y,width,height" of a cropped image format |
|
1982
|
|
|
* |
|
1983
|
|
|
* @return bool Returns the resulting common file name of created images which usually should be stored in database. |
|
1984
|
|
|
* When deletion is requested returns empty string. |
|
1985
|
|
|
* In case of internal error or negative validation returns FALSE. |
|
1986
|
|
|
*/ |
|
1987
|
|
|
public static function update_user_picture($userId, UploadedFile $file, string $crop = '') |
|
1988
|
|
|
{ |
|
1989
|
|
|
if (empty($userId) || empty($file)) { |
|
1990
|
|
|
return false; |
|
1991
|
|
|
} |
|
1992
|
|
|
|
|
1993
|
|
|
$repo = Container::getUserRepository(); |
|
1994
|
|
|
$user = $repo->find($userId); |
|
1995
|
|
|
if ($user) { |
|
1996
|
|
|
$repoIllustration = Container::getIllustrationRepository(); |
|
1997
|
|
|
$repoIllustration->addIllustration($user, $user, $file, $crop); |
|
1998
|
|
|
} |
|
1999
|
|
|
} |
|
2000
|
|
|
|
|
2001
|
|
|
/** |
|
2002
|
|
|
* Deletes user photos. |
|
2003
|
|
|
* |
|
2004
|
|
|
* @param int $userId the user internal identification number |
|
2005
|
|
|
* |
|
2006
|
|
|
* @return mixed returns empty string on success, FALSE on error |
|
2007
|
|
|
*/ |
|
2008
|
|
|
public static function deleteUserPicture($userId) |
|
2009
|
|
|
{ |
|
2010
|
|
|
$repo = Container::getUserRepository(); |
|
2011
|
|
|
$user = $repo->find($userId); |
|
2012
|
|
|
if ($user) { |
|
2013
|
|
|
$illustrationRepo = Container::getIllustrationRepository(); |
|
2014
|
|
|
$illustrationRepo->deleteIllustration($user); |
|
2015
|
|
|
} |
|
2016
|
|
|
} |
|
2017
|
|
|
|
|
2018
|
|
|
/** |
|
2019
|
|
|
* Returns an XHTML formatted list of productions for a user, or FALSE if he |
|
2020
|
|
|
* doesn't have any. |
|
2021
|
|
|
* |
|
2022
|
|
|
* If there has been a request to remove a production, the function will return |
|
2023
|
|
|
* without building the list unless forced to do so by the optional second |
|
2024
|
|
|
* parameter. This increases performance by avoiding to read through the |
|
2025
|
|
|
* productions on the filesystem before the removal request has been carried |
|
2026
|
|
|
* out because they'll have to be re-read afterwards anyway. |
|
2027
|
|
|
* |
|
2028
|
|
|
* @deprecated This method is being removed from chamilo 2.0 |
|
2029
|
|
|
* @param int $user_id User id |
|
2030
|
|
|
* @param bool $force Optional parameter to force building after a removal request |
|
2031
|
|
|
* @param bool $showDelete |
|
2032
|
|
|
* |
|
2033
|
|
|
* @return string A string containing the XHTML code to display the production list, or FALSE |
|
2034
|
|
|
*/ |
|
2035
|
|
|
public static function build_production_list($user_id, $force = false, $showDelete = false) |
|
2036
|
|
|
{ |
|
2037
|
|
|
if (!$force && !empty($_POST['remove_production'])) { |
|
2038
|
|
|
return true; // postpone reading from the filesystem |
|
2039
|
|
|
} |
|
2040
|
|
|
|
|
2041
|
|
|
$productions = self::get_user_productions($user_id); |
|
2042
|
|
|
|
|
2043
|
|
|
if (empty($productions)) { |
|
2044
|
|
|
return false; |
|
2045
|
|
|
} |
|
2046
|
|
|
|
|
2047
|
|
|
return false; |
|
2048
|
|
|
|
|
2049
|
|
|
$production_dir = self::getUserPathById($user_id, 'web'); |
|
|
|
|
|
|
2050
|
|
|
$del_image = Display::returnIconPath('delete.png'); |
|
2051
|
|
|
$add_image = Display::returnIconPath('archive.png'); |
|
2052
|
|
|
$del_text = get_lang('Delete'); |
|
2053
|
|
|
$production_list = ''; |
|
2054
|
|
|
if (count($productions) > 0) { |
|
2055
|
|
|
$production_list = '<div class="files-production"><ul id="productions">'; |
|
2056
|
|
|
foreach ($productions as $file) { |
|
2057
|
|
|
$production_list .= '<li> |
|
2058
|
|
|
<img src="'.$add_image.'" /> |
|
2059
|
|
|
<a href="'.$production_dir.urlencode($file).'" target="_blank"> |
|
2060
|
|
|
'.htmlentities($file).' |
|
2061
|
|
|
</a>'; |
|
2062
|
|
|
if ($showDelete) { |
|
2063
|
|
|
$production_list .= ' |
|
2064
|
|
|
<input |
|
2065
|
|
|
style="width:16px;" |
|
2066
|
|
|
type="image" |
|
2067
|
|
|
name="remove_production['.urlencode($file).']" |
|
2068
|
|
|
src="'.$del_image.'" |
|
2069
|
|
|
alt="'.$del_text.'" |
|
2070
|
|
|
title="'.$del_text.' '.htmlentities($file).'" |
|
2071
|
|
|
onclick="javascript: return confirmation(\''.htmlentities($file).'\');" /></li>'; |
|
2072
|
|
|
} |
|
2073
|
|
|
} |
|
2074
|
|
|
$production_list .= '</ul></div>'; |
|
2075
|
|
|
} |
|
2076
|
|
|
|
|
2077
|
|
|
return $production_list; |
|
2078
|
|
|
} |
|
2079
|
|
|
|
|
2080
|
|
|
/** |
|
2081
|
|
|
* Returns an array with the user's productions. |
|
2082
|
|
|
* |
|
2083
|
|
|
* @param int $user_id User id |
|
2084
|
|
|
* |
|
2085
|
|
|
* @return array An array containing the user's productions |
|
2086
|
|
|
*/ |
|
2087
|
|
|
public static function get_user_productions($user_id) |
|
2088
|
|
|
{ |
|
2089
|
|
|
return []; |
|
2090
|
|
|
|
|
2091
|
|
|
$production_repository = self::getUserPathById($user_id, 'system'); |
|
|
|
|
|
|
2092
|
|
|
$productions = []; |
|
2093
|
|
|
|
|
2094
|
|
|
if (is_dir($production_repository)) { |
|
2095
|
|
|
$handle = opendir($production_repository); |
|
2096
|
|
|
while ($file = readdir($handle)) { |
|
2097
|
|
|
if ('.' == $file || |
|
2098
|
|
|
'..' == $file || |
|
2099
|
|
|
'.htaccess' == $file || |
|
2100
|
|
|
is_dir($production_repository.$file) |
|
2101
|
|
|
) { |
|
2102
|
|
|
// skip current/parent directory and .htaccess |
|
2103
|
|
|
continue; |
|
2104
|
|
|
} |
|
2105
|
|
|
|
|
2106
|
|
|
if (preg_match('/('.$user_id.'|[0-9a-f]{13}|saved)_.+\.(png|jpg|jpeg|gif)$/i', $file)) { |
|
2107
|
|
|
// User's photos should not be listed as productions. |
|
2108
|
|
|
continue; |
|
2109
|
|
|
} |
|
2110
|
|
|
$productions[] = $file; |
|
2111
|
|
|
} |
|
2112
|
|
|
} |
|
2113
|
|
|
|
|
2114
|
|
|
return $productions; |
|
2115
|
|
|
} |
|
2116
|
|
|
|
|
2117
|
|
|
/** |
|
2118
|
|
|
* Remove a user production. |
|
2119
|
|
|
* |
|
2120
|
|
|
* @param int $user_id User id |
|
2121
|
|
|
* @param string $production The production to remove |
|
2122
|
|
|
* |
|
2123
|
|
|
* @return bool |
|
2124
|
|
|
*/ |
|
2125
|
|
|
public static function remove_user_production($user_id, $production) |
|
2126
|
|
|
{ |
|
2127
|
|
|
throw new Exception('remove_user_production'); |
|
2128
|
|
|
/*$production_path = self::get_user_picture_path_by_id($user_id, 'system'); |
|
2129
|
|
|
$production_file = $production_path['dir'].$production; |
|
2130
|
|
|
if (is_file($production_file)) { |
|
2131
|
|
|
unlink($production_file); |
|
2132
|
|
|
|
|
2133
|
|
|
return true; |
|
2134
|
|
|
} |
|
2135
|
|
|
|
|
2136
|
|
|
return false;*/ |
|
2137
|
|
|
} |
|
2138
|
|
|
|
|
2139
|
|
|
/** |
|
2140
|
|
|
* Update an extra field value for a given user. |
|
2141
|
|
|
* |
|
2142
|
|
|
* @param int $userId User ID |
|
2143
|
|
|
* @param string $variable Field variable name |
|
2144
|
|
|
* @param string $value Field value |
|
2145
|
|
|
* |
|
2146
|
|
|
* @return bool true if field updated, false otherwise |
|
2147
|
|
|
*/ |
|
2148
|
|
|
public static function update_extra_field_value($userId, $variable, $value = '') |
|
2149
|
|
|
{ |
|
2150
|
|
|
$extraFieldValue = new ExtraFieldValue('user'); |
|
2151
|
|
|
$params = [ |
|
2152
|
|
|
'item_id' => $userId, |
|
2153
|
|
|
'variable' => $variable, |
|
2154
|
|
|
'field_value' => $value, |
|
2155
|
|
|
]; |
|
2156
|
|
|
|
|
2157
|
|
|
return $extraFieldValue->save($params); |
|
|
|
|
|
|
2158
|
|
|
} |
|
2159
|
|
|
|
|
2160
|
|
|
/** |
|
2161
|
|
|
* Get an array of extra fields with field details (type, default value and options). |
|
2162
|
|
|
* |
|
2163
|
|
|
* @param int Offset (from which row) |
|
2164
|
|
|
* @param int Number of items |
|
2165
|
|
|
* @param int Column on which sorting is made |
|
2166
|
|
|
* @param string Sorting direction |
|
2167
|
|
|
* @param bool Optional. Whether we get all the fields or just the visible ones |
|
|
|
|
|
|
2168
|
|
|
* @param int Optional. Whether we get all the fields with field_filter 1 or 0 or everything |
|
2169
|
|
|
* |
|
2170
|
|
|
* @return array Extra fields details (e.g. $list[2]['type'], $list[4]['options'][2]['title'] |
|
2171
|
|
|
*/ |
|
2172
|
|
|
public static function get_extra_fields( |
|
2173
|
|
|
$from = 0, |
|
2174
|
|
|
$number_of_items = 0, |
|
2175
|
|
|
$column = 5, |
|
2176
|
|
|
$direction = 'ASC', |
|
2177
|
|
|
$all_visibility = true, |
|
2178
|
|
|
$field_filter = null |
|
2179
|
|
|
) { |
|
2180
|
|
|
$fields = []; |
|
2181
|
|
|
$t_uf = Database::get_main_table(TABLE_EXTRA_FIELD); |
|
2182
|
|
|
$t_ufo = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS); |
|
2183
|
|
|
$columns = [ |
|
2184
|
|
|
'id', |
|
2185
|
|
|
'variable', |
|
2186
|
|
|
'value_type', |
|
2187
|
|
|
'display_text', |
|
2188
|
|
|
'default_value', |
|
2189
|
|
|
'field_order', |
|
2190
|
|
|
'filter', |
|
2191
|
|
|
]; |
|
2192
|
|
|
$column = (int) $column; |
|
2193
|
|
|
$sort_direction = ''; |
|
2194
|
|
|
if (in_array(strtoupper($direction), ['ASC', 'DESC'])) { |
|
2195
|
|
|
$sort_direction = strtoupper($direction); |
|
2196
|
|
|
} |
|
2197
|
|
|
$extraFieldType = EntityExtraField::USER_FIELD_TYPE; |
|
2198
|
|
|
$sqlf = "SELECT * FROM $t_uf WHERE item_type = $extraFieldType "; |
|
2199
|
|
|
if (!$all_visibility) { |
|
2200
|
|
|
$sqlf .= " AND visible_to_self = 1 "; |
|
2201
|
|
|
} |
|
2202
|
|
|
if (!is_null($field_filter)) { |
|
2203
|
|
|
$field_filter = (int) $field_filter; |
|
2204
|
|
|
$sqlf .= " AND filter = $field_filter "; |
|
2205
|
|
|
} |
|
2206
|
|
|
$sqlf .= " ORDER BY `".$columns[$column]."` $sort_direction "; |
|
2207
|
|
|
if (0 != $number_of_items) { |
|
2208
|
|
|
$sqlf .= " LIMIT ".intval($from).','.intval($number_of_items); |
|
2209
|
|
|
} |
|
2210
|
|
|
$resf = Database::query($sqlf); |
|
2211
|
|
|
if (Database::num_rows($resf) > 0) { |
|
2212
|
|
|
while ($rowf = Database::fetch_array($resf)) { |
|
2213
|
|
|
$fields[$rowf['id']] = [ |
|
2214
|
|
|
0 => $rowf['id'], |
|
2215
|
|
|
1 => $rowf['variable'], |
|
2216
|
|
|
2 => $rowf['value_type'], |
|
2217
|
|
|
3 => empty($rowf['display_text']) ? '' : $rowf['display_text'], |
|
2218
|
|
|
4 => $rowf['default_value'], |
|
2219
|
|
|
5 => $rowf['field_order'], |
|
2220
|
|
|
6 => $rowf['visible_to_self'], |
|
2221
|
|
|
7 => $rowf['changeable'], |
|
2222
|
|
|
8 => $rowf['filter'], |
|
2223
|
|
|
9 => [], |
|
2224
|
|
|
10 => '<a name="'.$rowf['id'].'"></a>', |
|
2225
|
|
|
]; |
|
2226
|
|
|
|
|
2227
|
|
|
$sqlo = "SELECT * FROM $t_ufo |
|
2228
|
|
|
WHERE field_id = ".$rowf['id']." |
|
2229
|
|
|
ORDER BY option_order ASC"; |
|
2230
|
|
|
$reso = Database::query($sqlo); |
|
2231
|
|
|
if (Database::num_rows($reso) > 0) { |
|
2232
|
|
|
while ($rowo = Database::fetch_array($reso)) { |
|
2233
|
|
|
$fields[$rowf['id']][9][$rowo['id']] = [ |
|
2234
|
|
|
0 => $rowo['id'], |
|
2235
|
|
|
1 => $rowo['option_value'], |
|
2236
|
|
|
2 => empty($rowo['display_text']) ? '' : $rowo['display_text'], |
|
2237
|
|
|
3 => $rowo['option_order'], |
|
2238
|
|
|
]; |
|
2239
|
|
|
} |
|
2240
|
|
|
} |
|
2241
|
|
|
} |
|
2242
|
|
|
} |
|
2243
|
|
|
|
|
2244
|
|
|
return $fields; |
|
2245
|
|
|
} |
|
2246
|
|
|
|
|
2247
|
|
|
/** |
|
2248
|
|
|
* Creates a new extra field. |
|
2249
|
|
|
* |
|
2250
|
|
|
* @param string $variable Field's internal variable name |
|
2251
|
|
|
* @param int $fieldType Field's type |
|
2252
|
|
|
* @param string $displayText Field's language var name |
|
2253
|
|
|
* @param string $default Field's default value |
|
2254
|
|
|
* |
|
2255
|
|
|
* @return int |
|
2256
|
|
|
*/ |
|
2257
|
|
|
public static function create_extra_field( |
|
2258
|
|
|
$variable, |
|
2259
|
|
|
$valueType, |
|
2260
|
|
|
$displayText, |
|
2261
|
|
|
$default |
|
2262
|
|
|
) { |
|
2263
|
|
|
$extraField = new ExtraField('user'); |
|
2264
|
|
|
$params = [ |
|
2265
|
|
|
'variable' => $variable, |
|
2266
|
|
|
'value_type' => $valueType, |
|
2267
|
|
|
'display_text' => $displayText, |
|
2268
|
|
|
'default_value' => $default, |
|
2269
|
|
|
]; |
|
2270
|
|
|
|
|
2271
|
|
|
return $extraField->save($params); |
|
|
|
|
|
|
2272
|
|
|
} |
|
2273
|
|
|
|
|
2274
|
|
|
/** |
|
2275
|
|
|
* Check if a field is available. |
|
2276
|
|
|
* |
|
2277
|
|
|
* @param string $variable |
|
2278
|
|
|
* |
|
2279
|
|
|
* @return bool |
|
2280
|
|
|
*/ |
|
2281
|
|
|
public static function is_extra_field_available($variable) |
|
2282
|
|
|
{ |
|
2283
|
|
|
$extraField = new ExtraField('user'); |
|
2284
|
|
|
$data = $extraField->get_handler_field_info_by_field_variable($variable); |
|
2285
|
|
|
|
|
2286
|
|
|
return !empty($data) ? true : false; |
|
2287
|
|
|
} |
|
2288
|
|
|
|
|
2289
|
|
|
/** |
|
2290
|
|
|
* Gets user extra fields data. |
|
2291
|
|
|
* |
|
2292
|
|
|
* @param int User ID |
|
2293
|
|
|
* @param bool Whether to prefix the fields indexes with "extra_" (might be used by formvalidator) |
|
2294
|
|
|
* @param bool Whether to return invisible fields as well |
|
2295
|
|
|
* @param bool Whether to split multiple-selection fields or not |
|
2296
|
|
|
* |
|
2297
|
|
|
* @return array Array of fields => value for the given user |
|
2298
|
|
|
*/ |
|
2299
|
|
|
public static function get_extra_user_data( |
|
2300
|
|
|
$user_id, |
|
2301
|
|
|
$prefix = false, |
|
2302
|
|
|
$allVisibility = true, |
|
2303
|
|
|
$splitMultiple = false, |
|
2304
|
|
|
$fieldFilter = null |
|
2305
|
|
|
) { |
|
2306
|
|
|
$user_id = (int) $user_id; |
|
2307
|
|
|
|
|
2308
|
|
|
if (empty($user_id)) { |
|
2309
|
|
|
return []; |
|
2310
|
|
|
} |
|
2311
|
|
|
|
|
2312
|
|
|
$extra_data = []; |
|
2313
|
|
|
$t_uf = Database::get_main_table(TABLE_EXTRA_FIELD); |
|
2314
|
|
|
$t_ufv = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
|
2315
|
|
|
$sql = "SELECT f.id as id, f.variable as fvar, f.value_type as type |
|
2316
|
|
|
FROM $t_uf f |
|
2317
|
|
|
WHERE |
|
2318
|
|
|
item_type = ".EntityExtraField::USER_FIELD_TYPE." |
|
2319
|
|
|
"; |
|
2320
|
|
|
$filter_cond = ''; |
|
2321
|
|
|
|
|
2322
|
|
|
if (!$allVisibility) { |
|
2323
|
|
|
if (isset($fieldFilter)) { |
|
2324
|
|
|
$fieldFilter = (int) $fieldFilter; |
|
2325
|
|
|
$filter_cond .= " AND filter = $fieldFilter "; |
|
2326
|
|
|
} |
|
2327
|
|
|
$sql .= " AND f.visible_to_self = 1 $filter_cond "; |
|
2328
|
|
|
} else { |
|
2329
|
|
|
if (isset($fieldFilter)) { |
|
2330
|
|
|
$fieldFilter = (int) $fieldFilter; |
|
2331
|
|
|
$sql .= " AND filter = $fieldFilter "; |
|
2332
|
|
|
} |
|
2333
|
|
|
} |
|
2334
|
|
|
|
|
2335
|
|
|
$sql .= ' ORDER BY f.field_order'; |
|
2336
|
|
|
|
|
2337
|
|
|
$res = Database::query($sql); |
|
2338
|
|
|
if (Database::num_rows($res) > 0) { |
|
2339
|
|
|
while ($row = Database::fetch_array($res)) { |
|
2340
|
|
|
if (self::USER_FIELD_TYPE_TAG == $row['type']) { |
|
2341
|
|
|
$tags = self::get_user_tags_to_string($user_id, $row['id'], false); |
|
2342
|
|
|
$extra_data['extra_'.$row['fvar']] = $tags; |
|
2343
|
|
|
} else { |
|
2344
|
|
|
$sqlu = "SELECT field_value as fval |
|
2345
|
|
|
FROM $t_ufv |
|
2346
|
|
|
WHERE field_id=".$row['id']." AND item_id = ".$user_id; |
|
2347
|
|
|
$resu = Database::query($sqlu); |
|
2348
|
|
|
// get default value |
|
2349
|
|
|
$sql_df = "SELECT default_value as fval_df FROM $t_uf |
|
2350
|
|
|
WHERE id=".$row['id']; |
|
2351
|
|
|
$res_df = Database::query($sql_df); |
|
2352
|
|
|
|
|
2353
|
|
|
if (Database::num_rows($resu) > 0) { |
|
2354
|
|
|
$rowu = Database::fetch_array($resu); |
|
2355
|
|
|
$fval = $rowu['fval']; |
|
2356
|
|
|
if (self::USER_FIELD_TYPE_SELECT_MULTIPLE == $row['type']) { |
|
2357
|
|
|
$fval = explode(';', $rowu['fval']); |
|
2358
|
|
|
} |
|
2359
|
|
|
} else { |
|
2360
|
|
|
$row_df = Database::fetch_array($res_df); |
|
2361
|
|
|
$fval = $row_df['fval_df']; |
|
2362
|
|
|
} |
|
2363
|
|
|
// We get here (and fill the $extra_data array) even if there |
|
2364
|
|
|
// is no user with data (we fill it with default values) |
|
2365
|
|
|
if ($prefix) { |
|
2366
|
|
|
if (self::USER_FIELD_TYPE_RADIO == $row['type']) { |
|
2367
|
|
|
$extra_data['extra_'.$row['fvar']]['extra_'.$row['fvar']] = $fval; |
|
2368
|
|
|
} else { |
|
2369
|
|
|
$extra_data['extra_'.$row['fvar']] = $fval; |
|
2370
|
|
|
} |
|
2371
|
|
|
} else { |
|
2372
|
|
|
if (self::USER_FIELD_TYPE_RADIO == $row['type']) { |
|
2373
|
|
|
$extra_data['extra_'.$row['fvar']]['extra_'.$row['fvar']] = $fval; |
|
2374
|
|
|
} else { |
|
2375
|
|
|
$extra_data[$row['fvar']] = $fval; |
|
2376
|
|
|
} |
|
2377
|
|
|
} |
|
2378
|
|
|
} |
|
2379
|
|
|
} |
|
2380
|
|
|
} |
|
2381
|
|
|
|
|
2382
|
|
|
return $extra_data; |
|
2383
|
|
|
} |
|
2384
|
|
|
|
|
2385
|
|
|
/** Get extra user data by field. |
|
2386
|
|
|
* @param int user ID |
|
2387
|
|
|
* @param string the internal variable name of the field |
|
2388
|
|
|
* |
|
2389
|
|
|
* @return array with extra data info of a user i.e array('field_variable'=>'value'); |
|
2390
|
|
|
*/ |
|
2391
|
|
|
public static function get_extra_user_data_by_field( |
|
2392
|
|
|
$user_id, |
|
2393
|
|
|
$field_variable, |
|
2394
|
|
|
$prefix = false, |
|
2395
|
|
|
$all_visibility = true, |
|
2396
|
|
|
$splitmultiple = false |
|
2397
|
|
|
) { |
|
2398
|
|
|
$user_id = (int) $user_id; |
|
2399
|
|
|
|
|
2400
|
|
|
if (empty($user_id)) { |
|
2401
|
|
|
return []; |
|
2402
|
|
|
} |
|
2403
|
|
|
|
|
2404
|
|
|
$extra_data = []; |
|
2405
|
|
|
$t_uf = Database::get_main_table(TABLE_EXTRA_FIELD); |
|
2406
|
|
|
$t_ufv = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
|
2407
|
|
|
|
|
2408
|
|
|
$sql = "SELECT f.id as id, f.variable as fvar, f.value_type as type |
|
2409
|
|
|
FROM $t_uf f |
|
2410
|
|
|
WHERE f.variable = '$field_variable' "; |
|
2411
|
|
|
|
|
2412
|
|
|
if (!$all_visibility) { |
|
2413
|
|
|
$sql .= " AND f.visible_to_self = 1 "; |
|
2414
|
|
|
} |
|
2415
|
|
|
|
|
2416
|
|
|
$sql .= " AND item_type = ".EntityExtraField::USER_FIELD_TYPE; |
|
2417
|
|
|
$sql .= " ORDER BY f.field_order "; |
|
2418
|
|
|
|
|
2419
|
|
|
$res = Database::query($sql); |
|
2420
|
|
|
if (Database::num_rows($res) > 0) { |
|
2421
|
|
|
while ($row = Database::fetch_array($res)) { |
|
2422
|
|
|
$sqlu = "SELECT field_value as fval FROM $t_ufv v |
|
2423
|
|
|
INNER JOIN $t_uf f |
|
2424
|
|
|
ON (v.field_id = f.id) |
|
2425
|
|
|
WHERE |
|
2426
|
|
|
item_type = ".EntityExtraField::USER_FIELD_TYPE." AND |
|
2427
|
|
|
field_id = ".$row['id']." AND |
|
2428
|
|
|
item_id = ".$user_id; |
|
2429
|
|
|
$resu = Database::query($sqlu); |
|
2430
|
|
|
$fval = ''; |
|
2431
|
|
|
if (Database::num_rows($resu) > 0) { |
|
2432
|
|
|
$rowu = Database::fetch_array($resu); |
|
2433
|
|
|
$fval = $rowu['fval']; |
|
2434
|
|
|
if (self::USER_FIELD_TYPE_SELECT_MULTIPLE == $row['type']) { |
|
2435
|
|
|
$fval = explode(';', $rowu['fval']); |
|
2436
|
|
|
} |
|
2437
|
|
|
} |
|
2438
|
|
|
if ($prefix) { |
|
2439
|
|
|
$extra_data['extra_'.$row['fvar']] = $fval; |
|
2440
|
|
|
} else { |
|
2441
|
|
|
$extra_data[$row['fvar']] = $fval; |
|
2442
|
|
|
} |
|
2443
|
|
|
} |
|
2444
|
|
|
} |
|
2445
|
|
|
|
|
2446
|
|
|
return $extra_data; |
|
2447
|
|
|
} |
|
2448
|
|
|
|
|
2449
|
|
|
/** |
|
2450
|
|
|
* Get the extra field information for a certain field (the options as well). |
|
2451
|
|
|
* |
|
2452
|
|
|
* @param int $variable The name of the field we want to know everything about |
|
2453
|
|
|
* |
|
2454
|
|
|
* @return array Array containing all the information about the extra profile field |
|
2455
|
|
|
* (first level of array contains field details, then 'options' sub-array contains options details, |
|
2456
|
|
|
* as returned by the database) |
|
2457
|
|
|
* |
|
2458
|
|
|
* @author Julio Montoya |
|
2459
|
|
|
* |
|
2460
|
|
|
* @since v1.8.6 |
|
2461
|
|
|
*/ |
|
2462
|
|
|
public static function get_extra_field_information_by_name($variable) |
|
2463
|
|
|
{ |
|
2464
|
|
|
$extraField = new ExtraField('user'); |
|
2465
|
|
|
|
|
2466
|
|
|
return $extraField->get_handler_field_info_by_field_variable($variable); |
|
|
|
|
|
|
2467
|
|
|
} |
|
2468
|
|
|
|
|
2469
|
|
|
/** |
|
2470
|
|
|
* Get the extra field information for user tag (the options as well). |
|
2471
|
|
|
* |
|
2472
|
|
|
* @param int $variable The name of the field we want to know everything about |
|
2473
|
|
|
* |
|
2474
|
|
|
* @return array Array containing all the information about the extra profile field |
|
2475
|
|
|
* (first level of array contains field details, then 'options' sub-array contains options details, |
|
2476
|
|
|
* as returned by the database) |
|
2477
|
|
|
* |
|
2478
|
|
|
* @author José Loguercio |
|
2479
|
|
|
* |
|
2480
|
|
|
* @since v1.11.0 |
|
2481
|
|
|
*/ |
|
2482
|
|
|
public static function get_extra_field_tags_information_by_name($variable) |
|
2483
|
|
|
{ |
|
2484
|
|
|
$extraField = new ExtraField('user'); |
|
2485
|
|
|
|
|
2486
|
|
|
return $extraField->get_handler_field_info_by_tags($variable); |
|
|
|
|
|
|
2487
|
|
|
} |
|
2488
|
|
|
|
|
2489
|
|
|
/** |
|
2490
|
|
|
* Get all the extra field information of a certain field (also the options). |
|
2491
|
|
|
* |
|
2492
|
|
|
* @param int $fieldId the ID of the field we want to know everything of |
|
2493
|
|
|
* |
|
2494
|
|
|
* @return array $return containing all th information about the extra profile field |
|
2495
|
|
|
* |
|
2496
|
|
|
* @author Julio Montoya |
|
2497
|
|
|
* |
|
2498
|
|
|
* @deprecated |
|
2499
|
|
|
* @since v1.8.6 |
|
2500
|
|
|
*/ |
|
2501
|
|
|
public static function get_extra_field_information($fieldId) |
|
2502
|
|
|
{ |
|
2503
|
|
|
$extraField = new ExtraField('user'); |
|
2504
|
|
|
|
|
2505
|
|
|
return $extraField->getFieldInfoByFieldId($fieldId); |
|
|
|
|
|
|
2506
|
|
|
} |
|
2507
|
|
|
|
|
2508
|
|
|
/** |
|
2509
|
|
|
* Get extra user data by value. |
|
2510
|
|
|
* |
|
2511
|
|
|
* @param string $variable the internal variable name of the field |
|
2512
|
|
|
* @param string $value the internal value of the field |
|
2513
|
|
|
* @param bool $all_visibility |
|
2514
|
|
|
* |
|
2515
|
|
|
* @return array with extra data info of a user i.e array('field_variable'=>'value'); |
|
2516
|
|
|
*/ |
|
2517
|
|
|
public static function get_extra_user_data_by_value($variable, $value, $all_visibility = true) |
|
2518
|
|
|
{ |
|
2519
|
|
|
$extraFieldValue = new ExtraFieldValue('user'); |
|
2520
|
|
|
$extraField = new ExtraField('user'); |
|
2521
|
|
|
|
|
2522
|
|
|
$info = $extraField->get_handler_field_info_by_field_variable($variable); |
|
2523
|
|
|
|
|
2524
|
|
|
if (false === $info) { |
|
2525
|
|
|
return []; |
|
2526
|
|
|
} |
|
2527
|
|
|
|
|
2528
|
|
|
$data = $extraFieldValue->get_item_id_from_field_variable_and_field_value( |
|
2529
|
|
|
$variable, |
|
2530
|
|
|
$value, |
|
2531
|
|
|
false, |
|
2532
|
|
|
false, |
|
2533
|
|
|
true |
|
2534
|
|
|
); |
|
2535
|
|
|
|
|
2536
|
|
|
$result = []; |
|
2537
|
|
|
if (!empty($data)) { |
|
2538
|
|
|
foreach ($data as $item) { |
|
2539
|
|
|
$result[] = $item['item_id']; |
|
2540
|
|
|
} |
|
2541
|
|
|
} |
|
2542
|
|
|
|
|
2543
|
|
|
return $result; |
|
2544
|
|
|
} |
|
2545
|
|
|
|
|
2546
|
|
|
/** |
|
2547
|
|
|
* Get extra user data by tags value. |
|
2548
|
|
|
* |
|
2549
|
|
|
* @param int $fieldId the ID of the field we want to know everything of |
|
2550
|
|
|
* @param string $tag the tag name for search |
|
2551
|
|
|
* |
|
2552
|
|
|
* @return array with extra data info of a user |
|
2553
|
|
|
* |
|
2554
|
|
|
* @author José Loguercio |
|
2555
|
|
|
* |
|
2556
|
|
|
* @since v1.11.0 |
|
2557
|
|
|
*/ |
|
2558
|
|
|
public static function get_extra_user_data_by_tags($fieldId, $tag) |
|
2559
|
|
|
{ |
|
2560
|
|
|
$extraField = new ExtraField('user'); |
|
2561
|
|
|
$result = $extraField->getAllUserPerTag($fieldId, $tag); |
|
2562
|
|
|
$array = []; |
|
2563
|
|
|
foreach ($result as $index => $user) { |
|
2564
|
|
|
$array[] = $user['user_id']; |
|
2565
|
|
|
} |
|
2566
|
|
|
|
|
2567
|
|
|
return $array; |
|
2568
|
|
|
} |
|
2569
|
|
|
|
|
2570
|
|
|
/** |
|
2571
|
|
|
* Get extra user data by field variable. |
|
2572
|
|
|
* |
|
2573
|
|
|
* @param string $variable field variable |
|
2574
|
|
|
* |
|
2575
|
|
|
* @return array data |
|
2576
|
|
|
*/ |
|
2577
|
|
|
public static function get_extra_user_data_by_field_variable($variable) |
|
2578
|
|
|
{ |
|
2579
|
|
|
$extraInfo = self::get_extra_field_information_by_name($variable); |
|
2580
|
|
|
$field_id = (int) $extraInfo['id']; |
|
2581
|
|
|
|
|
2582
|
|
|
$extraField = new ExtraFieldValue('user'); |
|
2583
|
|
|
$data = $extraField->getValuesByFieldId($field_id); |
|
2584
|
|
|
|
|
2585
|
|
|
if (!empty($data)) { |
|
2586
|
|
|
foreach ($data as $row) { |
|
2587
|
|
|
$user_id = $row['item_id']; |
|
2588
|
|
|
$data[$user_id] = $row; |
|
2589
|
|
|
} |
|
2590
|
|
|
} |
|
2591
|
|
|
|
|
2592
|
|
|
return $data; |
|
|
|
|
|
|
2593
|
|
|
} |
|
2594
|
|
|
|
|
2595
|
|
|
/** |
|
2596
|
|
|
* Get extra user data tags by field variable. |
|
2597
|
|
|
* |
|
2598
|
|
|
* @param string $variable field variable |
|
2599
|
|
|
* |
|
2600
|
|
|
* @return array |
|
2601
|
|
|
*/ |
|
2602
|
|
|
public static function get_extra_user_data_for_tags($variable) |
|
2603
|
|
|
{ |
|
2604
|
|
|
$data = self::get_extra_field_tags_information_by_name($variable); |
|
2605
|
|
|
|
|
2606
|
|
|
return $data; |
|
2607
|
|
|
} |
|
2608
|
|
|
|
|
2609
|
|
|
/** |
|
2610
|
|
|
* Gives a list of [session_category][session_id] for the current user. |
|
2611
|
|
|
* |
|
2612
|
|
|
* @param int $user_id |
|
2613
|
|
|
* @param bool $is_time_over whether to fill the first element or not |
|
2614
|
|
|
* (to give space for courses out of categories) |
|
2615
|
|
|
* @param bool $ignore_visibility_for_admins optional true if limit time from session is over, false otherwise |
|
2616
|
|
|
* @param bool $ignoreTimeLimit ignore time start/end |
|
2617
|
|
|
* @param bool $getCount |
|
2618
|
|
|
* |
|
2619
|
|
|
* @return array list of statuses [session_category][session_id] |
|
2620
|
|
|
* |
|
2621
|
|
|
* @todo ensure multiple access urls are managed correctly |
|
2622
|
|
|
*/ |
|
2623
|
|
|
public static function get_sessions_by_category( |
|
2624
|
|
|
$user_id, |
|
2625
|
|
|
$is_time_over = true, |
|
2626
|
|
|
$ignore_visibility_for_admins = false, |
|
2627
|
|
|
$ignoreTimeLimit = false, |
|
2628
|
|
|
$getCount = false |
|
2629
|
|
|
) { |
|
2630
|
|
|
$user_id = (int) $user_id; |
|
2631
|
|
|
|
|
2632
|
|
|
if (empty($user_id)) { |
|
2633
|
|
|
return []; |
|
2634
|
|
|
} |
|
2635
|
|
|
|
|
2636
|
|
|
// Get the list of sessions per user |
|
2637
|
|
|
$now = new DateTime('now', new DateTimeZone('UTC')); |
|
2638
|
|
|
|
|
2639
|
|
|
// LEFT JOIN is used for session_rel_course_rel_user because an inner |
|
2640
|
|
|
// join would not catch session-courses where the user is general |
|
2641
|
|
|
// session coach but which do not have students nor coaches registered |
|
2642
|
|
|
$dqlSelect = ' COUNT(DISTINCT s.id) '; |
|
2643
|
|
|
|
|
2644
|
|
|
if (!$getCount) { |
|
2645
|
|
|
$dqlSelect = " DISTINCT |
|
2646
|
|
|
s.id, |
|
2647
|
|
|
s.title, |
|
2648
|
|
|
s.accessStartDate AS access_start_date, |
|
2649
|
|
|
s.accessEndDate AS access_end_date, |
|
2650
|
|
|
s.duration, |
|
2651
|
|
|
sc.id AS session_category_id, |
|
2652
|
|
|
sc.title AS session_category_title, |
|
2653
|
|
|
sc.dateStart AS session_category_date_start, |
|
2654
|
|
|
sc.dateEnd AS session_category_date_end, |
|
2655
|
|
|
s.coachAccessStartDate AS coach_access_start_date, |
|
2656
|
|
|
s.coachAccessEndDate AS coach_access_end_date, |
|
2657
|
|
|
CASE WHEN s.accessEndDate IS NULL THEN 1 ELSE 0 END HIDDEN _isFieldNull |
|
2658
|
|
|
, s.position AS position |
|
2659
|
|
|
"; |
|
2660
|
|
|
} |
|
2661
|
|
|
|
|
2662
|
|
|
// A single OR operation on scu.user = :user OR s.generalCoach = :user |
|
2663
|
|
|
// is awfully inefficient for large sets of data (1m25s for 58K |
|
2664
|
|
|
// sessions, BT#14115) but executing a similar query twice and grouping |
|
2665
|
|
|
// the results afterwards in PHP takes about 1/1000th of the time |
|
2666
|
|
|
// (0.1s + 0.0s) for the same set of data, so we do it this way... |
|
2667
|
|
|
$dqlStudent = "SELECT $dqlSelect |
|
2668
|
|
|
FROM ChamiloCoreBundle:Session AS s |
|
2669
|
|
|
LEFT JOIN ChamiloCoreBundle:SessionRelCourseRelUser AS scu WITH scu.session = s |
|
2670
|
|
|
INNER JOIN ChamiloCoreBundle:AccessUrlRelSession AS url WITH url.session = s.id |
|
2671
|
|
|
LEFT JOIN ChamiloCoreBundle:SessionCategory AS sc WITH s.category = sc |
|
2672
|
|
|
WHERE scu.user = :user AND url.url = :url "; |
|
2673
|
|
|
$dqlCoach = "SELECT $dqlSelect |
|
2674
|
|
|
FROM ChamiloCoreBundle:Session AS s |
|
2675
|
|
|
INNER JOIN ChamiloCoreBundle:AccessUrlRelSession AS url WITH url.session = s.id |
|
2676
|
|
|
LEFT JOIN ChamiloCoreBundle:SessionCategory AS sc WITH s.category = sc |
|
2677
|
|
|
INNER JOIN ChamiloCoreBundle:SessionRelUser AS su WITH su.session = s |
|
2678
|
|
|
WHERE (su.user = :user AND su.relationType = ".SessionEntity::GENERAL_COACH.") AND url.url = :url "; |
|
2679
|
|
|
|
|
2680
|
|
|
// Default order |
|
2681
|
|
|
$order = 'ORDER BY sc.title, s.title'; |
|
2682
|
|
|
|
|
2683
|
|
|
// Order by date if showing all sessions |
|
2684
|
|
|
$showAllSessions = ('true' === api_get_setting('session.show_all_sessions_on_my_course_page')); |
|
2685
|
|
|
if ($showAllSessions) { |
|
2686
|
|
|
$order = 'ORDER BY s.accessStartDate'; |
|
2687
|
|
|
} |
|
2688
|
|
|
|
|
2689
|
|
|
// Order by position |
|
2690
|
|
|
if ('true' === api_get_setting('session.session_list_order')) { |
|
2691
|
|
|
$order = 'ORDER BY s.position'; |
|
2692
|
|
|
} |
|
2693
|
|
|
|
|
2694
|
|
|
// Order by dates according to settings |
|
2695
|
|
|
$orderBySettings = api_get_setting('session.my_courses_session_order', true); |
|
2696
|
|
|
if (!empty($orderBySettings) && isset($orderBySettings['field']) && isset($orderBySettings['order'])) { |
|
2697
|
|
|
$field = $orderBySettings['field']; |
|
2698
|
|
|
$orderSetting = $orderBySettings['order']; |
|
2699
|
|
|
switch ($field) { |
|
2700
|
|
|
case 'start_date': |
|
2701
|
|
|
$order = " ORDER BY s.accessStartDate $orderSetting"; |
|
2702
|
|
|
break; |
|
2703
|
|
|
case 'end_date': |
|
2704
|
|
|
$order = " ORDER BY s.accessEndDate $orderSetting "; |
|
2705
|
|
|
if ('asc' == $orderSetting) { |
|
2706
|
|
|
// Put null values at the end |
|
2707
|
|
|
// https://stackoverflow.com/questions/12652034/how-can-i-order-by-null-in-dql |
|
2708
|
|
|
$order = ' ORDER BY _isFieldNull asc, s.accessEndDate asc'; |
|
2709
|
|
|
} |
|
2710
|
|
|
break; |
|
2711
|
|
|
case 'name': |
|
2712
|
|
|
case 'title': |
|
2713
|
|
|
$order = " ORDER BY s.title $orderSetting "; |
|
2714
|
|
|
break; |
|
2715
|
|
|
} |
|
2716
|
|
|
} |
|
2717
|
|
|
|
|
2718
|
|
|
$dqlStudent .= $order; |
|
2719
|
|
|
$dqlCoach .= $order; |
|
2720
|
|
|
|
|
2721
|
|
|
$accessUrlId = api_get_current_access_url_id(); |
|
2722
|
|
|
$dqlStudent = Database::getManager() |
|
2723
|
|
|
->createQuery($dqlStudent) |
|
2724
|
|
|
->setParameters( |
|
2725
|
|
|
['user' => $user_id, 'url' => $accessUrlId] |
|
2726
|
|
|
) |
|
2727
|
|
|
; |
|
2728
|
|
|
$dqlCoach = Database::getManager() |
|
2729
|
|
|
->createQuery($dqlCoach) |
|
2730
|
|
|
->setParameters( |
|
2731
|
|
|
['user' => $user_id, 'url' => $accessUrlId] |
|
2732
|
|
|
) |
|
2733
|
|
|
; |
|
2734
|
|
|
|
|
2735
|
|
|
if ($getCount) { |
|
2736
|
|
|
return $dqlStudent->getSingleScalarResult() + $dqlCoach->getSingleScalarResult(); |
|
2737
|
|
|
} |
|
2738
|
|
|
|
|
2739
|
|
|
$sessionDataStudent = $dqlStudent->getResult(); |
|
2740
|
|
|
$sessionDataCoach = $dqlCoach->getResult(); |
|
2741
|
|
|
|
|
2742
|
|
|
$sessionData = []; |
|
2743
|
|
|
// First fill $sessionData with student sessions |
|
2744
|
|
|
if (!empty($sessionDataStudent)) { |
|
2745
|
|
|
foreach ($sessionDataStudent as $row) { |
|
2746
|
|
|
$sessionData[$row['id']] = $row; |
|
2747
|
|
|
} |
|
2748
|
|
|
} |
|
2749
|
|
|
// Overwrite session data of the user as a student with session data |
|
2750
|
|
|
// of the user as a coach. |
|
2751
|
|
|
// There shouldn't be such duplicate rows, but just in case... |
|
2752
|
|
|
if (!empty($sessionDataCoach)) { |
|
2753
|
|
|
foreach ($sessionDataCoach as $row) { |
|
2754
|
|
|
$sessionData[$row['id']] = $row; |
|
2755
|
|
|
} |
|
2756
|
|
|
} |
|
2757
|
|
|
|
|
2758
|
|
|
$collapsable = ('true' === api_get_setting('session.allow_user_session_collapsable')); |
|
2759
|
|
|
|
|
2760
|
|
|
|
|
2761
|
|
|
|
|
2762
|
|
|
$extraField = new ExtraFieldValue('session'); |
|
2763
|
|
|
$collapsableLink = api_get_path(WEB_PATH).'user_portal.php?action=collapse_session'; |
|
2764
|
|
|
|
|
2765
|
|
|
if (empty($sessionData)) { |
|
2766
|
|
|
return []; |
|
2767
|
|
|
} |
|
2768
|
|
|
$categories = []; |
|
2769
|
|
|
foreach ($sessionData as $row) { |
|
2770
|
|
|
$session_id = $row['id']; |
|
2771
|
|
|
$coachList = SessionManager::getCoachesBySession($session_id); |
|
2772
|
|
|
$categoryStart = $row['session_category_date_start'] ? $row['session_category_date_start']->format('Y-m-d') : ''; |
|
2773
|
|
|
$categoryEnd = $row['session_category_date_end'] ? $row['session_category_date_end']->format('Y-m-d') : ''; |
|
2774
|
|
|
$courseList = self::get_courses_list_by_session($user_id, $session_id); |
|
2775
|
|
|
$daysLeft = SessionManager::getDayLeftInSession($row, $user_id); |
|
2776
|
|
|
|
|
2777
|
|
|
// User portal filters: |
|
2778
|
|
|
if (false === $ignoreTimeLimit) { |
|
2779
|
|
|
if ($is_time_over) { |
|
2780
|
|
|
// History |
|
2781
|
|
|
if ($row['duration']) { |
|
2782
|
|
|
if ($daysLeft >= 0) { |
|
2783
|
|
|
continue; |
|
2784
|
|
|
} |
|
2785
|
|
|
} else { |
|
2786
|
|
|
if (empty($row['access_end_date'])) { |
|
2787
|
|
|
continue; |
|
2788
|
|
|
} else { |
|
2789
|
|
|
if ($row['access_end_date'] > $now) { |
|
2790
|
|
|
continue; |
|
2791
|
|
|
} |
|
2792
|
|
|
} |
|
2793
|
|
|
} |
|
2794
|
|
|
} else { |
|
2795
|
|
|
// Current user portal |
|
2796
|
|
|
$isGeneralCoach = api_get_session_entity($row['id'])->hasUserAsGeneralCoach(api_get_user_entity($user_id)); |
|
2797
|
|
|
$isCoachOfCourse = in_array($user_id, $coachList); |
|
2798
|
|
|
|
|
2799
|
|
|
if (api_is_platform_admin() || $isGeneralCoach || $isCoachOfCourse) { |
|
2800
|
|
|
// Teachers can access the session depending in the access_coach date |
|
2801
|
|
|
} else { |
|
2802
|
|
|
if ($row['duration']) { |
|
2803
|
|
|
if ($daysLeft <= 0) { |
|
2804
|
|
|
continue; |
|
2805
|
|
|
} |
|
2806
|
|
|
} else { |
|
2807
|
|
|
if (isset($row['access_end_date']) && |
|
2808
|
|
|
!empty($row['access_end_date']) |
|
2809
|
|
|
) { |
|
2810
|
|
|
if ($row['access_end_date'] <= $now) { |
|
2811
|
|
|
continue; |
|
2812
|
|
|
} |
|
2813
|
|
|
} |
|
2814
|
|
|
} |
|
2815
|
|
|
} |
|
2816
|
|
|
} |
|
2817
|
|
|
} |
|
2818
|
|
|
|
|
2819
|
|
|
$categories[$row['session_category_id']]['session_category'] = [ |
|
2820
|
|
|
'id' => $row['session_category_id'], |
|
2821
|
|
|
'name' => $row['session_category_title'], |
|
2822
|
|
|
'date_start' => $categoryStart, |
|
2823
|
|
|
'date_end' => $categoryEnd, |
|
2824
|
|
|
]; |
|
2825
|
|
|
|
|
2826
|
|
|
$visibility = api_get_session_visibility( |
|
|
|
|
|
|
2827
|
|
|
$session_id, |
|
2828
|
|
|
null, |
|
2829
|
|
|
$ignore_visibility_for_admins |
|
2830
|
|
|
); |
|
2831
|
|
|
|
|
2832
|
|
|
if (SESSION_VISIBLE != $visibility) { |
|
2833
|
|
|
// Course Coach session visibility. |
|
2834
|
|
|
$blockedCourseCount = 0; |
|
2835
|
|
|
$closedVisibilityList = [ |
|
2836
|
|
|
COURSE_VISIBILITY_CLOSED, |
|
2837
|
|
|
COURSE_VISIBILITY_HIDDEN, |
|
2838
|
|
|
]; |
|
2839
|
|
|
|
|
2840
|
|
|
foreach ($courseList as $course) { |
|
2841
|
|
|
// Checking session visibility |
|
2842
|
|
|
$sessionCourseVisibility = api_get_session_visibility( |
|
|
|
|
|
|
2843
|
|
|
$session_id, |
|
2844
|
|
|
$course['real_id'], |
|
2845
|
|
|
$ignore_visibility_for_admins |
|
2846
|
|
|
); |
|
2847
|
|
|
|
|
2848
|
|
|
$courseIsVisible = !in_array($course['visibility'], $closedVisibilityList); |
|
2849
|
|
|
if (false === $courseIsVisible || SESSION_INVISIBLE == $sessionCourseVisibility) { |
|
|
|
|
|
|
2850
|
|
|
$blockedCourseCount++; |
|
2851
|
|
|
} |
|
2852
|
|
|
} |
|
2853
|
|
|
|
|
2854
|
|
|
// If all courses are blocked then no show in the list. |
|
2855
|
|
|
if ($blockedCourseCount === count($courseList)) { |
|
2856
|
|
|
$visibility = SESSION_INVISIBLE; |
|
|
|
|
|
|
2857
|
|
|
} else { |
|
2858
|
|
|
$visibility = $sessionCourseVisibility; |
|
|
|
|
|
|
2859
|
|
|
} |
|
2860
|
|
|
} |
|
2861
|
|
|
|
|
2862
|
|
|
switch ($visibility) { |
|
2863
|
|
|
case SESSION_VISIBLE_READ_ONLY: |
|
2864
|
|
|
case SESSION_VISIBLE: |
|
2865
|
|
|
case SESSION_AVAILABLE: |
|
2866
|
|
|
break; |
|
2867
|
|
|
case SESSION_INVISIBLE: |
|
|
|
|
|
|
2868
|
|
|
if (false === $ignore_visibility_for_admins) { |
|
2869
|
|
|
continue 2; |
|
2870
|
|
|
} |
|
2871
|
|
|
} |
|
2872
|
|
|
|
|
2873
|
|
|
$collapsed = ''; |
|
2874
|
|
|
$collapsedAction = ''; |
|
2875
|
|
|
if ($collapsable) { |
|
2876
|
|
|
$collapsableData = SessionManager::getCollapsableData( |
|
2877
|
|
|
$user_id, |
|
2878
|
|
|
$session_id, |
|
2879
|
|
|
$extraField, |
|
2880
|
|
|
$collapsableLink |
|
2881
|
|
|
); |
|
2882
|
|
|
$collapsed = $collapsableData['collapsed']; |
|
2883
|
|
|
$collapsedAction = $collapsableData['collapsable_link']; |
|
2884
|
|
|
} |
|
2885
|
|
|
|
|
2886
|
|
|
$categories[$row['session_category_id']]['sessions'][] = [ |
|
2887
|
|
|
'session_name' => $row['title'], |
|
2888
|
|
|
'session_id' => $row['id'], |
|
2889
|
|
|
'access_start_date' => $row['access_start_date'] ? $row['access_start_date']->format('Y-m-d H:i:s') : null, |
|
2890
|
|
|
'access_end_date' => $row['access_end_date'] ? $row['access_end_date']->format('Y-m-d H:i:s') : null, |
|
2891
|
|
|
'coach_access_start_date' => $row['coach_access_start_date'] ? $row['coach_access_start_date']->format('Y-m-d H:i:s') : null, |
|
2892
|
|
|
'coach_access_end_date' => $row['coach_access_end_date'] ? $row['coach_access_end_date']->format('Y-m-d H:i:s') : null, |
|
2893
|
|
|
'courses' => $courseList, |
|
2894
|
|
|
'collapsed' => $collapsed, |
|
2895
|
|
|
'collapsable_link' => $collapsedAction, |
|
2896
|
|
|
'duration' => $row['duration'], |
|
2897
|
|
|
]; |
|
2898
|
|
|
} |
|
2899
|
|
|
|
|
2900
|
|
|
return $categories; |
|
2901
|
|
|
} |
|
2902
|
|
|
|
|
2903
|
|
|
/** |
|
2904
|
|
|
* Gives a list of [session_id-course_code] => [status] for the current user. |
|
2905
|
|
|
* |
|
2906
|
|
|
* @param int $user_id |
|
2907
|
|
|
* @param int $sessionLimit |
|
2908
|
|
|
* |
|
2909
|
|
|
* @return array list of statuses (session_id-course_code => status) |
|
2910
|
|
|
* |
|
2911
|
|
|
* @throws Exception |
|
2912
|
|
|
*/ |
|
2913
|
|
|
public static function get_personal_session_course_list($user_id, $sessionLimit = null) |
|
2914
|
|
|
{ |
|
2915
|
|
|
// Database Table Definitions |
|
2916
|
|
|
$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE); |
|
2917
|
|
|
$tbl_user = Database::get_main_table(TABLE_MAIN_USER); |
|
2918
|
|
|
$tbl_session = Database::get_main_table(TABLE_MAIN_SESSION); |
|
2919
|
|
|
$tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER); |
|
2920
|
|
|
$tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
|
2921
|
|
|
$tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
|
2922
|
|
|
|
|
2923
|
|
|
$user_id = (int) $user_id; |
|
2924
|
|
|
|
|
2925
|
|
|
if (empty($user_id)) { |
|
2926
|
|
|
return []; |
|
2927
|
|
|
} |
|
2928
|
|
|
|
|
2929
|
|
|
$sessionRepo = Container::getSessionRepository(); |
|
2930
|
|
|
|
|
2931
|
|
|
$user = api_get_user_entity($user_id); |
|
2932
|
|
|
$url = null; |
|
2933
|
|
|
$formattedUserName = Container::$container->get(NameConventionHelper::class)->getPersonName($user); |
|
2934
|
|
|
|
|
2935
|
|
|
// We filter the courses from the URL |
|
2936
|
|
|
$join_access_url = $where_access_url = ''; |
|
2937
|
|
|
if (api_get_multiple_access_url()) { |
|
2938
|
|
|
$access_url_id = api_get_current_access_url_id(); |
|
2939
|
|
|
if (-1 != $access_url_id) { |
|
2940
|
|
|
$url = api_get_url_entity($access_url_id); |
|
2941
|
|
|
$tbl_url_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
|
2942
|
|
|
$join_access_url = "LEFT JOIN $tbl_url_course url_rel_course ON url_rel_course.c_id = course.id"; |
|
2943
|
|
|
$where_access_url = " AND access_url_id = $access_url_id "; |
|
2944
|
|
|
} |
|
2945
|
|
|
} |
|
2946
|
|
|
|
|
2947
|
|
|
// Courses in which we subscribed out of any session |
|
2948
|
|
|
|
|
2949
|
|
|
$sql = "SELECT |
|
2950
|
|
|
course.code, |
|
2951
|
|
|
course_rel_user.status course_rel_status, |
|
2952
|
|
|
course_rel_user.sort sort, |
|
2953
|
|
|
course_rel_user.user_course_cat user_course_cat |
|
2954
|
|
|
FROM $tbl_course_user course_rel_user |
|
2955
|
|
|
LEFT JOIN $tbl_course course |
|
2956
|
|
|
ON course.id = course_rel_user.c_id |
|
2957
|
|
|
$join_access_url |
|
2958
|
|
|
WHERE |
|
2959
|
|
|
course_rel_user.user_id = '".$user_id."' AND |
|
2960
|
|
|
course_rel_user.relation_type <> ".COURSE_RELATION_TYPE_RRHH." |
|
2961
|
|
|
$where_access_url |
|
2962
|
|
|
ORDER BY course_rel_user.sort, course.title ASC"; |
|
2963
|
|
|
|
|
2964
|
|
|
$course_list_sql_result = Database::query($sql); |
|
2965
|
|
|
$personal_course_list = []; |
|
2966
|
|
|
if (Database::num_rows($course_list_sql_result) > 0) { |
|
2967
|
|
|
while ($result_row = Database::fetch_assoc($course_list_sql_result)) { |
|
2968
|
|
|
$course_info = api_get_course_info($result_row['code']); |
|
2969
|
|
|
$result_row['course_info'] = $course_info; |
|
2970
|
|
|
$personal_course_list[] = $result_row; |
|
2971
|
|
|
} |
|
2972
|
|
|
} |
|
2973
|
|
|
|
|
2974
|
|
|
$coachCourseConditions = ''; |
|
2975
|
|
|
// Getting sessions that are related to a coach in the session_rel_course_rel_user table |
|
2976
|
|
|
if (api_is_allowed_to_create_course()) { |
|
2977
|
|
|
$sessionListFromCourseCoach = []; |
|
2978
|
|
|
$sql = " SELECT DISTINCT session_id |
|
2979
|
|
|
FROM $tbl_session_course_user |
|
2980
|
|
|
WHERE user_id = $user_id AND status = ".SessionEntity::COURSE_COACH; |
|
2981
|
|
|
|
|
2982
|
|
|
$result = Database::query($sql); |
|
2983
|
|
|
if (Database::num_rows($result)) { |
|
2984
|
|
|
$result = Database::store_result($result); |
|
2985
|
|
|
foreach ($result as $session) { |
|
2986
|
|
|
$sessionListFromCourseCoach[] = $session['session_id']; |
|
2987
|
|
|
} |
|
2988
|
|
|
} |
|
2989
|
|
|
if (!empty($sessionListFromCourseCoach)) { |
|
2990
|
|
|
$condition = implode("','", $sessionListFromCourseCoach); |
|
2991
|
|
|
$coachCourseConditions = " OR ( s.id IN ('$condition'))"; |
|
2992
|
|
|
} |
|
2993
|
|
|
} |
|
2994
|
|
|
|
|
2995
|
|
|
// Get the list of sessions where the user is subscribed |
|
2996
|
|
|
// This is divided into two different queries |
|
2997
|
|
|
$sessions = []; |
|
2998
|
|
|
$sessionLimitRestriction = ''; |
|
2999
|
|
|
if (!empty($sessionLimit)) { |
|
3000
|
|
|
$sessionLimit = (int) $sessionLimit; |
|
3001
|
|
|
$sessionLimitRestriction = "LIMIT $sessionLimit"; |
|
3002
|
|
|
} |
|
3003
|
|
|
|
|
3004
|
|
|
$sql = "SELECT DISTINCT s.id, s.title, access_start_date, access_end_date |
|
3005
|
|
|
FROM $tbl_session_user su INNER JOIN $tbl_session s |
|
3006
|
|
|
ON (s.id = su.session_id) |
|
3007
|
|
|
WHERE ( |
|
3008
|
|
|
su.user_id = $user_id AND |
|
3009
|
|
|
su.relation_type = ".SessionEntity::STUDENT." |
|
3010
|
|
|
) |
|
3011
|
|
|
$coachCourseConditions |
|
3012
|
|
|
ORDER BY access_start_date, access_end_date, s.title |
|
3013
|
|
|
$sessionLimitRestriction |
|
3014
|
|
|
"; |
|
3015
|
|
|
|
|
3016
|
|
|
$result = Database::query($sql); |
|
3017
|
|
|
if (Database::num_rows($result) > 0) { |
|
3018
|
|
|
while ($row = Database::fetch_assoc($result)) { |
|
3019
|
|
|
$sessions[$row['id']] = $row; |
|
3020
|
|
|
} |
|
3021
|
|
|
} |
|
3022
|
|
|
|
|
3023
|
|
|
$sql = "SELECT DISTINCT |
|
3024
|
|
|
s.id, s.title, s.access_start_date, s.access_end_date |
|
3025
|
|
|
FROM $tbl_session s |
|
3026
|
|
|
INNER JOIN $tbl_session_user sru ON sru.session_id = s.id |
|
3027
|
|
|
WHERE ( |
|
3028
|
|
|
sru.user_id = $user_id AND sru.relation_type = ".SessionEntity::GENERAL_COACH." |
|
3029
|
|
|
) |
|
3030
|
|
|
$coachCourseConditions |
|
3031
|
|
|
ORDER BY s.access_start_date, s.access_end_date, s.title"; |
|
3032
|
|
|
|
|
3033
|
|
|
$result = Database::query($sql); |
|
3034
|
|
|
if (Database::num_rows($result) > 0) { |
|
3035
|
|
|
while ($row = Database::fetch_assoc($result)) { |
|
3036
|
|
|
if (empty($sessions[$row['id']])) { |
|
3037
|
|
|
$sessions[$row['id']] = $row; |
|
3038
|
|
|
} |
|
3039
|
|
|
} |
|
3040
|
|
|
} |
|
3041
|
|
|
|
|
3042
|
|
|
if (api_is_allowed_to_create_course()) { |
|
3043
|
|
|
foreach ($sessions as $enreg) { |
|
3044
|
|
|
$session_id = $enreg['id']; |
|
3045
|
|
|
$session_visibility = api_get_session_visibility($session_id); |
|
|
|
|
|
|
3046
|
|
|
$session = api_get_session_entity($session_id); |
|
3047
|
|
|
|
|
3048
|
|
|
if (SESSION_INVISIBLE == $session_visibility) { |
|
|
|
|
|
|
3049
|
|
|
continue; |
|
3050
|
|
|
} |
|
3051
|
|
|
|
|
3052
|
|
|
$coursesAsGeneralCoach = $sessionRepo->getSessionCoursesByStatusInUserSubscription( |
|
3053
|
|
|
$user, |
|
3054
|
|
|
$session, |
|
3055
|
|
|
SessionEntity::GENERAL_COACH, |
|
3056
|
|
|
$url |
|
3057
|
|
|
); |
|
3058
|
|
|
$coursesAsCourseCoach = $sessionRepo->getSessionCoursesByStatusInCourseSubscription( |
|
3059
|
|
|
$user, |
|
3060
|
|
|
$session, |
|
3061
|
|
|
SessionEntity::COURSE_COACH, |
|
3062
|
|
|
$url |
|
3063
|
|
|
); |
|
3064
|
|
|
|
|
3065
|
|
|
// This query is horribly slow when more than a few thousand |
|
3066
|
|
|
// users and just a few sessions to which they are subscribed |
|
3067
|
|
|
$coursesInSession = array_map( |
|
3068
|
|
|
function (SessionRelCourse $courseInSession) { |
|
3069
|
|
|
$course = $courseInSession->getCourse(); |
|
3070
|
|
|
|
|
3071
|
|
|
return [ |
|
3072
|
|
|
'code' => $course->getCode(), |
|
3073
|
|
|
'i' => $course->getTitle(), |
|
3074
|
|
|
'l' => $course->getCourseLanguage(), |
|
3075
|
|
|
'sort' => 1, |
|
3076
|
|
|
]; |
|
3077
|
|
|
}, |
|
3078
|
|
|
array_merge($coursesAsGeneralCoach, $coursesAsCourseCoach) |
|
3079
|
|
|
); |
|
3080
|
|
|
|
|
3081
|
|
|
foreach ($coursesInSession as $result_row) { |
|
3082
|
|
|
$result_row['t'] = $formattedUserName; |
|
3083
|
|
|
$result_row['email'] = $user->getEmail(); |
|
3084
|
|
|
$result_row['access_start_date'] = $session->getAccessStartDate()?->format('Y-m-d H:i:s'); |
|
3085
|
|
|
$result_row['access_end_date'] = $session->getAccessEndDate()?->format('Y-m-d H:i:s'); |
|
3086
|
|
|
$result_row['session_id'] = $session->getId(); |
|
3087
|
|
|
$result_row['session_name'] = $session->getTitle(); |
|
3088
|
|
|
$result_row['course_info'] = api_get_course_info($result_row['code']); |
|
3089
|
|
|
$key = $result_row['session_id'].' - '.$result_row['code']; |
|
3090
|
|
|
$personal_course_list[$key] = $result_row; |
|
3091
|
|
|
} |
|
3092
|
|
|
} |
|
3093
|
|
|
} |
|
3094
|
|
|
|
|
3095
|
|
|
foreach ($sessions as $enreg) { |
|
3096
|
|
|
$session_id = $enreg['id']; |
|
3097
|
|
|
$session_visibility = api_get_session_visibility($session_id); |
|
|
|
|
|
|
3098
|
|
|
if (SESSION_INVISIBLE == $session_visibility) { |
|
|
|
|
|
|
3099
|
|
|
continue; |
|
3100
|
|
|
} |
|
3101
|
|
|
|
|
3102
|
|
|
/* This query is very similar to the above query, |
|
3103
|
|
|
but it will check the session_rel_course_user table if there are courses registered to our user or not */ |
|
3104
|
|
|
$sql = "SELECT DISTINCT |
|
3105
|
|
|
course.code code, |
|
3106
|
|
|
course.title i, CONCAT(user.lastname,' ',user.firstname) t, |
|
3107
|
|
|
email, |
|
3108
|
|
|
course.course_language l, |
|
3109
|
|
|
1 sort, |
|
3110
|
|
|
access_start_date, |
|
3111
|
|
|
access_end_date, |
|
3112
|
|
|
session.id as session_id, |
|
3113
|
|
|
session.title as session_name, |
|
3114
|
|
|
IF((session_course_user.user_id = 3 AND session_course_user.status = ".SessionEntity::COURSE_COACH."),'2', '5') |
|
3115
|
|
|
FROM $tbl_session_course_user as session_course_user |
|
3116
|
|
|
INNER JOIN $tbl_course AS course |
|
3117
|
|
|
ON course.id = session_course_user.c_id AND session_course_user.session_id = $session_id |
|
3118
|
|
|
INNER JOIN $tbl_session as session |
|
3119
|
|
|
ON session_course_user.session_id = session.id |
|
3120
|
|
|
LEFT JOIN $tbl_user as user ON user.id = session_course_user.user_id |
|
3121
|
|
|
WHERE session_course_user.user_id = $user_id |
|
3122
|
|
|
ORDER BY i"; |
|
3123
|
|
|
|
|
3124
|
|
|
$course_list_sql_result = Database::query($sql); |
|
3125
|
|
|
while ($result_row = Database::fetch_assoc($course_list_sql_result)) { |
|
3126
|
|
|
$result_row['course_info'] = api_get_course_info($result_row['code']); |
|
3127
|
|
|
$key = $result_row['session_id'].' - '.$result_row['code']; |
|
3128
|
|
|
if (!isset($personal_course_list[$key])) { |
|
3129
|
|
|
$personal_course_list[$key] = $result_row; |
|
3130
|
|
|
} |
|
3131
|
|
|
} |
|
3132
|
|
|
} |
|
3133
|
|
|
|
|
3134
|
|
|
return $personal_course_list; |
|
3135
|
|
|
} |
|
3136
|
|
|
|
|
3137
|
|
|
/** |
|
3138
|
|
|
* Gives a list of courses for the given user in the given session. |
|
3139
|
|
|
* |
|
3140
|
|
|
* @param int $user_id |
|
3141
|
|
|
* @param int $session_id |
|
3142
|
|
|
* |
|
3143
|
|
|
* @return array list of statuses (session_id-course_code => status) |
|
3144
|
|
|
*/ |
|
3145
|
|
|
public static function get_courses_list_by_session($user_id, $session_id) |
|
3146
|
|
|
{ |
|
3147
|
|
|
// Database Table Definitions |
|
3148
|
|
|
$tableCourse = Database::get_main_table(TABLE_MAIN_COURSE); |
|
3149
|
|
|
$tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
|
3150
|
|
|
$tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE); |
|
3151
|
|
|
|
|
3152
|
|
|
$user_id = (int) $user_id; |
|
3153
|
|
|
$session_id = (int) $session_id; |
|
3154
|
|
|
|
|
3155
|
|
|
$sessionRepo = Container::getSessionRepository(); |
|
3156
|
|
|
|
|
3157
|
|
|
$user = api_get_user_entity($user_id); |
|
3158
|
|
|
$session = api_get_session_entity($session_id); |
|
3159
|
|
|
$url = null; |
|
3160
|
|
|
|
|
3161
|
|
|
// We filter the courses from the URL |
|
3162
|
|
|
$join_access_url = $where_access_url = ''; |
|
3163
|
|
|
if (api_get_multiple_access_url()) { |
|
3164
|
|
|
$urlId = api_get_current_access_url_id(); |
|
3165
|
|
|
if (-1 != $urlId) { |
|
3166
|
|
|
$url = api_get_url_entity($urlId); |
|
3167
|
|
|
$tbl_url_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION); |
|
3168
|
|
|
$join_access_url = " , $tbl_url_session url_rel_session "; |
|
3169
|
|
|
$where_access_url = " AND access_url_id = $urlId AND url_rel_session.session_id = $session_id "; |
|
3170
|
|
|
} |
|
3171
|
|
|
} |
|
3172
|
|
|
|
|
3173
|
|
|
/* This query is very similar to the query below, but it will check the |
|
3174
|
|
|
session_rel_course_user table if there are courses registered |
|
3175
|
|
|
to our user or not */ |
|
3176
|
|
|
$sql = "SELECT DISTINCT |
|
3177
|
|
|
c.title, |
|
3178
|
|
|
c.visibility, |
|
3179
|
|
|
c.id as real_id, |
|
3180
|
|
|
c.code as course_code, |
|
3181
|
|
|
sc.position, |
|
3182
|
|
|
c.unsubscribe |
|
3183
|
|
|
FROM $tbl_session_course_user as scu |
|
3184
|
|
|
INNER JOIN $tbl_session_course sc |
|
3185
|
|
|
ON (scu.session_id = sc.session_id AND scu.c_id = sc.c_id) |
|
3186
|
|
|
INNER JOIN $tableCourse as c |
|
3187
|
|
|
ON (scu.c_id = c.id) |
|
3188
|
|
|
$join_access_url |
|
3189
|
|
|
WHERE |
|
3190
|
|
|
scu.user_id = $user_id AND |
|
3191
|
|
|
scu.session_id = $session_id |
|
3192
|
|
|
$where_access_url |
|
3193
|
|
|
ORDER BY sc.position ASC"; |
|
3194
|
|
|
|
|
3195
|
|
|
$myCourseList = []; |
|
3196
|
|
|
$courses = []; |
|
3197
|
|
|
$result = Database::query($sql); |
|
3198
|
|
|
if (Database::num_rows($result) > 0) { |
|
3199
|
|
|
while ($result_row = Database::fetch_assoc($result)) { |
|
3200
|
|
|
$result_row['status'] = 5; |
|
3201
|
|
|
if (!in_array($result_row['real_id'], $courses)) { |
|
3202
|
|
|
$position = $result_row['position']; |
|
3203
|
|
|
if (!isset($myCourseList[$position])) { |
|
3204
|
|
|
$myCourseList[$position] = $result_row; |
|
3205
|
|
|
} else { |
|
3206
|
|
|
$myCourseList[] = $result_row; |
|
3207
|
|
|
} |
|
3208
|
|
|
$courses[] = $result_row['real_id']; |
|
3209
|
|
|
} |
|
3210
|
|
|
} |
|
3211
|
|
|
} |
|
3212
|
|
|
|
|
3213
|
|
|
if (api_is_allowed_to_create_course()) { |
|
3214
|
|
|
$coursesAsGeneralCoach = $sessionRepo->getSessionCoursesByStatusInUserSubscription( |
|
3215
|
|
|
$user, |
|
3216
|
|
|
$session, |
|
3217
|
|
|
SessionEntity::GENERAL_COACH, |
|
3218
|
|
|
$url |
|
3219
|
|
|
); |
|
3220
|
|
|
$coursesAsCourseCoach = $sessionRepo->getSessionCoursesByStatusInCourseSubscription( |
|
3221
|
|
|
$user, |
|
3222
|
|
|
$session, |
|
3223
|
|
|
SessionEntity::COURSE_COACH, |
|
3224
|
|
|
$url |
|
3225
|
|
|
); |
|
3226
|
|
|
|
|
3227
|
|
|
$coursesInSession = array_map( |
|
3228
|
|
|
function (SessionRelCourse $courseInSession) { |
|
3229
|
|
|
$course = $courseInSession->getCourse(); |
|
3230
|
|
|
|
|
3231
|
|
|
return [ |
|
3232
|
|
|
'title' => $course->getTitle(), |
|
3233
|
|
|
'visibility' => $course->getVisibility(), |
|
3234
|
|
|
'real_id' => $course->getId(), |
|
3235
|
|
|
'course_code' => $course->getCode(), |
|
3236
|
|
|
'position' => $courseInSession->getPosition(), |
|
3237
|
|
|
'unsubscribe' => $course->getUnsubscribe(), |
|
3238
|
|
|
]; |
|
3239
|
|
|
}, |
|
3240
|
|
|
array_merge($coursesAsGeneralCoach, $coursesAsCourseCoach) |
|
3241
|
|
|
); |
|
3242
|
|
|
|
|
3243
|
|
|
foreach ($coursesInSession as $result_row) { |
|
3244
|
|
|
$result_row['status'] = 2; |
|
3245
|
|
|
if (!in_array($result_row['real_id'], $courses)) { |
|
3246
|
|
|
$position = $result_row['position']; |
|
3247
|
|
|
if (!isset($myCourseList[$position])) { |
|
3248
|
|
|
$myCourseList[$position] = $result_row; |
|
3249
|
|
|
} else { |
|
3250
|
|
|
$myCourseList[] = $result_row; |
|
3251
|
|
|
} |
|
3252
|
|
|
$courses[] = $result_row['real_id']; |
|
3253
|
|
|
} |
|
3254
|
|
|
} |
|
3255
|
|
|
} |
|
3256
|
|
|
|
|
3257
|
|
|
if (api_is_drh()) { |
|
3258
|
|
|
$sessionList = SessionManager::get_sessions_followed_by_drh($user_id); |
|
3259
|
|
|
$sessionList = array_keys($sessionList); |
|
3260
|
|
|
if (in_array($session_id, $sessionList)) { |
|
3261
|
|
|
$courseList = SessionManager::get_course_list_by_session_id($session_id); |
|
3262
|
|
|
if (!empty($courseList)) { |
|
3263
|
|
|
foreach ($courseList as $course) { |
|
3264
|
|
|
if (!in_array($course['id'], $courses)) { |
|
3265
|
|
|
$position = $course['position']; |
|
3266
|
|
|
if (!isset($myCourseList[$position])) { |
|
3267
|
|
|
$myCourseList[$position] = $course; |
|
3268
|
|
|
} else { |
|
3269
|
|
|
$myCourseList[] = $course; |
|
3270
|
|
|
} |
|
3271
|
|
|
} |
|
3272
|
|
|
} |
|
3273
|
|
|
} |
|
3274
|
|
|
} |
|
3275
|
|
|
} else { |
|
3276
|
|
|
//check if user is general coach for this session |
|
3277
|
|
|
if ($session && $session->hasUserAsGeneralCoach($user)) { |
|
3278
|
|
|
$courseList = SessionManager::get_course_list_by_session_id($session_id); |
|
3279
|
|
|
if (!empty($courseList)) { |
|
3280
|
|
|
foreach ($courseList as $course) { |
|
3281
|
|
|
if (!in_array($course['id'], $courses)) { |
|
3282
|
|
|
$position = $course['position']; |
|
3283
|
|
|
if (!isset($myCourseList[$position])) { |
|
3284
|
|
|
$myCourseList[$position] = $course; |
|
3285
|
|
|
} else { |
|
3286
|
|
|
$myCourseList[] = $course; |
|
3287
|
|
|
} |
|
3288
|
|
|
} |
|
3289
|
|
|
} |
|
3290
|
|
|
} |
|
3291
|
|
|
} |
|
3292
|
|
|
} |
|
3293
|
|
|
|
|
3294
|
|
|
if (!empty($myCourseList)) { |
|
3295
|
|
|
ksort($myCourseList); |
|
3296
|
|
|
$checkPosition = array_filter(array_column($myCourseList, 'position')); |
|
3297
|
|
|
if (empty($checkPosition)) { |
|
3298
|
|
|
// The session course list doesn't have any position, |
|
3299
|
|
|
// then order the course list by course code |
|
3300
|
|
|
$list = array_column($myCourseList, 'course_code'); |
|
3301
|
|
|
array_multisort($myCourseList, SORT_ASC, $list); |
|
|
|
|
|
|
3302
|
|
|
} |
|
3303
|
|
|
} |
|
3304
|
|
|
|
|
3305
|
|
|
return $myCourseList; |
|
3306
|
|
|
} |
|
3307
|
|
|
|
|
3308
|
|
|
/** |
|
3309
|
|
|
* Get user id from a username. |
|
3310
|
|
|
* |
|
3311
|
|
|
* @param string $username |
|
3312
|
|
|
* |
|
3313
|
|
|
* @return int User ID (or false if not found) |
|
3314
|
|
|
*/ |
|
3315
|
|
|
public static function get_user_id_from_username($username) |
|
3316
|
|
|
{ |
|
3317
|
|
|
if (empty($username)) { |
|
3318
|
|
|
return false; |
|
3319
|
|
|
} |
|
3320
|
|
|
$username = trim($username); |
|
3321
|
|
|
$username = Database::escape_string($username); |
|
3322
|
|
|
$t_user = Database::get_main_table(TABLE_MAIN_USER); |
|
3323
|
|
|
$sql = "SELECT id FROM $t_user WHERE username = '$username'"; |
|
3324
|
|
|
$res = Database::query($sql); |
|
3325
|
|
|
|
|
3326
|
|
|
if (false === $res) { |
|
3327
|
|
|
return false; |
|
3328
|
|
|
} |
|
3329
|
|
|
if (1 !== Database::num_rows($res)) { |
|
3330
|
|
|
return false; |
|
3331
|
|
|
} |
|
3332
|
|
|
$row = Database::fetch_array($res); |
|
3333
|
|
|
|
|
3334
|
|
|
return $row['id']; |
|
3335
|
|
|
} |
|
3336
|
|
|
|
|
3337
|
|
|
/** |
|
3338
|
|
|
* Get the users files upload from his share_folder. |
|
3339
|
|
|
* |
|
3340
|
|
|
* @param string $user_id User ID |
|
3341
|
|
|
* @param string $course course directory |
|
3342
|
|
|
* @param string $resourceType resource type: images, all |
|
3343
|
|
|
* |
|
3344
|
|
|
* @return string |
|
3345
|
|
|
*/ |
|
3346
|
|
|
/*public static function get_user_upload_files_by_course( |
|
3347
|
|
|
$user_id, |
|
3348
|
|
|
$course, |
|
3349
|
|
|
$resourceType = 'all' |
|
3350
|
|
|
) { |
|
3351
|
|
|
$return = ''; |
|
3352
|
|
|
$user_id = (int) $user_id; |
|
3353
|
|
|
|
|
3354
|
|
|
if (!empty($user_id) && !empty($course)) { |
|
3355
|
|
|
$path = api_get_path(SYS_COURSE_PATH).$course.'/document/shared_folder/sf_user_'.$user_id.'/'; |
|
3356
|
|
|
$web_path = api_get_path(WEB_COURSE_PATH).$course.'/document/shared_folder/sf_user_'.$user_id.'/'; |
|
3357
|
|
|
$file_list = []; |
|
3358
|
|
|
|
|
3359
|
|
|
if (is_dir($path)) { |
|
3360
|
|
|
$handle = opendir($path); |
|
3361
|
|
|
while ($file = readdir($handle)) { |
|
3362
|
|
|
if ('.' == $file || '..' == $file || '.htaccess' == $file || is_dir($path.$file)) { |
|
3363
|
|
|
continue; // skip current/parent directory and .htaccess |
|
3364
|
|
|
} |
|
3365
|
|
|
$file_list[] = $file; |
|
3366
|
|
|
} |
|
3367
|
|
|
if (count($file_list) > 0) { |
|
3368
|
|
|
$return = "<h4>$course</h4>"; |
|
3369
|
|
|
$return .= '<ul class="thumbnails">'; |
|
3370
|
|
|
} |
|
3371
|
|
|
$extensionList = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tif']; |
|
3372
|
|
|
foreach ($file_list as $file) { |
|
3373
|
|
|
if ('all' == $resourceType) { |
|
3374
|
|
|
$return .= '<li> |
|
3375
|
|
|
<a href="'.$web_path.urlencode($file).'" target="_blank">'.htmlentities($file).'</a></li>'; |
|
3376
|
|
|
} elseif ('images' == $resourceType) { |
|
3377
|
|
|
//get extension |
|
3378
|
|
|
$ext = explode('.', $file); |
|
3379
|
|
|
if (isset($ext[1]) && in_array($ext[1], $extensionList)) { |
|
3380
|
|
|
$return .= '<li class="span2"> |
|
3381
|
|
|
<a class="thumbnail" href="'.$web_path.urlencode($file).'" target="_blank"> |
|
3382
|
|
|
<img src="'.$web_path.urlencode($file).'" > |
|
3383
|
|
|
</a> |
|
3384
|
|
|
</li>'; |
|
3385
|
|
|
} |
|
3386
|
|
|
} |
|
3387
|
|
|
} |
|
3388
|
|
|
if (count($file_list) > 0) { |
|
3389
|
|
|
$return .= '</ul>'; |
|
3390
|
|
|
} |
|
3391
|
|
|
} |
|
3392
|
|
|
} |
|
3393
|
|
|
|
|
3394
|
|
|
return $return; |
|
3395
|
|
|
}*/ |
|
3396
|
|
|
|
|
3397
|
|
|
/** |
|
3398
|
|
|
* Gets the API key (or keys) and return them into an array. |
|
3399
|
|
|
* |
|
3400
|
|
|
* @param int Optional user id (defaults to the result of api_get_user_id()) |
|
3401
|
|
|
* @param string $api_service |
|
3402
|
|
|
* |
|
3403
|
|
|
* @return mixed Non-indexed array containing the list of API keys for this user, or FALSE on error |
|
3404
|
|
|
*/ |
|
3405
|
|
|
public static function get_api_keys($user_id = null, $api_service = 'default') |
|
3406
|
|
|
{ |
|
3407
|
|
|
if ($user_id != strval(intval($user_id))) { |
|
3408
|
|
|
return false; |
|
3409
|
|
|
} |
|
3410
|
|
|
if (empty($user_id)) { |
|
3411
|
|
|
$user_id = api_get_user_id(); |
|
3412
|
|
|
} |
|
3413
|
|
|
if (false === $user_id) { |
|
3414
|
|
|
return false; |
|
3415
|
|
|
} |
|
3416
|
|
|
$service_name = Database::escape_string($api_service); |
|
3417
|
|
|
if (false === is_string($service_name)) { |
|
3418
|
|
|
return false; |
|
3419
|
|
|
} |
|
3420
|
|
|
$t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY); |
|
3421
|
|
|
$sql = "SELECT * FROM $t_api WHERE user_id = $user_id AND api_service='$api_service';"; |
|
3422
|
|
|
$res = Database::query($sql); |
|
3423
|
|
|
if (false === $res) { |
|
3424
|
|
|
return false; |
|
3425
|
|
|
} //error during query |
|
3426
|
|
|
$num = Database::num_rows($res); |
|
3427
|
|
|
if (0 == $num) { |
|
3428
|
|
|
return false; |
|
3429
|
|
|
} |
|
3430
|
|
|
$list = []; |
|
3431
|
|
|
while ($row = Database::fetch_array($res)) { |
|
3432
|
|
|
$list[$row['id']] = $row['api_key']; |
|
3433
|
|
|
} |
|
3434
|
|
|
|
|
3435
|
|
|
return $list; |
|
3436
|
|
|
} |
|
3437
|
|
|
|
|
3438
|
|
|
/** |
|
3439
|
|
|
* Adds a new API key to the users' account. |
|
3440
|
|
|
* |
|
3441
|
|
|
* @param int Optional user ID (defaults to the results of api_get_user_id()) |
|
3442
|
|
|
* @param string $api_service |
|
3443
|
|
|
* |
|
3444
|
|
|
* @return bool True on success, false on failure |
|
3445
|
|
|
*/ |
|
3446
|
|
|
public static function add_api_key($user_id = null, $api_service = 'default') |
|
3447
|
|
|
{ |
|
3448
|
|
|
if ($user_id != strval(intval($user_id))) { |
|
3449
|
|
|
return false; |
|
3450
|
|
|
} |
|
3451
|
|
|
if (empty($user_id)) { |
|
3452
|
|
|
$user_id = api_get_user_id(); |
|
3453
|
|
|
} |
|
3454
|
|
|
if (false === $user_id) { |
|
3455
|
|
|
return false; |
|
3456
|
|
|
} |
|
3457
|
|
|
$service_name = Database::escape_string($api_service); |
|
3458
|
|
|
if (false === is_string($service_name)) { |
|
3459
|
|
|
return false; |
|
3460
|
|
|
} |
|
3461
|
|
|
$t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY); |
|
3462
|
|
|
$md5 = md5((time() + ($user_id * 5)) - rand(10000, 10000)); //generate some kind of random key |
|
3463
|
|
|
$sql = "INSERT INTO $t_api (user_id, api_key,api_service) VALUES ($user_id,'$md5','$service_name')"; |
|
3464
|
|
|
$res = Database::query($sql); |
|
3465
|
|
|
if (false === $res) { |
|
3466
|
|
|
return false; |
|
3467
|
|
|
} //error during query |
|
3468
|
|
|
$num = Database::insert_id(); |
|
3469
|
|
|
|
|
3470
|
|
|
return 0 == $num ? false : $num; |
|
|
|
|
|
|
3471
|
|
|
} |
|
3472
|
|
|
|
|
3473
|
|
|
/** |
|
3474
|
|
|
* Deletes an API key from the user's account. |
|
3475
|
|
|
* |
|
3476
|
|
|
* @param int API key's internal ID |
|
3477
|
|
|
* |
|
3478
|
|
|
* @return bool True on success, false on failure |
|
3479
|
|
|
*/ |
|
3480
|
|
|
public static function delete_api_key($key_id) |
|
3481
|
|
|
{ |
|
3482
|
|
|
if ($key_id != strval(intval($key_id))) { |
|
3483
|
|
|
return false; |
|
3484
|
|
|
} |
|
3485
|
|
|
if (false === $key_id) { |
|
3486
|
|
|
return false; |
|
3487
|
|
|
} |
|
3488
|
|
|
$t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY); |
|
3489
|
|
|
$sql = "SELECT * FROM $t_api WHERE id = ".$key_id; |
|
3490
|
|
|
$res = Database::query($sql); |
|
3491
|
|
|
if (false === $res) { |
|
3492
|
|
|
return false; |
|
3493
|
|
|
} //error during query |
|
3494
|
|
|
$num = Database::num_rows($res); |
|
3495
|
|
|
if (1 !== $num) { |
|
3496
|
|
|
return false; |
|
3497
|
|
|
} |
|
3498
|
|
|
$sql = "DELETE FROM $t_api WHERE id = ".$key_id; |
|
3499
|
|
|
$res = Database::query($sql); |
|
3500
|
|
|
if (false === $res) { |
|
3501
|
|
|
return false; |
|
3502
|
|
|
} //error during query |
|
3503
|
|
|
|
|
3504
|
|
|
return true; |
|
3505
|
|
|
} |
|
3506
|
|
|
|
|
3507
|
|
|
/** |
|
3508
|
|
|
* Regenerate an API key from the user's account. |
|
3509
|
|
|
* |
|
3510
|
|
|
* @param int user ID (defaults to the results of api_get_user_id()) |
|
3511
|
|
|
* @param string API key's internal ID |
|
3512
|
|
|
* |
|
3513
|
|
|
* @return int num |
|
3514
|
|
|
*/ |
|
3515
|
|
|
public static function update_api_key($user_id, $api_service) |
|
3516
|
|
|
{ |
|
3517
|
|
|
if ($user_id != strval(intval($user_id))) { |
|
3518
|
|
|
return false; |
|
3519
|
|
|
} |
|
3520
|
|
|
if (false === $user_id) { |
|
3521
|
|
|
return false; |
|
3522
|
|
|
} |
|
3523
|
|
|
$service_name = Database::escape_string($api_service); |
|
3524
|
|
|
if (false === is_string($service_name)) { |
|
3525
|
|
|
return false; |
|
3526
|
|
|
} |
|
3527
|
|
|
$t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY); |
|
3528
|
|
|
$sql = "SELECT id FROM $t_api |
|
3529
|
|
|
WHERE user_id=".$user_id." AND api_service='".$api_service."'"; |
|
3530
|
|
|
$res = Database::query($sql); |
|
3531
|
|
|
$num = Database::num_rows($res); |
|
3532
|
|
|
if (1 == $num) { |
|
3533
|
|
|
$id_key = Database::fetch_assoc($res); |
|
3534
|
|
|
self::delete_api_key($id_key['id']); |
|
3535
|
|
|
$num = self::add_api_key($user_id, $api_service); |
|
3536
|
|
|
} elseif (0 == $num) { |
|
3537
|
|
|
$num = self::add_api_key($user_id, $api_service); |
|
3538
|
|
|
} |
|
3539
|
|
|
|
|
3540
|
|
|
return $num; |
|
|
|
|
|
|
3541
|
|
|
} |
|
3542
|
|
|
|
|
3543
|
|
|
/** |
|
3544
|
|
|
* @param int user ID (defaults to the results of api_get_user_id()) |
|
3545
|
|
|
* @param string API key's internal ID |
|
3546
|
|
|
* |
|
3547
|
|
|
* @return int row ID, or return false if not found |
|
3548
|
|
|
*/ |
|
3549
|
|
|
public static function get_api_key_id($user_id, $api_service) |
|
3550
|
|
|
{ |
|
3551
|
|
|
if ($user_id != strval(intval($user_id))) { |
|
3552
|
|
|
return false; |
|
3553
|
|
|
} |
|
3554
|
|
|
if (false === $user_id) { |
|
3555
|
|
|
return false; |
|
3556
|
|
|
} |
|
3557
|
|
|
if (empty($api_service)) { |
|
3558
|
|
|
return false; |
|
3559
|
|
|
} |
|
3560
|
|
|
$t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY); |
|
3561
|
|
|
$api_service = Database::escape_string($api_service); |
|
3562
|
|
|
$sql = "SELECT id FROM $t_api |
|
3563
|
|
|
WHERE user_id=".$user_id." AND api_service='".$api_service."'"; |
|
3564
|
|
|
$res = Database::query($sql); |
|
3565
|
|
|
if (Database::num_rows($res) < 1) { |
|
3566
|
|
|
return false; |
|
3567
|
|
|
} |
|
3568
|
|
|
$row = Database::fetch_assoc($res); |
|
3569
|
|
|
|
|
3570
|
|
|
return $row['id']; |
|
3571
|
|
|
} |
|
3572
|
|
|
|
|
3573
|
|
|
/** |
|
3574
|
|
|
* Checks if a user_id is platform admin. |
|
3575
|
|
|
* |
|
3576
|
|
|
* @param int user ID |
|
3577
|
|
|
* |
|
3578
|
|
|
* @return bool True if is admin, false otherwise |
|
3579
|
|
|
* |
|
3580
|
|
|
* @see main_api.lib.php::api_is_platform_admin() for a context-based check |
|
3581
|
|
|
*/ |
|
3582
|
|
|
public static function is_admin($user_id) |
|
3583
|
|
|
{ |
|
3584
|
|
|
$user_id = (int) $user_id; |
|
3585
|
|
|
if (empty($user_id)) { |
|
3586
|
|
|
return false; |
|
3587
|
|
|
} |
|
3588
|
|
|
$admin_table = Database::get_main_table(TABLE_MAIN_ADMIN); |
|
3589
|
|
|
$sql = "SELECT * FROM $admin_table WHERE user_id = $user_id"; |
|
3590
|
|
|
$res = Database::query($sql); |
|
3591
|
|
|
|
|
3592
|
|
|
return 1 === Database::num_rows($res); |
|
3593
|
|
|
} |
|
3594
|
|
|
|
|
3595
|
|
|
/** |
|
3596
|
|
|
* Get the total count of users. |
|
3597
|
|
|
* |
|
3598
|
|
|
* @param ?int $status Status of users to be counted |
|
3599
|
|
|
* @param ?int $access_url_id Access URL ID (optional) |
|
3600
|
|
|
* @param ?int $active |
|
3601
|
|
|
* |
|
3602
|
|
|
* @return mixed Number of users or false on error |
|
3603
|
|
|
* @throws \Doctrine\DBAL\Exception |
|
3604
|
|
|
*/ |
|
3605
|
|
|
public static function get_number_of_users( |
|
3606
|
|
|
?int $status = 0, |
|
3607
|
|
|
?int $access_url_id = 1, |
|
3608
|
|
|
?int $active = null, |
|
3609
|
|
|
?string $dateFrom = null, |
|
3610
|
|
|
?string $dateUntil = null |
|
3611
|
|
|
): mixed { |
|
3612
|
|
|
$tableUser = Database::get_main_table(TABLE_MAIN_USER); |
|
3613
|
|
|
$tableAccessUrlRelUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
|
3614
|
|
|
|
|
3615
|
|
|
if (api_is_multiple_url_enabled()) { |
|
|
|
|
|
|
3616
|
|
|
$sql = "SELECT count(u.id) |
|
3617
|
|
|
FROM $tableUser u |
|
3618
|
|
|
INNER JOIN $tableAccessUrlRelUser url_user |
|
3619
|
|
|
ON (u.id = url_user.user_id) |
|
3620
|
|
|
WHERE url_user.access_url_id = $access_url_id |
|
3621
|
|
|
"; |
|
3622
|
|
|
} else { |
|
3623
|
|
|
$sql = "SELECT count(u.id) |
|
3624
|
|
|
FROM $tableUser u |
|
3625
|
|
|
WHERE 1 = 1 "; |
|
3626
|
|
|
} |
|
3627
|
|
|
|
|
3628
|
|
|
$status = (int) $status; |
|
3629
|
|
|
if (!empty($status) && $status > 0) { |
|
3630
|
|
|
$sql .= " AND u.status = $status "; |
|
3631
|
|
|
} |
|
3632
|
|
|
|
|
3633
|
|
|
if (isset($active)) { |
|
3634
|
|
|
$active = (int) $active; |
|
3635
|
|
|
$sql .= " AND u.active = $active "; |
|
3636
|
|
|
} |
|
3637
|
|
|
|
|
3638
|
|
|
if (!empty($dateFrom)) { |
|
3639
|
|
|
$dateFrom = api_get_utc_datetime("$dateFrom 00:00:00"); |
|
3640
|
|
|
$sql .= " AND u.created_at >= '$dateFrom' "; |
|
3641
|
|
|
} |
|
3642
|
|
|
if (!empty($dateUntil)) { |
|
3643
|
|
|
$dateUntil = api_get_utc_datetime("$dateUntil 23:59:59"); |
|
3644
|
|
|
$sql .= " AND u.created_at <= '$dateUntil' "; |
|
3645
|
|
|
} |
|
3646
|
|
|
|
|
3647
|
|
|
$res = Database::query($sql); |
|
3648
|
|
|
if (1 === Database::num_rows($res)) { |
|
3649
|
|
|
return (int) Database::result($res, 0, 0); |
|
3650
|
|
|
} |
|
3651
|
|
|
|
|
3652
|
|
|
return false; |
|
3653
|
|
|
} |
|
3654
|
|
|
|
|
3655
|
|
|
/** |
|
3656
|
|
|
* Gets the tags of a specific field_id |
|
3657
|
|
|
* USER TAGS. |
|
3658
|
|
|
* |
|
3659
|
|
|
* Instructions to create a new user tag by Julio Montoya <[email protected]> |
|
3660
|
|
|
* |
|
3661
|
|
|
* 1. Create a new extra field in main/admin/user_fields.php with the "TAG" field type make it available and visible. |
|
3662
|
|
|
* Called it "books" for example. |
|
3663
|
|
|
* 2. Go to profile main/auth/profile.php There you will see a special input (facebook style) that will show suggestions of tags. |
|
3664
|
|
|
* 3. All the tags are registered in the user_tag table and the relationship between user and tags is in the user_rel_tag table |
|
3665
|
|
|
* 4. Tags are independent this means that tags can't be shared between tags + book + hobbies. |
|
3666
|
|
|
* 5. Test and enjoy. |
|
3667
|
|
|
* |
|
3668
|
|
|
* @param string $tag |
|
3669
|
|
|
* @param int $field_id field_id |
|
3670
|
|
|
* @param string $return_format how we are going to result value in array or in a string (json) |
|
3671
|
|
|
* @param $limit |
|
3672
|
|
|
* |
|
3673
|
|
|
* @return mixed |
|
3674
|
|
|
*/ |
|
3675
|
|
|
public static function get_tags($tag, $field_id, $return_format = 'json', $limit = 10) |
|
3676
|
|
|
{ |
|
3677
|
|
|
// database table definition |
|
3678
|
|
|
$table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
|
3679
|
|
|
$field_id = (int) $field_id; |
|
3680
|
|
|
$limit = (int) $limit; |
|
3681
|
|
|
$tag = trim(Database::escape_string($tag)); |
|
3682
|
|
|
|
|
3683
|
|
|
// all the information of the field |
|
3684
|
|
|
$sql = "SELECT DISTINCT id, tag from $table_user_tag |
|
3685
|
|
|
WHERE field_id = $field_id AND tag LIKE '$tag%' ORDER BY tag LIMIT $limit"; |
|
3686
|
|
|
$result = Database::query($sql); |
|
3687
|
|
|
$return = []; |
|
3688
|
|
|
if (Database::num_rows($result) > 0) { |
|
3689
|
|
|
while ($row = Database::fetch_assoc($result)) { |
|
3690
|
|
|
$return[] = ['id' => $row['tag'], 'text' => $row['tag']]; |
|
3691
|
|
|
} |
|
3692
|
|
|
} |
|
3693
|
|
|
if ('json' === $return_format) { |
|
3694
|
|
|
$return = json_encode($return); |
|
3695
|
|
|
} |
|
3696
|
|
|
|
|
3697
|
|
|
return $return; |
|
3698
|
|
|
} |
|
3699
|
|
|
|
|
3700
|
|
|
/** |
|
3701
|
|
|
* @param int $field_id |
|
3702
|
|
|
* @param int $limit |
|
3703
|
|
|
* |
|
3704
|
|
|
* @return array |
|
3705
|
|
|
*/ |
|
3706
|
|
|
public static function get_top_tags($field_id, $limit = 100) |
|
3707
|
|
|
{ |
|
3708
|
|
|
// database table definition |
|
3709
|
|
|
$table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
|
3710
|
|
|
$table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG); |
|
3711
|
|
|
$field_id = (int) $field_id; |
|
3712
|
|
|
$limit = (int) $limit; |
|
3713
|
|
|
// all the information of the field |
|
3714
|
|
|
$sql = "SELECT count(*) count, tag FROM $table_user_tag_values uv |
|
3715
|
|
|
INNER JOIN $table_user_tag ut |
|
3716
|
|
|
ON (ut.id = uv.tag_id) |
|
3717
|
|
|
WHERE field_id = $field_id |
|
3718
|
|
|
GROUP BY tag_id |
|
3719
|
|
|
ORDER BY count DESC |
|
3720
|
|
|
LIMIT $limit"; |
|
3721
|
|
|
$result = Database::query($sql); |
|
3722
|
|
|
$return = []; |
|
3723
|
|
|
if (Database::num_rows($result) > 0) { |
|
3724
|
|
|
while ($row = Database::fetch_assoc($result)) { |
|
3725
|
|
|
$return[] = $row; |
|
3726
|
|
|
} |
|
3727
|
|
|
} |
|
3728
|
|
|
|
|
3729
|
|
|
return $return; |
|
3730
|
|
|
} |
|
3731
|
|
|
|
|
3732
|
|
|
/** |
|
3733
|
|
|
* Get user's tags. |
|
3734
|
|
|
* |
|
3735
|
|
|
* @param int $user_id |
|
3736
|
|
|
* @param int $field_id |
|
3737
|
|
|
* |
|
3738
|
|
|
* @return array |
|
3739
|
|
|
*/ |
|
3740
|
|
|
public static function get_user_tags($user_id, $field_id) |
|
3741
|
|
|
{ |
|
3742
|
|
|
// database table definition |
|
3743
|
|
|
$table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
|
3744
|
|
|
$table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG); |
|
3745
|
|
|
$field_id = (int) $field_id; |
|
3746
|
|
|
$user_id = (int) $user_id; |
|
3747
|
|
|
|
|
3748
|
|
|
// all the information of the field |
|
3749
|
|
|
$sql = "SELECT ut.id, tag, count |
|
3750
|
|
|
FROM $table_user_tag ut |
|
3751
|
|
|
INNER JOIN $table_user_tag_values uv |
|
3752
|
|
|
ON (uv.tag_id=ut.ID) |
|
3753
|
|
|
WHERE field_id = $field_id AND user_id = $user_id |
|
3754
|
|
|
ORDER BY tag"; |
|
3755
|
|
|
$result = Database::query($sql); |
|
3756
|
|
|
$return = []; |
|
3757
|
|
|
if (Database::num_rows($result) > 0) { |
|
3758
|
|
|
while ($row = Database::fetch_assoc($result)) { |
|
3759
|
|
|
$return[$row['id']] = ['tag' => $row['tag'], 'count' => $row['count']]; |
|
3760
|
|
|
} |
|
3761
|
|
|
} |
|
3762
|
|
|
|
|
3763
|
|
|
return $return; |
|
3764
|
|
|
} |
|
3765
|
|
|
|
|
3766
|
|
|
/** |
|
3767
|
|
|
* Get user's tags. |
|
3768
|
|
|
* |
|
3769
|
|
|
* @param int $user_id |
|
3770
|
|
|
* @param int $field_id |
|
3771
|
|
|
* @param bool $show_links show links or not |
|
3772
|
|
|
* |
|
3773
|
|
|
* @return string |
|
3774
|
|
|
*/ |
|
3775
|
|
|
public static function get_user_tags_to_string($user_id, $field_id, $show_links = true) |
|
3776
|
|
|
{ |
|
3777
|
|
|
// database table definition |
|
3778
|
|
|
$table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
|
3779
|
|
|
$table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG); |
|
3780
|
|
|
$field_id = (int) $field_id; |
|
3781
|
|
|
$user_id = (int) $user_id; |
|
3782
|
|
|
|
|
3783
|
|
|
// all the information of the field |
|
3784
|
|
|
$sql = "SELECT ut.id, tag,count FROM $table_user_tag ut |
|
3785
|
|
|
INNER JOIN $table_user_tag_values uv |
|
3786
|
|
|
ON (uv.tag_id = ut.id) |
|
3787
|
|
|
WHERE field_id = $field_id AND user_id = $user_id |
|
3788
|
|
|
ORDER BY tag"; |
|
3789
|
|
|
|
|
3790
|
|
|
$result = Database::query($sql); |
|
3791
|
|
|
$return = []; |
|
3792
|
|
|
if (Database::num_rows($result) > 0) { |
|
3793
|
|
|
while ($row = Database::fetch_assoc($result)) { |
|
3794
|
|
|
$return[$row['id']] = ['tag' => $row['tag'], 'count' => $row['count']]; |
|
3795
|
|
|
} |
|
3796
|
|
|
} |
|
3797
|
|
|
$user_tags = $return; |
|
3798
|
|
|
$tag_tmp = []; |
|
3799
|
|
|
foreach ($user_tags as $tag) { |
|
3800
|
|
|
if ($show_links) { |
|
3801
|
|
|
$tag_tmp[] = '<a href="'.api_get_path(WEB_PATH).'main/search/index.php?q='.$tag['tag'].'">'. |
|
3802
|
|
|
$tag['tag']. |
|
3803
|
|
|
'</a>'; |
|
3804
|
|
|
} else { |
|
3805
|
|
|
$tag_tmp[] = $tag['tag']; |
|
3806
|
|
|
} |
|
3807
|
|
|
} |
|
3808
|
|
|
|
|
3809
|
|
|
if (is_array($user_tags) && count($user_tags) > 0) { |
|
3810
|
|
|
return implode(', ', $tag_tmp); |
|
3811
|
|
|
} else { |
|
3812
|
|
|
return ''; |
|
3813
|
|
|
} |
|
3814
|
|
|
} |
|
3815
|
|
|
|
|
3816
|
|
|
/** |
|
3817
|
|
|
* Get the tag id. |
|
3818
|
|
|
* |
|
3819
|
|
|
* @param int $tag |
|
3820
|
|
|
* @param int $field_id |
|
3821
|
|
|
* |
|
3822
|
|
|
* @return int returns 0 if fails otherwise the tag id |
|
3823
|
|
|
*/ |
|
3824
|
|
|
public static function get_tag_id($tag, $field_id) |
|
3825
|
|
|
{ |
|
3826
|
|
|
$table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
|
3827
|
|
|
$tag = Database::escape_string($tag); |
|
3828
|
|
|
$field_id = (int) $field_id; |
|
3829
|
|
|
//with COLLATE latin1_bin to select query in a case sensitive mode |
|
3830
|
|
|
$sql = "SELECT id FROM $table_user_tag |
|
3831
|
|
|
WHERE tag LIKE '$tag' AND field_id = $field_id"; |
|
3832
|
|
|
$result = Database::query($sql); |
|
3833
|
|
|
if (Database::num_rows($result) > 0) { |
|
3834
|
|
|
$row = Database::fetch_assoc($result); |
|
3835
|
|
|
|
|
3836
|
|
|
return $row['id']; |
|
3837
|
|
|
} else { |
|
3838
|
|
|
return 0; |
|
3839
|
|
|
} |
|
3840
|
|
|
} |
|
3841
|
|
|
|
|
3842
|
|
|
/** |
|
3843
|
|
|
* Get the tag id. |
|
3844
|
|
|
* |
|
3845
|
|
|
* @param int $tag_id |
|
3846
|
|
|
* @param int $field_id |
|
3847
|
|
|
* |
|
3848
|
|
|
* @return int 0 if fails otherwise the tag id |
|
3849
|
|
|
*/ |
|
3850
|
|
|
public static function get_tag_id_from_id($tag_id, $field_id) |
|
3851
|
|
|
{ |
|
3852
|
|
|
$table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
|
3853
|
|
|
$tag_id = (int) $tag_id; |
|
3854
|
|
|
$field_id = (int) $field_id; |
|
3855
|
|
|
$sql = "SELECT id FROM $table_user_tag |
|
3856
|
|
|
WHERE id = '$tag_id' AND field_id = $field_id"; |
|
3857
|
|
|
$result = Database::query($sql); |
|
3858
|
|
|
if (Database::num_rows($result) > 0) { |
|
3859
|
|
|
$row = Database::fetch_assoc($result); |
|
3860
|
|
|
|
|
3861
|
|
|
return $row['id']; |
|
3862
|
|
|
} else { |
|
3863
|
|
|
return false; |
|
3864
|
|
|
} |
|
3865
|
|
|
} |
|
3866
|
|
|
|
|
3867
|
|
|
/** |
|
3868
|
|
|
* Adds a user-tag value. |
|
3869
|
|
|
* |
|
3870
|
|
|
* @param mixed $tag |
|
3871
|
|
|
* @param int $user_id |
|
3872
|
|
|
* @param int $field_id field id of the tag |
|
3873
|
|
|
* |
|
3874
|
|
|
* @return bool True if the tag was inserted or updated. False otherwise. |
|
3875
|
|
|
* The return value doesn't take into account *values* added to the tag. |
|
3876
|
|
|
* Only the creation/update of the tag field itself. |
|
3877
|
|
|
*/ |
|
3878
|
|
|
public static function add_tag($tag, $user_id, $field_id) |
|
3879
|
|
|
{ |
|
3880
|
|
|
// database table definition |
|
3881
|
|
|
$table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
|
3882
|
|
|
$table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG); |
|
3883
|
|
|
$tag = trim(Database::escape_string($tag)); |
|
3884
|
|
|
$user_id = (int) $user_id; |
|
3885
|
|
|
$field_id = (int) $field_id; |
|
3886
|
|
|
|
|
3887
|
|
|
$tag_id = self::get_tag_id($tag, $field_id); |
|
3888
|
|
|
|
|
3889
|
|
|
/* IMPORTANT |
|
3890
|
|
|
* @todo we don't create tags with numbers |
|
3891
|
|
|
* |
|
3892
|
|
|
*/ |
|
3893
|
|
|
|
|
3894
|
|
|
//this is a new tag |
|
3895
|
|
|
if (0 == $tag_id) { |
|
3896
|
|
|
//the tag doesn't exist |
|
3897
|
|
|
$sql = "INSERT INTO $table_user_tag (tag, field_id,count) VALUES ('$tag','$field_id', count + 1)"; |
|
3898
|
|
|
Database::query($sql); |
|
3899
|
|
|
$last_insert_id = Database::insert_id(); |
|
3900
|
|
|
} else { |
|
3901
|
|
|
//the tag exists we update it |
|
3902
|
|
|
$sql = "UPDATE $table_user_tag SET count = count + 1 WHERE id = $tag_id"; |
|
3903
|
|
|
Database::query($sql); |
|
3904
|
|
|
$last_insert_id = $tag_id; |
|
3905
|
|
|
} |
|
3906
|
|
|
|
|
3907
|
|
|
if (!empty($last_insert_id) && (0 != $last_insert_id)) { |
|
3908
|
|
|
//we insert the relationship user-tag |
|
3909
|
|
|
$sql = "SELECT tag_id FROM $table_user_tag_values |
|
3910
|
|
|
WHERE user_id = $user_id AND tag_id = $last_insert_id "; |
|
3911
|
|
|
$result = Database::query($sql); |
|
3912
|
|
|
//if the relationship does not exist we create it |
|
3913
|
|
|
if (0 == Database::num_rows($result)) { |
|
3914
|
|
|
$sql = "INSERT INTO $table_user_tag_values SET user_id = $user_id, tag_id = $last_insert_id"; |
|
3915
|
|
|
Database::query($sql); |
|
3916
|
|
|
} |
|
3917
|
|
|
|
|
3918
|
|
|
return true; |
|
3919
|
|
|
} |
|
3920
|
|
|
|
|
3921
|
|
|
return false; |
|
3922
|
|
|
} |
|
3923
|
|
|
|
|
3924
|
|
|
/** |
|
3925
|
|
|
* Deletes an user tag. |
|
3926
|
|
|
* |
|
3927
|
|
|
* @param int $user_id |
|
3928
|
|
|
* @param int $field_id |
|
3929
|
|
|
*/ |
|
3930
|
|
|
public static function delete_user_tags($user_id, $field_id) |
|
3931
|
|
|
{ |
|
3932
|
|
|
// database table definition |
|
3933
|
|
|
$table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
|
3934
|
|
|
$table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG); |
|
3935
|
|
|
$user_id = (int) $user_id; |
|
3936
|
|
|
|
|
3937
|
|
|
$tags = self::get_user_tags($user_id, $field_id); |
|
3938
|
|
|
if (is_array($tags) && count($tags) > 0) { |
|
3939
|
|
|
foreach ($tags as $key => $tag) { |
|
3940
|
|
|
if ($tag['count'] > '0') { |
|
3941
|
|
|
$sql = "UPDATE $table_user_tag SET count = count - 1 WHERE id = $key "; |
|
3942
|
|
|
Database::query($sql); |
|
3943
|
|
|
} |
|
3944
|
|
|
$sql = "DELETE FROM $table_user_tag_values |
|
3945
|
|
|
WHERE user_id = $user_id AND tag_id = $key"; |
|
3946
|
|
|
Database::query($sql); |
|
3947
|
|
|
} |
|
3948
|
|
|
} |
|
3949
|
|
|
} |
|
3950
|
|
|
|
|
3951
|
|
|
/** |
|
3952
|
|
|
* Process the tag list comes from the UserManager::update_extra_field_value() function. |
|
3953
|
|
|
* |
|
3954
|
|
|
* @param array $tags the tag list that will be added |
|
3955
|
|
|
* @param int $user_id |
|
3956
|
|
|
* @param int $field_id |
|
3957
|
|
|
* |
|
3958
|
|
|
* @return bool |
|
3959
|
|
|
*/ |
|
3960
|
|
|
public static function process_tags($tags, $user_id, $field_id) |
|
3961
|
|
|
{ |
|
3962
|
|
|
// We loop the tags and add it to the DB |
|
3963
|
|
|
if (is_array($tags)) { |
|
3964
|
|
|
foreach ($tags as $tag) { |
|
3965
|
|
|
self::add_tag($tag, $user_id, $field_id); |
|
3966
|
|
|
} |
|
3967
|
|
|
} else { |
|
3968
|
|
|
self::add_tag($tags, $user_id, $field_id); |
|
3969
|
|
|
} |
|
3970
|
|
|
|
|
3971
|
|
|
return true; |
|
3972
|
|
|
} |
|
3973
|
|
|
|
|
3974
|
|
|
/** |
|
3975
|
|
|
* Returns a list of all administrators. |
|
3976
|
|
|
* |
|
3977
|
|
|
* @return array |
|
3978
|
|
|
*/ |
|
3979
|
|
|
public static function get_all_administrators() |
|
3980
|
|
|
{ |
|
3981
|
|
|
$table_user = Database::get_main_table(TABLE_MAIN_USER); |
|
3982
|
|
|
$table_admin = Database::get_main_table(TABLE_MAIN_ADMIN); |
|
3983
|
|
|
$tbl_url_rel_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
|
3984
|
|
|
$access_url_id = api_get_current_access_url_id(); |
|
3985
|
|
|
if (api_get_multiple_access_url()) { |
|
3986
|
|
|
$sql = "SELECT admin.user_id, username, firstname, lastname, email, active, locale |
|
3987
|
|
|
FROM $tbl_url_rel_user as url |
|
3988
|
|
|
INNER JOIN $table_admin as admin |
|
3989
|
|
|
ON (admin.user_id=url.user_id) |
|
3990
|
|
|
INNER JOIN $table_user u |
|
3991
|
|
|
ON (u.id=admin.user_id) |
|
3992
|
|
|
WHERE access_url_id ='".$access_url_id."'"; |
|
3993
|
|
|
} else { |
|
3994
|
|
|
$sql = "SELECT admin.user_id, username, firstname, lastname, email, active, locale |
|
3995
|
|
|
FROM $table_admin as admin |
|
3996
|
|
|
INNER JOIN $table_user u |
|
3997
|
|
|
ON (u.id=admin.user_id)"; |
|
3998
|
|
|
} |
|
3999
|
|
|
$sql .= !str_contains($sql, 'WHERE') ? ' WHERE u.active <> '.USER_SOFT_DELETED : ' AND u.active <> '.USER_SOFT_DELETED; |
|
4000
|
|
|
$result = Database::query($sql); |
|
4001
|
|
|
$return = []; |
|
4002
|
|
|
if (Database::num_rows($result) > 0) { |
|
4003
|
|
|
while ($row = Database::fetch_assoc($result)) { |
|
4004
|
|
|
$return[$row['user_id']] = $row; |
|
4005
|
|
|
} |
|
4006
|
|
|
} |
|
4007
|
|
|
|
|
4008
|
|
|
return $return; |
|
4009
|
|
|
} |
|
4010
|
|
|
|
|
4011
|
|
|
/** |
|
4012
|
|
|
* Search an user (tags, first name, last name and email ). |
|
4013
|
|
|
* |
|
4014
|
|
|
* @param string $tag |
|
4015
|
|
|
* @param int $field_id field id of the tag |
|
4016
|
|
|
* @param int $from where to start in the query |
|
4017
|
|
|
* @param int $number_of_items |
|
4018
|
|
|
* @param bool $getCount get count or not |
|
4019
|
|
|
* |
|
4020
|
|
|
* @return array |
|
4021
|
|
|
*/ |
|
4022
|
|
|
public static function get_all_user_tags( |
|
4023
|
|
|
$tag, |
|
4024
|
|
|
$field_id = 0, |
|
4025
|
|
|
$from = 0, |
|
4026
|
|
|
$number_of_items = 10, |
|
4027
|
|
|
$getCount = false |
|
4028
|
|
|
) { |
|
4029
|
|
|
$user_table = Database::get_main_table(TABLE_MAIN_USER); |
|
4030
|
|
|
$table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
|
4031
|
|
|
$table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG); |
|
4032
|
|
|
$access_url_rel_user_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
|
4033
|
|
|
|
|
4034
|
|
|
$field_id = intval($field_id); |
|
4035
|
|
|
$from = intval($from); |
|
4036
|
|
|
$number_of_items = intval($number_of_items); |
|
4037
|
|
|
|
|
4038
|
|
|
$where_field = ""; |
|
4039
|
|
|
$where_extra_fields = self::get_search_form_where_extra_fields(); |
|
4040
|
|
|
if (0 != $field_id) { |
|
4041
|
|
|
$where_field = " field_id = $field_id AND "; |
|
4042
|
|
|
} |
|
4043
|
|
|
|
|
4044
|
|
|
// all the information of the field |
|
4045
|
|
|
if ($getCount) { |
|
4046
|
|
|
$select = "SELECT count(DISTINCT u.id) count"; |
|
4047
|
|
|
} else { |
|
4048
|
|
|
$select = "SELECT DISTINCT u.id, u.username, firstname, lastname, email, tag, picture_uri"; |
|
4049
|
|
|
} |
|
4050
|
|
|
|
|
4051
|
|
|
$sql = " $select |
|
4052
|
|
|
FROM $user_table u |
|
4053
|
|
|
INNER JOIN $access_url_rel_user_table url_rel_user |
|
4054
|
|
|
ON (u.id = url_rel_user.user_id) |
|
4055
|
|
|
LEFT JOIN $table_user_tag_values uv |
|
4056
|
|
|
ON (u.id AND uv.user_id AND uv.user_id = url_rel_user.user_id) |
|
4057
|
|
|
LEFT JOIN $table_user_tag ut ON (uv.tag_id = ut.id) |
|
4058
|
|
|
WHERE |
|
4059
|
|
|
($where_field tag LIKE '".Database::escape_string($tag."%")."') OR |
|
4060
|
|
|
( |
|
4061
|
|
|
u.firstname LIKE '".Database::escape_string("%".$tag."%")."' OR |
|
4062
|
|
|
u.lastname LIKE '".Database::escape_string("%".$tag."%")."' OR |
|
4063
|
|
|
u.username LIKE '".Database::escape_string("%".$tag."%")."' OR |
|
4064
|
|
|
concat(u.firstname, ' ', u.lastname) LIKE '".Database::escape_string("%".$tag."%")."' OR |
|
4065
|
|
|
concat(u.lastname, ' ', u.firstname) LIKE '".Database::escape_string("%".$tag."%")."' |
|
4066
|
|
|
) |
|
4067
|
|
|
".(!empty($where_extra_fields) ? $where_extra_fields : '')." |
|
4068
|
|
|
AND url_rel_user.access_url_id=".api_get_current_access_url_id(); |
|
4069
|
|
|
|
|
4070
|
|
|
$keyword_active = true; |
|
4071
|
|
|
// only active users |
|
4072
|
|
|
if ($keyword_active) { |
|
4073
|
|
|
$sql .= " AND u.active='1'"; |
|
4074
|
|
|
} |
|
4075
|
|
|
// avoid anonymous |
|
4076
|
|
|
$sql .= " AND u.status <> 6 "; |
|
4077
|
|
|
$sql .= " ORDER BY username"; |
|
4078
|
|
|
$sql .= " LIMIT $from , $number_of_items"; |
|
4079
|
|
|
|
|
4080
|
|
|
$result = Database::query($sql); |
|
4081
|
|
|
$return = []; |
|
4082
|
|
|
|
|
4083
|
|
|
if (Database::num_rows($result) > 0) { |
|
4084
|
|
|
if ($getCount) { |
|
4085
|
|
|
$row = Database::fetch_assoc($result); |
|
4086
|
|
|
|
|
4087
|
|
|
return $row['count']; |
|
4088
|
|
|
} |
|
4089
|
|
|
while ($row = Database::fetch_assoc($result)) { |
|
4090
|
|
|
$return[$row['id']] = $row; |
|
4091
|
|
|
} |
|
4092
|
|
|
} |
|
4093
|
|
|
|
|
4094
|
|
|
return $return; |
|
4095
|
|
|
} |
|
4096
|
|
|
|
|
4097
|
|
|
/** |
|
4098
|
|
|
* Get extra filterable user fields (only type select). |
|
4099
|
|
|
* |
|
4100
|
|
|
* @return array Array of extra fields as [int => ['name' => ..., 'variable' => ..., 'data' => ...]] ( |
|
4101
|
|
|
* or empty array if no extra field) |
|
4102
|
|
|
*/ |
|
4103
|
|
|
public static function getExtraFilterableFields() |
|
4104
|
|
|
{ |
|
4105
|
|
|
$extraFieldList = self::get_extra_fields(); |
|
4106
|
|
|
$fields = []; |
|
4107
|
|
|
if (is_array($extraFieldList)) { |
|
4108
|
|
|
foreach ($extraFieldList as $extraField) { |
|
4109
|
|
|
// If is enabled to filter and is a "<select>" field type |
|
4110
|
|
|
if (1 == $extraField[8] && 4 == $extraField[2]) { |
|
4111
|
|
|
$fields[] = [ |
|
4112
|
|
|
'name' => $extraField[3], |
|
4113
|
|
|
'variable' => $extraField[1], |
|
4114
|
|
|
'data' => $extraField[9], |
|
4115
|
|
|
]; |
|
4116
|
|
|
} |
|
4117
|
|
|
} |
|
4118
|
|
|
} |
|
4119
|
|
|
|
|
4120
|
|
|
return $fields; |
|
4121
|
|
|
} |
|
4122
|
|
|
|
|
4123
|
|
|
/** |
|
4124
|
|
|
* Get extra where clauses for finding users based on extra filterable user fields (type select). |
|
4125
|
|
|
* |
|
4126
|
|
|
* @return string With AND clauses based on user's ID which have the values to search in extra user fields |
|
4127
|
|
|
* (or empty if no extra field exists) |
|
4128
|
|
|
*/ |
|
4129
|
|
|
public static function get_search_form_where_extra_fields() |
|
4130
|
|
|
{ |
|
4131
|
|
|
$useExtraFields = false; |
|
4132
|
|
|
$extraFields = self::getExtraFilterableFields(); |
|
4133
|
|
|
$extraFieldResult = []; |
|
4134
|
|
|
if (is_array($extraFields) && count($extraFields) > 0) { |
|
4135
|
|
|
foreach ($extraFields as $extraField) { |
|
4136
|
|
|
$varName = 'field_'.$extraField['variable']; |
|
4137
|
|
|
if (self::is_extra_field_available($extraField['variable'])) { |
|
4138
|
|
|
if (isset($_GET[$varName]) && '0' != $_GET[$varName]) { |
|
4139
|
|
|
$useExtraFields = true; |
|
4140
|
|
|
$extraFieldResult[] = self::get_extra_user_data_by_value( |
|
4141
|
|
|
$extraField['variable'], |
|
4142
|
|
|
$_GET[$varName] |
|
4143
|
|
|
); |
|
4144
|
|
|
} |
|
4145
|
|
|
} |
|
4146
|
|
|
} |
|
4147
|
|
|
} |
|
4148
|
|
|
|
|
4149
|
|
|
if ($useExtraFields) { |
|
4150
|
|
|
$finalResult = []; |
|
4151
|
|
|
if (count($extraFieldResult) > 1) { |
|
4152
|
|
|
for ($i = 0; $i < count($extraFieldResult) - 1; $i++) { |
|
4153
|
|
|
if (is_array($extraFieldResult[$i]) && is_array($extraFieldResult[$i + 1])) { |
|
4154
|
|
|
$finalResult = array_intersect($extraFieldResult[$i], $extraFieldResult[$i + 1]); |
|
4155
|
|
|
} |
|
4156
|
|
|
} |
|
4157
|
|
|
} else { |
|
4158
|
|
|
$finalResult = $extraFieldResult[0]; |
|
4159
|
|
|
} |
|
4160
|
|
|
|
|
4161
|
|
|
if (is_array($finalResult) && count($finalResult) > 0) { |
|
4162
|
|
|
$whereFilter = " AND u.id IN ('".implode("','", $finalResult)."') "; |
|
4163
|
|
|
} else { |
|
4164
|
|
|
//no results |
|
4165
|
|
|
$whereFilter = " AND u.id = -1 "; |
|
4166
|
|
|
} |
|
4167
|
|
|
|
|
4168
|
|
|
return $whereFilter; |
|
4169
|
|
|
} |
|
4170
|
|
|
|
|
4171
|
|
|
return ''; |
|
4172
|
|
|
} |
|
4173
|
|
|
|
|
4174
|
|
|
/** |
|
4175
|
|
|
* Show the search form. |
|
4176
|
|
|
* |
|
4177
|
|
|
* @param string $query the value of the search box |
|
4178
|
|
|
* |
|
4179
|
|
|
* @throws Exception |
|
4180
|
|
|
* |
|
4181
|
|
|
* @return string HTML form |
|
4182
|
|
|
*/ |
|
4183
|
|
|
public static function get_search_form($query, $defaultParams = []) |
|
4184
|
|
|
{ |
|
4185
|
|
|
$searchType = isset($_GET['search_type']) ? $_GET['search_type'] : null; |
|
4186
|
|
|
$form = new FormValidator( |
|
4187
|
|
|
'search_user', |
|
4188
|
|
|
'get', |
|
4189
|
|
|
api_get_path(WEB_PATH).'main/social/search.php', |
|
4190
|
|
|
'', |
|
4191
|
|
|
[], |
|
4192
|
|
|
FormValidator::LAYOUT_HORIZONTAL |
|
4193
|
|
|
); |
|
4194
|
|
|
|
|
4195
|
|
|
$query = Security::remove_XSS($query); |
|
4196
|
|
|
|
|
4197
|
|
|
if (!empty($query)) { |
|
4198
|
|
|
$form->addHeader(get_lang('Results and feedback').' "'.$query.'"'); |
|
4199
|
|
|
} |
|
4200
|
|
|
|
|
4201
|
|
|
$form->addText( |
|
4202
|
|
|
'q', |
|
4203
|
|
|
get_lang('Users, Groups'), |
|
4204
|
|
|
false, |
|
4205
|
|
|
[ |
|
4206
|
|
|
'id' => 'q', |
|
4207
|
|
|
] |
|
4208
|
|
|
); |
|
4209
|
|
|
$options = [ |
|
4210
|
|
|
0 => get_lang('Select'), |
|
4211
|
|
|
1 => get_lang('User'), |
|
4212
|
|
|
2 => get_lang('Group'), |
|
4213
|
|
|
]; |
|
4214
|
|
|
$form->addSelect( |
|
4215
|
|
|
'search_type', |
|
4216
|
|
|
get_lang('Type'), |
|
4217
|
|
|
$options, |
|
4218
|
|
|
['onchange' => 'javascript: extra_field_toogle();', 'id' => 'search_type'] |
|
4219
|
|
|
); |
|
4220
|
|
|
|
|
4221
|
|
|
// Extra fields |
|
4222
|
|
|
$extraFields = self::getExtraFilterableFields(); |
|
4223
|
|
|
$defaults = []; |
|
4224
|
|
|
if (is_array($extraFields) && count($extraFields) > 0) { |
|
4225
|
|
|
foreach ($extraFields as $extraField) { |
|
4226
|
|
|
$varName = 'field_'.$extraField['variable']; |
|
4227
|
|
|
$options = [ |
|
4228
|
|
|
0 => get_lang('Select'), |
|
4229
|
|
|
]; |
|
4230
|
|
|
foreach ($extraField['data'] as $option) { |
|
4231
|
|
|
if (isset($_GET[$varName])) { |
|
4232
|
|
|
if ($_GET[$varName] == $option[1]) { |
|
4233
|
|
|
$defaults[$option[1]] = true; |
|
4234
|
|
|
} |
|
4235
|
|
|
} |
|
4236
|
|
|
|
|
4237
|
|
|
$options[$option[1]] = $option[1]; |
|
4238
|
|
|
} |
|
4239
|
|
|
$form->addSelect($varName, $extraField['name'], $options); |
|
4240
|
|
|
} |
|
4241
|
|
|
} |
|
4242
|
|
|
|
|
4243
|
|
|
$defaults['search_type'] = (int) $searchType; |
|
4244
|
|
|
$defaults['q'] = $query; |
|
4245
|
|
|
|
|
4246
|
|
|
if (!empty($defaultParams)) { |
|
4247
|
|
|
$defaults = array_merge($defaults, $defaultParams); |
|
4248
|
|
|
} |
|
4249
|
|
|
$form->setDefaults($defaults); |
|
4250
|
|
|
$form->addButtonSearch(get_lang('Search')); |
|
4251
|
|
|
|
|
4252
|
|
|
$js = '<script> |
|
4253
|
|
|
extra_field_toogle(); |
|
4254
|
|
|
function extra_field_toogle() { |
|
4255
|
|
|
if (jQuery("select[name=search_type]").val() != "1") { |
|
4256
|
|
|
jQuery(".extra_field").hide(); |
|
4257
|
|
|
} else { |
|
4258
|
|
|
jQuery(".extra_field").show(); |
|
4259
|
|
|
} |
|
4260
|
|
|
} |
|
4261
|
|
|
</script>'; |
|
4262
|
|
|
|
|
4263
|
|
|
return $js.$form->returnForm(); |
|
4264
|
|
|
} |
|
4265
|
|
|
|
|
4266
|
|
|
/** |
|
4267
|
|
|
* @param int $userId |
|
4268
|
|
|
* |
|
4269
|
|
|
* @return array |
|
4270
|
|
|
*/ |
|
4271
|
|
|
public static function getDrhListFromUser($userId) |
|
4272
|
|
|
{ |
|
4273
|
|
|
$tblUser = Database::get_main_table(TABLE_MAIN_USER); |
|
4274
|
|
|
$tblUserRelUser = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
|
4275
|
|
|
$tblUserRelAccessUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
|
4276
|
|
|
$userId = (int) $userId; |
|
4277
|
|
|
|
|
4278
|
|
|
$orderBy = null; |
|
4279
|
|
|
if (api_is_western_name_order()) { |
|
4280
|
|
|
$orderBy .= ' ORDER BY firstname, lastname '; |
|
4281
|
|
|
} else { |
|
4282
|
|
|
$orderBy .= ' ORDER BY lastname, firstname '; |
|
4283
|
|
|
} |
|
4284
|
|
|
|
|
4285
|
|
|
$sql = "SELECT u.id, username, u.firstname, u.lastname |
|
4286
|
|
|
FROM $tblUser u |
|
4287
|
|
|
INNER JOIN $tblUserRelUser uru ON (uru.friend_user_id = u.id) |
|
4288
|
|
|
INNER JOIN $tblUserRelAccessUrl a ON (a.user_id = u.id) |
|
4289
|
|
|
WHERE |
|
4290
|
|
|
access_url_id = ".api_get_current_access_url_id()." AND |
|
4291
|
|
|
uru.user_id = '$userId' AND |
|
4292
|
|
|
relation_type = '".UserRelUser::USER_RELATION_TYPE_RRHH."' |
|
4293
|
|
|
$orderBy |
|
4294
|
|
|
"; |
|
4295
|
|
|
$result = Database::query($sql); |
|
4296
|
|
|
|
|
4297
|
|
|
return Database::store_result($result); |
|
4298
|
|
|
} |
|
4299
|
|
|
|
|
4300
|
|
|
/** |
|
4301
|
|
|
* get users followed by human resource manager. |
|
4302
|
|
|
* |
|
4303
|
|
|
* @param int $userId |
|
4304
|
|
|
* @param int $userStatus (STUDENT, COURSEMANAGER, etc) |
|
4305
|
|
|
* @param bool $getOnlyUserId |
|
4306
|
|
|
* @param bool $getSql |
|
4307
|
|
|
* @param bool $getCount |
|
4308
|
|
|
* @param int $from |
|
4309
|
|
|
* @param int $numberItems |
|
4310
|
|
|
* @param int $column |
|
4311
|
|
|
* @param string $direction |
|
4312
|
|
|
* @param int $active |
|
4313
|
|
|
* @param string $lastConnectionDate |
|
4314
|
|
|
* |
|
4315
|
|
|
* @return array users |
|
4316
|
|
|
*/ |
|
4317
|
|
|
public static function get_users_followed_by_drh( |
|
4318
|
|
|
$userId, |
|
4319
|
|
|
$userStatus = 0, |
|
4320
|
|
|
$getOnlyUserId = false, |
|
4321
|
|
|
$getSql = false, |
|
4322
|
|
|
$getCount = false, |
|
4323
|
|
|
$from = null, |
|
4324
|
|
|
$numberItems = null, |
|
4325
|
|
|
$column = null, |
|
4326
|
|
|
$direction = null, |
|
4327
|
|
|
$active = null, |
|
4328
|
|
|
$lastConnectionDate = null |
|
4329
|
|
|
) { |
|
4330
|
|
|
return self::getUsersFollowedByUser( |
|
|
|
|
|
|
4331
|
|
|
$userId, |
|
4332
|
|
|
$userStatus, |
|
4333
|
|
|
$getOnlyUserId, |
|
4334
|
|
|
$getSql, |
|
4335
|
|
|
$getCount, |
|
4336
|
|
|
$from, |
|
4337
|
|
|
$numberItems, |
|
4338
|
|
|
$column, |
|
4339
|
|
|
$direction, |
|
4340
|
|
|
$active, |
|
4341
|
|
|
$lastConnectionDate, |
|
4342
|
|
|
DRH |
|
4343
|
|
|
); |
|
4344
|
|
|
} |
|
4345
|
|
|
|
|
4346
|
|
|
/** |
|
4347
|
|
|
* Get users followed by human resource manager. |
|
4348
|
|
|
* |
|
4349
|
|
|
* @param int $userId |
|
4350
|
|
|
* @param int $userStatus Filter users by status (STUDENT, COURSEMANAGER, etc) |
|
4351
|
|
|
* @param bool $getOnlyUserId |
|
4352
|
|
|
* @param bool $getSql |
|
4353
|
|
|
* @param bool $getCount |
|
4354
|
|
|
* @param int $from |
|
4355
|
|
|
* @param int $numberItems |
|
4356
|
|
|
* @param int $column |
|
4357
|
|
|
* @param string $direction |
|
4358
|
|
|
* @param int $active |
|
4359
|
|
|
* @param string $lastConnectionDate |
|
4360
|
|
|
* @param int $status the function is called by who? COURSEMANAGER, DRH? |
|
4361
|
|
|
* @param string $keyword |
|
4362
|
|
|
* @param bool $checkSessionVisibility |
|
4363
|
|
|
* |
|
4364
|
|
|
* @return mixed Users list (array) or the SQL query if $getSQL was set to true |
|
4365
|
|
|
*/ |
|
4366
|
|
|
public static function getUsersFollowedByUser( |
|
4367
|
|
|
$userId, |
|
4368
|
|
|
$userStatus = null, |
|
4369
|
|
|
$getOnlyUserId = false, |
|
4370
|
|
|
$getSql = false, |
|
4371
|
|
|
$getCount = false, |
|
4372
|
|
|
$from = null, |
|
4373
|
|
|
$numberItems = null, |
|
4374
|
|
|
$column = null, |
|
4375
|
|
|
$direction = null, |
|
4376
|
|
|
$active = null, |
|
4377
|
|
|
$lastConnectionDate = null, |
|
4378
|
|
|
$status = null, |
|
4379
|
|
|
$keyword = null, |
|
4380
|
|
|
$checkSessionVisibility = false |
|
4381
|
|
|
) { |
|
4382
|
|
|
// Database Table Definitions |
|
4383
|
|
|
$tbl_user = Database::get_main_table(TABLE_MAIN_USER); |
|
4384
|
|
|
$tbl_user_rel_user = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
|
4385
|
|
|
$tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
|
4386
|
|
|
$tbl_session = Database::get_main_table(TABLE_MAIN_SESSION); |
|
4387
|
|
|
$tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
|
4388
|
|
|
$tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
|
4389
|
|
|
$tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION); |
|
4390
|
|
|
$tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER); |
|
4391
|
|
|
|
|
4392
|
|
|
$userId = (int) $userId; |
|
4393
|
|
|
$limitCondition = ''; |
|
4394
|
|
|
|
|
4395
|
|
|
if (isset($from) && isset($numberItems)) { |
|
4396
|
|
|
$from = (int) $from; |
|
4397
|
|
|
$numberItems = (int) $numberItems; |
|
4398
|
|
|
$limitCondition = "LIMIT $from, $numberItems"; |
|
4399
|
|
|
} |
|
4400
|
|
|
|
|
4401
|
|
|
$column = Database::escape_string($column); |
|
4402
|
|
|
$direction = in_array(strtolower($direction), ['asc', 'desc']) ? $direction : null; |
|
4403
|
|
|
|
|
4404
|
|
|
$userConditions = ''; |
|
4405
|
|
|
if (!empty($userStatus)) { |
|
4406
|
|
|
$userConditions .= ' AND u.status = '.intval($userStatus); |
|
4407
|
|
|
} |
|
4408
|
|
|
|
|
4409
|
|
|
$select = " SELECT DISTINCT u.id user_id, u.username, u.lastname, u.firstname, u.email "; |
|
4410
|
|
|
if ($getOnlyUserId) { |
|
4411
|
|
|
$select = " SELECT DISTINCT u.id user_id"; |
|
4412
|
|
|
} |
|
4413
|
|
|
|
|
4414
|
|
|
$masterSelect = "SELECT DISTINCT * FROM "; |
|
4415
|
|
|
|
|
4416
|
|
|
if ($getCount) { |
|
4417
|
|
|
$masterSelect = "SELECT COUNT(DISTINCT(user_id)) as count FROM "; |
|
4418
|
|
|
$select = " SELECT DISTINCT(u.id) user_id"; |
|
4419
|
|
|
} |
|
4420
|
|
|
|
|
4421
|
|
|
if (!is_null($active)) { |
|
4422
|
|
|
$active = intval($active); |
|
4423
|
|
|
$userConditions .= " AND u.active = $active "; |
|
4424
|
|
|
} |
|
4425
|
|
|
|
|
4426
|
|
|
if (!empty($keyword)) { |
|
4427
|
|
|
$keyword = trim(Database::escape_string($keyword)); |
|
4428
|
|
|
$keywordParts = array_filter(explode(' ', $keyword)); |
|
4429
|
|
|
$extraKeyword = ''; |
|
4430
|
|
|
if (!empty($keywordParts)) { |
|
4431
|
|
|
$keywordPartsFixed = Database::escape_string(implode('%', $keywordParts)); |
|
4432
|
|
|
if (!empty($keywordPartsFixed)) { |
|
4433
|
|
|
$extraKeyword .= " OR |
|
4434
|
|
|
CONCAT(u.firstname, ' ', u.lastname) LIKE '%$keywordPartsFixed%' OR |
|
4435
|
|
|
CONCAT(u.lastname, ' ', u.firstname) LIKE '%$keywordPartsFixed%' "; |
|
4436
|
|
|
} |
|
4437
|
|
|
} |
|
4438
|
|
|
$userConditions .= " AND ( |
|
4439
|
|
|
u.username LIKE '%$keyword%' OR |
|
4440
|
|
|
u.firstname LIKE '%$keyword%' OR |
|
4441
|
|
|
u.lastname LIKE '%$keyword%' OR |
|
4442
|
|
|
u.official_code LIKE '%$keyword%' OR |
|
4443
|
|
|
u.email LIKE '%$keyword%' OR |
|
4444
|
|
|
CONCAT(u.firstname, ' ', u.lastname) LIKE '%$keyword%' OR |
|
4445
|
|
|
CONCAT(u.lastname, ' ', u.firstname) LIKE '%$keyword%' |
|
4446
|
|
|
$extraKeyword |
|
4447
|
|
|
)"; |
|
4448
|
|
|
} |
|
4449
|
|
|
|
|
4450
|
|
|
if (!empty($lastConnectionDate)) { |
|
4451
|
|
|
$lastConnectionDate = Database::escape_string($lastConnectionDate); |
|
4452
|
|
|
$userConditions .= " AND u.last_login <= '$lastConnectionDate' "; |
|
4453
|
|
|
} |
|
4454
|
|
|
|
|
4455
|
|
|
$sessionConditionsCoach = null; |
|
4456
|
|
|
$dateCondition = ''; |
|
4457
|
|
|
$drhConditions = null; |
|
4458
|
|
|
$teacherSelect = null; |
|
4459
|
|
|
$urlId = api_get_current_access_url_id(); |
|
4460
|
|
|
|
|
4461
|
|
|
switch ($status) { |
|
4462
|
|
|
case DRH: |
|
4463
|
|
|
$drhConditions .= " AND |
|
4464
|
|
|
friend_user_id = '$userId' AND |
|
4465
|
|
|
relation_type = '".UserRelUser::USER_RELATION_TYPE_RRHH."' |
|
4466
|
|
|
"; |
|
4467
|
|
|
break; |
|
4468
|
|
|
case COURSEMANAGER: |
|
4469
|
|
|
$drhConditions .= " AND |
|
4470
|
|
|
friend_user_id = '$userId' AND |
|
4471
|
|
|
relation_type = '".UserRelUser::USER_RELATION_TYPE_RRHH."' |
|
4472
|
|
|
"; |
|
4473
|
|
|
|
|
4474
|
|
|
$sessionConditionsTeacher = " AND |
|
4475
|
|
|
(scu.status = ".SessionEntity::COURSE_COACH." AND scu.user_id = '$userId') |
|
4476
|
|
|
"; |
|
4477
|
|
|
|
|
4478
|
|
|
if ($checkSessionVisibility) { |
|
4479
|
|
|
$today = api_strtotime('now', 'UTC'); |
|
4480
|
|
|
$today = date('Y-m-d', $today); |
|
4481
|
|
|
$dateCondition = " |
|
4482
|
|
|
AND |
|
4483
|
|
|
( |
|
4484
|
|
|
(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR |
|
4485
|
|
|
(s.access_start_date IS NULL AND s.access_end_date IS NULL) OR |
|
4486
|
|
|
(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR |
|
4487
|
|
|
('$today' <= s.access_end_date AND s.access_start_date IS NULL) |
|
4488
|
|
|
) |
|
4489
|
|
|
"; |
|
4490
|
|
|
} |
|
4491
|
|
|
|
|
4492
|
|
|
// Use $tbl_session_rel_course_rel_user instead of $tbl_session_rel_user |
|
4493
|
|
|
/* |
|
4494
|
|
|
INNER JOIN $tbl_session_rel_user sru |
|
4495
|
|
|
ON (sru.user_id = u.id) |
|
4496
|
|
|
INNER JOIN $tbl_session_rel_course_rel_user scu |
|
4497
|
|
|
ON (scu.user_id = u.id AND scu.c_id IS NOT NULL AND visibility = 1)*/ |
|
4498
|
|
|
$teacherSelect = |
|
4499
|
|
|
"UNION ALL ( |
|
4500
|
|
|
$select |
|
4501
|
|
|
FROM $tbl_user u |
|
4502
|
|
|
INNER JOIN $tbl_session_rel_user sru ON (sru.user_id = u.id) |
|
4503
|
|
|
WHERE |
|
4504
|
|
|
( |
|
4505
|
|
|
sru.session_id IN ( |
|
4506
|
|
|
SELECT DISTINCT(s.id) FROM $tbl_session s INNER JOIN |
|
4507
|
|
|
$tbl_session_rel_access_url session_rel_access_rel_user |
|
4508
|
|
|
ON session_rel_access_rel_user.session_id = s.id |
|
4509
|
|
|
INNER JOIN $tbl_session_rel_user sru ON s.id = sru.session_id |
|
4510
|
|
|
WHERE access_url_id = ".$urlId." |
|
4511
|
|
|
AND (sru.relation_type = ".SessionEntity::GENERAL_COACH." |
|
4512
|
|
|
AND sru.user_id = $userId) |
|
4513
|
|
|
) OR sru.session_id IN ( |
|
4514
|
|
|
SELECT DISTINCT(s.id) FROM $tbl_session s |
|
4515
|
|
|
INNER JOIN $tbl_session_rel_access_url url |
|
4516
|
|
|
ON (url.session_id = s.id) |
|
4517
|
|
|
INNER JOIN $tbl_session_rel_course_rel_user scu |
|
4518
|
|
|
ON (scu.session_id = s.id) |
|
4519
|
|
|
WHERE access_url_id = ".$urlId." |
|
4520
|
|
|
$sessionConditionsTeacher |
|
4521
|
|
|
$dateCondition |
|
4522
|
|
|
) |
|
4523
|
|
|
) |
|
4524
|
|
|
$userConditions |
|
4525
|
|
|
) |
|
4526
|
|
|
UNION ALL( |
|
4527
|
|
|
$select |
|
4528
|
|
|
FROM $tbl_user u |
|
4529
|
|
|
INNER JOIN $tbl_course_user cu ON (cu.user_id = u.id) |
|
4530
|
|
|
WHERE cu.c_id IN ( |
|
4531
|
|
|
SELECT DISTINCT(c_id) FROM $tbl_course_user |
|
4532
|
|
|
WHERE user_id = $userId AND status = ".COURSEMANAGER." |
|
4533
|
|
|
) |
|
4534
|
|
|
$userConditions |
|
4535
|
|
|
)" |
|
4536
|
|
|
; |
|
4537
|
|
|
break; |
|
4538
|
|
|
case STUDENT_BOSS: |
|
4539
|
|
|
$drhConditions = " AND friend_user_id = $userId AND relation_type = ".UserRelUser::USER_RELATION_TYPE_BOSS; |
|
4540
|
|
|
break; |
|
4541
|
|
|
case HRM_REQUEST: |
|
4542
|
|
|
$drhConditions .= " AND |
|
4543
|
|
|
friend_user_id = '$userId' AND |
|
4544
|
|
|
relation_type = '".UserRelUser::USER_RELATION_TYPE_HRM_REQUEST."' |
|
4545
|
|
|
"; |
|
4546
|
|
|
break; |
|
4547
|
|
|
} |
|
4548
|
|
|
|
|
4549
|
|
|
$join = null; |
|
4550
|
|
|
$sql = " $masterSelect |
|
4551
|
|
|
( |
|
4552
|
|
|
( |
|
4553
|
|
|
$select |
|
4554
|
|
|
FROM $tbl_user u |
|
4555
|
|
|
INNER JOIN $tbl_user_rel_user uru ON (uru.user_id = u.id) |
|
4556
|
|
|
LEFT JOIN $tbl_user_rel_access_url a ON (a.user_id = u.id) |
|
4557
|
|
|
$join |
|
4558
|
|
|
WHERE |
|
4559
|
|
|
access_url_id = ".$urlId." |
|
4560
|
|
|
$drhConditions |
|
4561
|
|
|
$userConditions |
|
4562
|
|
|
) |
|
4563
|
|
|
$teacherSelect |
|
4564
|
|
|
|
|
4565
|
|
|
) as t1"; |
|
4566
|
|
|
|
|
4567
|
|
|
if ($getSql) { |
|
4568
|
|
|
return $sql; |
|
4569
|
|
|
} |
|
4570
|
|
|
if ($getCount) { |
|
4571
|
|
|
$result = Database::query($sql); |
|
4572
|
|
|
$row = Database::fetch_array($result); |
|
4573
|
|
|
|
|
4574
|
|
|
return $row['count']; |
|
4575
|
|
|
} |
|
4576
|
|
|
|
|
4577
|
|
|
$orderBy = null; |
|
4578
|
|
|
if (false == $getOnlyUserId) { |
|
|
|
|
|
|
4579
|
|
|
if (api_is_western_name_order()) { |
|
4580
|
|
|
$orderBy .= " ORDER BY firstname, lastname "; |
|
4581
|
|
|
} else { |
|
4582
|
|
|
$orderBy .= " ORDER BY lastname, firstname "; |
|
4583
|
|
|
} |
|
4584
|
|
|
|
|
4585
|
|
|
if (!empty($column) && !empty($direction)) { |
|
4586
|
|
|
// Fixing order due the UNIONs |
|
4587
|
|
|
$column = str_replace('u.', '', $column); |
|
4588
|
|
|
$orderBy = " ORDER BY `$column` $direction "; |
|
4589
|
|
|
} |
|
4590
|
|
|
} |
|
4591
|
|
|
|
|
4592
|
|
|
$sql .= $orderBy; |
|
4593
|
|
|
$sql .= $limitCondition; |
|
4594
|
|
|
|
|
4595
|
|
|
$result = Database::query($sql); |
|
4596
|
|
|
$users = []; |
|
4597
|
|
|
if (Database::num_rows($result) > 0) { |
|
4598
|
|
|
while ($row = Database::fetch_array($result)) { |
|
4599
|
|
|
$users[$row['user_id']] = $row; |
|
4600
|
|
|
} |
|
4601
|
|
|
} |
|
4602
|
|
|
|
|
4603
|
|
|
return $users; |
|
4604
|
|
|
} |
|
4605
|
|
|
|
|
4606
|
|
|
/** |
|
4607
|
|
|
* Subscribes users to human resource manager (Dashboard feature). |
|
4608
|
|
|
* |
|
4609
|
|
|
* @param int $hr_dept_id |
|
4610
|
|
|
* @param array $users_id |
|
4611
|
|
|
* @param bool $deleteOtherAssignedUsers |
|
4612
|
|
|
*/ |
|
4613
|
|
|
public static function subscribeUsersToHRManager( |
|
4614
|
|
|
$hr_dept_id, |
|
4615
|
|
|
$users_id, |
|
4616
|
|
|
$deleteOtherAssignedUsers = true |
|
4617
|
|
|
): void { |
|
4618
|
|
|
self::subscribeUsersToUser( |
|
4619
|
|
|
$hr_dept_id, |
|
4620
|
|
|
$users_id, |
|
4621
|
|
|
UserRelUser::USER_RELATION_TYPE_RRHH, |
|
4622
|
|
|
false, |
|
4623
|
|
|
$deleteOtherAssignedUsers |
|
4624
|
|
|
); |
|
4625
|
|
|
} |
|
4626
|
|
|
|
|
4627
|
|
|
/** |
|
4628
|
|
|
* Register request to assign users to HRM. |
|
4629
|
|
|
* |
|
4630
|
|
|
* @param int $hrmId The HRM ID |
|
4631
|
|
|
* @param array $usersId The users IDs |
|
4632
|
|
|
*/ |
|
4633
|
|
|
public static function requestUsersToHRManager($hrmId, $usersId): void |
|
4634
|
|
|
{ |
|
4635
|
|
|
self::subscribeUsersToUser( |
|
4636
|
|
|
$hrmId, |
|
4637
|
|
|
$usersId, |
|
4638
|
|
|
UserRelUser::USER_RELATION_TYPE_HRM_REQUEST, |
|
4639
|
|
|
false, |
|
4640
|
|
|
false |
|
4641
|
|
|
); |
|
4642
|
|
|
} |
|
4643
|
|
|
|
|
4644
|
|
|
/** |
|
4645
|
|
|
* Remove the requests for assign a user to a HRM. |
|
4646
|
|
|
* |
|
4647
|
|
|
* @param array $usersId List of user IDs from whom to remove all relations requests with HRM |
|
4648
|
|
|
*/ |
|
4649
|
|
|
public static function clearHrmRequestsForUser(User $hrmId, $usersId) |
|
4650
|
|
|
{ |
|
4651
|
|
|
$users = implode(', ', $usersId); |
|
4652
|
|
|
Database::getManager() |
|
4653
|
|
|
->createQuery(' |
|
4654
|
|
|
DELETE FROM ChamiloCoreBundle:UserRelUser uru |
|
4655
|
|
|
WHERE uru.friendUserId = :hrm_id AND uru.relationType = :relation_type AND uru.userId IN (:users_ids) |
|
4656
|
|
|
') |
|
4657
|
|
|
->execute(['hrm_id' => $hrmId, 'relation_type' => UserRelUser::USER_RELATION_TYPE_HRM_REQUEST, 'users_ids' => $users]); |
|
4658
|
|
|
} |
|
4659
|
|
|
|
|
4660
|
|
|
/** |
|
4661
|
|
|
* Add subscribed users to a user by relation type. |
|
4662
|
|
|
* |
|
4663
|
|
|
* @param int $userId The user id |
|
4664
|
|
|
* @param array $subscribedUsersId The id of subscribed users |
|
4665
|
|
|
* @param int $relationType The relation type |
|
4666
|
|
|
* @param bool $deleteUsersBeforeInsert |
|
4667
|
|
|
* @param bool $deleteOtherAssignedUsers |
|
4668
|
|
|
*/ |
|
4669
|
|
|
public static function subscribeUsersToUser( |
|
4670
|
|
|
$userId, |
|
4671
|
|
|
$subscribedUsersId, |
|
4672
|
|
|
$relationType, |
|
4673
|
|
|
$deleteUsersBeforeInsert = false, |
|
4674
|
|
|
$deleteOtherAssignedUsers = true |
|
4675
|
|
|
): void { |
|
4676
|
|
|
$userRelUserTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
|
4677
|
|
|
$userRelAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
|
4678
|
|
|
|
|
4679
|
|
|
$userId = (int) $userId; |
|
4680
|
|
|
$relationType = (int) $relationType; |
|
4681
|
|
|
|
|
4682
|
|
|
if ($deleteOtherAssignedUsers) { |
|
4683
|
|
|
if (api_get_multiple_access_url()) { |
|
4684
|
|
|
// Deleting assigned users to hrm_id |
|
4685
|
|
|
$sql = "SELECT s.user_id |
|
4686
|
|
|
FROM $userRelUserTable s |
|
4687
|
|
|
INNER JOIN $userRelAccessUrlTable a |
|
4688
|
|
|
ON (a.user_id = s.user_id) |
|
4689
|
|
|
WHERE |
|
4690
|
|
|
friend_user_id = $userId AND |
|
4691
|
|
|
relation_type = $relationType AND |
|
4692
|
|
|
access_url_id = ".api_get_current_access_url_id(); |
|
4693
|
|
|
} else { |
|
4694
|
|
|
$sql = "SELECT user_id |
|
4695
|
|
|
FROM $userRelUserTable |
|
4696
|
|
|
WHERE |
|
4697
|
|
|
friend_user_id = $userId AND |
|
4698
|
|
|
relation_type = $relationType"; |
|
4699
|
|
|
} |
|
4700
|
|
|
$result = Database::query($sql); |
|
4701
|
|
|
|
|
4702
|
|
|
if (Database::num_rows($result) > 0) { |
|
4703
|
|
|
while ($row = Database::fetch_array($result)) { |
|
4704
|
|
|
$sql = "DELETE FROM $userRelUserTable |
|
4705
|
|
|
WHERE |
|
4706
|
|
|
user_id = {$row['user_id']} AND |
|
4707
|
|
|
friend_user_id = $userId AND |
|
4708
|
|
|
relation_type = $relationType"; |
|
4709
|
|
|
Database::query($sql); |
|
4710
|
|
|
} |
|
4711
|
|
|
} |
|
4712
|
|
|
} |
|
4713
|
|
|
|
|
4714
|
|
|
if ($deleteUsersBeforeInsert) { |
|
4715
|
|
|
$sql = "DELETE FROM $userRelUserTable |
|
4716
|
|
|
WHERE |
|
4717
|
|
|
user_id = $userId AND |
|
4718
|
|
|
relation_type = $relationType"; |
|
4719
|
|
|
Database::query($sql); |
|
4720
|
|
|
} |
|
4721
|
|
|
|
|
4722
|
|
|
// Inserting new user list. |
|
4723
|
|
|
if (is_array($subscribedUsersId)) { |
|
4724
|
|
|
foreach ($subscribedUsersId as $subscribedUserId) { |
|
4725
|
|
|
$subscribedUserId = (int) $subscribedUserId; |
|
4726
|
|
|
$sql = "SELECT id |
|
4727
|
|
|
FROM $userRelUserTable |
|
4728
|
|
|
WHERE |
|
4729
|
|
|
user_id = $subscribedUserId AND |
|
4730
|
|
|
friend_user_id = $userId AND |
|
4731
|
|
|
relation_type = $relationType"; |
|
4732
|
|
|
|
|
4733
|
|
|
$result = Database::query($sql); |
|
4734
|
|
|
$num = Database::num_rows($result); |
|
4735
|
|
|
if (0 === $num) { |
|
4736
|
|
|
$userRelUser = (new UserRelUser()) |
|
4737
|
|
|
->setUser(api_get_user_entity($subscribedUserId)) |
|
4738
|
|
|
->setFriend(api_get_user_entity($userId)) |
|
4739
|
|
|
->setRelationType($relationType) |
|
4740
|
|
|
; |
|
4741
|
|
|
$em = Database::getManager(); |
|
4742
|
|
|
$em->persist($userRelUser); |
|
4743
|
|
|
$em->flush(); |
|
4744
|
|
|
} |
|
4745
|
|
|
} |
|
4746
|
|
|
} |
|
4747
|
|
|
} |
|
4748
|
|
|
|
|
4749
|
|
|
/** |
|
4750
|
|
|
* This function checks if a user is followed by provided human resources managers. |
|
4751
|
|
|
* |
|
4752
|
|
|
* @param int $user_id |
|
4753
|
|
|
* @param int $hr_dept_id Human resources manager |
|
4754
|
|
|
* |
|
4755
|
|
|
* @return bool |
|
4756
|
|
|
* @throws Exception |
|
4757
|
|
|
* @throws \Doctrine\DBAL\Exception |
|
4758
|
|
|
*/ |
|
4759
|
|
|
public static function is_user_followed_by_drh(int $user_id, int $hr_dept_id): bool |
|
4760
|
|
|
{ |
|
4761
|
|
|
$tbl_user_rel_user = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
|
4762
|
|
|
$result = false; |
|
4763
|
|
|
|
|
4764
|
|
|
$sql = "SELECT user_id FROM $tbl_user_rel_user |
|
4765
|
|
|
WHERE |
|
4766
|
|
|
user_id = $user_id AND |
|
4767
|
|
|
friend_user_id = $hr_dept_id AND |
|
4768
|
|
|
relation_type = ".UserRelUser::USER_RELATION_TYPE_RRHH; |
|
4769
|
|
|
$rs = Database::query($sql); |
|
4770
|
|
|
if (Database::num_rows($rs) > 0) { |
|
4771
|
|
|
$result = true; |
|
4772
|
|
|
} |
|
4773
|
|
|
|
|
4774
|
|
|
return $result; |
|
4775
|
|
|
} |
|
4776
|
|
|
|
|
4777
|
|
|
/** |
|
4778
|
|
|
* Return the user id of teacher or session administrator. |
|
4779
|
|
|
* |
|
4780
|
|
|
* @param array $courseInfo |
|
4781
|
|
|
* |
|
4782
|
|
|
* @return int The user id, or 0 if the session ID was negative |
|
4783
|
|
|
* @throws Exception |
|
4784
|
|
|
* @throws \Doctrine\DBAL\Exception |
|
4785
|
|
|
*/ |
|
4786
|
|
|
public static function get_user_id_of_course_admin_or_session_admin(array $courseInfo): int |
|
4787
|
|
|
{ |
|
4788
|
|
|
$session = api_get_session_id(); |
|
4789
|
|
|
$table_user = Database::get_main_table(TABLE_MAIN_USER); |
|
4790
|
|
|
$table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
|
4791
|
|
|
$table_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
|
4792
|
|
|
|
|
4793
|
|
|
if (empty($courseInfo)) { |
|
4794
|
|
|
return 0; |
|
4795
|
|
|
} |
|
4796
|
|
|
|
|
4797
|
|
|
$courseId = $courseInfo['real_id']; |
|
4798
|
|
|
|
|
4799
|
|
|
if (0 == $session) { |
|
4800
|
|
|
$sql = 'SELECT u.id uid FROM '.$table_user.' u |
|
4801
|
|
|
INNER JOIN '.$table_course_user.' ru |
|
4802
|
|
|
ON ru.user_id = u.id |
|
4803
|
|
|
WHERE |
|
4804
|
|
|
ru.status = 1 AND |
|
4805
|
|
|
ru.c_id = "'.$courseId.'" '; |
|
4806
|
|
|
$rs = Database::query($sql); |
|
4807
|
|
|
$num_rows = Database::num_rows($rs); |
|
4808
|
|
|
if (1 == $num_rows) { |
|
4809
|
|
|
$row = Database::fetch_array($rs); |
|
4810
|
|
|
|
|
4811
|
|
|
return (int) $row['uid']; |
|
4812
|
|
|
} else { |
|
4813
|
|
|
$my_num_rows = $num_rows; |
|
4814
|
|
|
|
|
4815
|
|
|
return (int) Database::result($rs, $my_num_rows - 1, 'uid'); |
|
4816
|
|
|
} |
|
4817
|
|
|
} elseif ($session > 0) { |
|
4818
|
|
|
$sql = 'SELECT u.id as uid FROM '.$table_user.' u |
|
4819
|
|
|
INNER JOIN '.$table_session_course_user.' sru |
|
4820
|
|
|
ON sru.user_id = u.id |
|
4821
|
|
|
WHERE |
|
4822
|
|
|
sru.c_id = '.$courseId.' AND |
|
4823
|
|
|
sru.status = '.SessionEntity::COURSE_COACH; |
|
4824
|
|
|
$rs = Database::query($sql); |
|
4825
|
|
|
if (Database::num_rows($rs) > 0) { |
|
4826
|
|
|
$row = Database::fetch_assoc($rs); |
|
4827
|
|
|
|
|
4828
|
|
|
return (int) $row['uid']; |
|
4829
|
|
|
} |
|
4830
|
|
|
} |
|
4831
|
|
|
|
|
4832
|
|
|
return 0; |
|
4833
|
|
|
} |
|
4834
|
|
|
|
|
4835
|
|
|
/** |
|
4836
|
|
|
* Determines if a user is a gradebook certified. |
|
4837
|
|
|
* |
|
4838
|
|
|
* @param int $cat_id The category id of gradebook |
|
4839
|
|
|
* @param int $user_id The user id |
|
4840
|
|
|
* |
|
4841
|
|
|
* @return bool |
|
4842
|
|
|
*/ |
|
4843
|
|
|
public static function is_user_certified($cat_id, $user_id) |
|
4844
|
|
|
{ |
|
4845
|
|
|
$cat_id = (int) $cat_id; |
|
4846
|
|
|
$user_id = (int) $user_id; |
|
4847
|
|
|
|
|
4848
|
|
|
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE); |
|
4849
|
|
|
$sql = 'SELECT path_certificate |
|
4850
|
|
|
FROM '.$table.' |
|
4851
|
|
|
WHERE |
|
4852
|
|
|
cat_id = "'.$cat_id.'" AND |
|
4853
|
|
|
user_id = "'.$user_id.'"'; |
|
4854
|
|
|
$rs = Database::query($sql); |
|
4855
|
|
|
$row = Database::fetch_array($rs); |
|
4856
|
|
|
|
|
4857
|
|
|
if (!isset($row['path_certificate']) || '' == $row['path_certificate'] || is_null($row['path_certificate'])) { |
|
4858
|
|
|
return false; |
|
4859
|
|
|
} |
|
4860
|
|
|
|
|
4861
|
|
|
return true; |
|
4862
|
|
|
} |
|
4863
|
|
|
|
|
4864
|
|
|
/** |
|
4865
|
|
|
* Gets the info about a gradebook certificate for a user by course. |
|
4866
|
|
|
* |
|
4867
|
|
|
* @param array $course_info The course code |
|
4868
|
|
|
* @param int $session_id |
|
4869
|
|
|
* @param int $user_id The user id |
|
4870
|
|
|
* |
|
4871
|
|
|
* @return array if there is not information return false |
|
4872
|
|
|
*/ |
|
4873
|
|
|
public static function get_info_gradebook_certificate($course_info, $session_id, $user_id) |
|
4874
|
|
|
{ |
|
4875
|
|
|
$tbl_grade_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE); |
|
4876
|
|
|
$tbl_grade_category = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY); |
|
4877
|
|
|
$session_id = (int) $session_id; |
|
4878
|
|
|
$user_id = (int) $user_id; |
|
4879
|
|
|
$courseId = $course_info['real_id']; |
|
4880
|
|
|
|
|
4881
|
|
|
if (empty($session_id)) { |
|
4882
|
|
|
$session_condition = ' AND (session_id = "" OR session_id = 0 OR session_id IS NULL )'; |
|
4883
|
|
|
} else { |
|
4884
|
|
|
$session_condition = " AND session_id = $session_id"; |
|
4885
|
|
|
} |
|
4886
|
|
|
|
|
4887
|
|
|
$sql = 'SELECT * FROM '.$tbl_grade_certificate.' |
|
4888
|
|
|
WHERE cat_id = ( |
|
4889
|
|
|
SELECT id FROM '.$tbl_grade_category.' |
|
4890
|
|
|
WHERE |
|
4891
|
|
|
c_id = "'.$courseId.'" '.$session_condition.' |
|
4892
|
|
|
LIMIT 1 |
|
4893
|
|
|
) AND user_id='.$user_id; |
|
4894
|
|
|
|
|
4895
|
|
|
$rs = Database::query($sql); |
|
4896
|
|
|
if (Database::num_rows($rs) > 0) { |
|
4897
|
|
|
$row = Database::fetch_assoc($rs); |
|
4898
|
|
|
$score = $row['score_certificate']; |
|
4899
|
|
|
$category_id = $row['cat_id']; |
|
4900
|
|
|
$cat = Category::load($category_id); |
|
4901
|
|
|
$displayscore = ScoreDisplay::instance(); |
|
4902
|
|
|
if (isset($cat) && $displayscore->is_custom()) { |
|
4903
|
|
|
$grade = $displayscore->display_score( |
|
4904
|
|
|
[$score, $cat[0]->get_weight()], |
|
4905
|
|
|
SCORE_DIV_PERCENT_WITH_CUSTOM |
|
4906
|
|
|
); |
|
4907
|
|
|
} else { |
|
4908
|
|
|
$grade = $displayscore->display_score( |
|
4909
|
|
|
[$score, $cat[0]->get_weight()] |
|
4910
|
|
|
); |
|
4911
|
|
|
} |
|
4912
|
|
|
$row['grade'] = $grade; |
|
4913
|
|
|
|
|
4914
|
|
|
return $row; |
|
|
|
|
|
|
4915
|
|
|
} |
|
4916
|
|
|
|
|
4917
|
|
|
return false; |
|
4918
|
|
|
} |
|
4919
|
|
|
|
|
4920
|
|
|
/** |
|
4921
|
|
|
* This function check if the user is a coach inside session course. |
|
4922
|
|
|
* |
|
4923
|
|
|
* @param int $user_id User id |
|
4924
|
|
|
* @param int $courseId |
|
4925
|
|
|
* @param int $session_id |
|
4926
|
|
|
* |
|
4927
|
|
|
* @return bool True if the user is a coach |
|
4928
|
|
|
*/ |
|
4929
|
|
|
public static function is_session_course_coach($user_id, $courseId, $session_id) |
|
4930
|
|
|
{ |
|
4931
|
|
|
$table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
|
4932
|
|
|
// Protect data |
|
4933
|
|
|
$user_id = intval($user_id); |
|
4934
|
|
|
$courseId = intval($courseId); |
|
4935
|
|
|
$session_id = intval($session_id); |
|
4936
|
|
|
$result = false; |
|
4937
|
|
|
|
|
4938
|
|
|
$sql = "SELECT session_id FROM $table |
|
4939
|
|
|
WHERE |
|
4940
|
|
|
session_id = $session_id AND |
|
4941
|
|
|
c_id = $courseId AND |
|
4942
|
|
|
user_id = $user_id AND |
|
4943
|
|
|
status = ".SessionEntity::COURSE_COACH; |
|
4944
|
|
|
$res = Database::query($sql); |
|
4945
|
|
|
|
|
4946
|
|
|
if (Database::num_rows($res) > 0) { |
|
4947
|
|
|
$result = true; |
|
4948
|
|
|
} |
|
4949
|
|
|
|
|
4950
|
|
|
return $result; |
|
4951
|
|
|
} |
|
4952
|
|
|
|
|
4953
|
|
|
/** |
|
4954
|
|
|
* This function returns an icon path that represents the favicon of the website of which the url given. |
|
4955
|
|
|
* Defaults to the current Chamilo favicon. |
|
4956
|
|
|
* |
|
4957
|
|
|
* @param string $url1 URL of website where to look for favicon.ico |
|
4958
|
|
|
* @param string $url2 Optional second URL of website where to look for favicon.ico |
|
4959
|
|
|
* |
|
4960
|
|
|
* @return string Path of icon to load |
|
4961
|
|
|
*/ |
|
4962
|
|
|
public static function get_favicon_from_url($url1, $url2 = null) |
|
4963
|
|
|
{ |
|
4964
|
|
|
$icon_link = ''; |
|
4965
|
|
|
$url = $url1; |
|
4966
|
|
|
if (empty($url1)) { |
|
4967
|
|
|
$url = $url2; |
|
4968
|
|
|
if (empty($url)) { |
|
4969
|
|
|
$url = api_get_access_url(api_get_current_access_url_id()); |
|
4970
|
|
|
$url = $url[0]; |
|
4971
|
|
|
} |
|
4972
|
|
|
} |
|
4973
|
|
|
if (!empty($url)) { |
|
4974
|
|
|
$pieces = parse_url($url); |
|
4975
|
|
|
$icon_link = $pieces['scheme'].'://'.$pieces['host'].'/favicon.ico'; |
|
4976
|
|
|
} |
|
4977
|
|
|
|
|
4978
|
|
|
return $icon_link; |
|
4979
|
|
|
} |
|
4980
|
|
|
|
|
4981
|
|
|
public static function addUserAsAdmin(User $user) |
|
4982
|
|
|
{ |
|
4983
|
|
|
$userId = $user->getId(); |
|
4984
|
|
|
|
|
4985
|
|
|
if (!self::is_admin($userId)) { |
|
4986
|
|
|
$table = Database::get_main_table(TABLE_MAIN_ADMIN); |
|
4987
|
|
|
$sql = "INSERT INTO $table SET user_id = $userId"; |
|
4988
|
|
|
Database::query($sql); |
|
4989
|
|
|
} |
|
4990
|
|
|
|
|
4991
|
|
|
$user->addRole('ROLE_ADMIN'); |
|
4992
|
|
|
self::getRepository()->updateUser($user, true); |
|
4993
|
|
|
} |
|
4994
|
|
|
|
|
4995
|
|
|
public static function removeUserAdmin(User $user) |
|
4996
|
|
|
{ |
|
4997
|
|
|
$userId = (int) $user->getId(); |
|
4998
|
|
|
if (self::is_admin($userId)) { |
|
4999
|
|
|
$table = Database::get_main_table(TABLE_MAIN_ADMIN); |
|
5000
|
|
|
$sql = "DELETE FROM $table WHERE user_id = $userId"; |
|
5001
|
|
|
Database::query($sql); |
|
5002
|
|
|
$user->removeRole('ROLE_ADMIN'); |
|
5003
|
|
|
self::getRepository()->updateUser($user, true); |
|
5004
|
|
|
} |
|
5005
|
|
|
} |
|
5006
|
|
|
|
|
5007
|
|
|
/** |
|
5008
|
|
|
* @param string $from |
|
5009
|
|
|
* @param string $to |
|
5010
|
|
|
*/ |
|
5011
|
|
|
public static function update_all_user_languages($from, $to) |
|
5012
|
|
|
{ |
|
5013
|
|
|
$table_user = Database::get_main_table(TABLE_MAIN_USER); |
|
5014
|
|
|
$from = Database::escape_string($from); |
|
5015
|
|
|
$to = Database::escape_string($to); |
|
5016
|
|
|
|
|
5017
|
|
|
if (!empty($to) && !empty($from)) { |
|
5018
|
|
|
$sql = "UPDATE $table_user SET language = '$to' |
|
5019
|
|
|
WHERE language = '$from'"; |
|
5020
|
|
|
Database::query($sql); |
|
5021
|
|
|
} |
|
5022
|
|
|
} |
|
5023
|
|
|
|
|
5024
|
|
|
/** |
|
5025
|
|
|
* Subscribe boss to students. |
|
5026
|
|
|
* |
|
5027
|
|
|
* @param int $bossId The boss id |
|
5028
|
|
|
* @param array $usersId The users array |
|
5029
|
|
|
* @param bool $deleteOtherAssignedUsers |
|
5030
|
|
|
*/ |
|
5031
|
|
|
public static function subscribeBossToUsers($bossId, $usersId, $deleteOtherAssignedUsers = true): void |
|
5032
|
|
|
{ |
|
5033
|
|
|
self::subscribeUsersToUser( |
|
5034
|
|
|
$bossId, |
|
5035
|
|
|
$usersId, |
|
5036
|
|
|
UserRelUser::USER_RELATION_TYPE_BOSS, |
|
5037
|
|
|
false, |
|
5038
|
|
|
$deleteOtherAssignedUsers |
|
5039
|
|
|
); |
|
5040
|
|
|
} |
|
5041
|
|
|
|
|
5042
|
|
|
/** |
|
5043
|
|
|
* @param int $userId |
|
5044
|
|
|
* |
|
5045
|
|
|
* @return bool |
|
5046
|
|
|
*/ |
|
5047
|
|
|
public static function removeAllBossFromStudent($userId) |
|
5048
|
|
|
{ |
|
5049
|
|
|
$userId = (int) $userId; |
|
5050
|
|
|
|
|
5051
|
|
|
if (empty($userId)) { |
|
5052
|
|
|
return false; |
|
5053
|
|
|
} |
|
5054
|
|
|
|
|
5055
|
|
|
$userRelUserTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
|
5056
|
|
|
$sql = "DELETE FROM $userRelUserTable |
|
5057
|
|
|
WHERE user_id = $userId AND relation_type = ".UserRelUser::USER_RELATION_TYPE_BOSS; |
|
5058
|
|
|
Database::query($sql); |
|
5059
|
|
|
|
|
5060
|
|
|
return true; |
|
5061
|
|
|
} |
|
5062
|
|
|
|
|
5063
|
|
|
/** |
|
5064
|
|
|
* Subscribe boss to students, if $bossList is empty then the boss list will be empty too. |
|
5065
|
|
|
* |
|
5066
|
|
|
* @param int $studentId |
|
5067
|
|
|
* @param array $bossList |
|
5068
|
|
|
* @param bool $sendNotification |
|
5069
|
|
|
* |
|
5070
|
|
|
* @return mixed Affected rows or false on failure |
|
5071
|
|
|
*/ |
|
5072
|
|
|
public static function subscribeUserToBossList( |
|
5073
|
|
|
$studentId, |
|
5074
|
|
|
$bossList, |
|
5075
|
|
|
$sendNotification = false |
|
5076
|
|
|
) { |
|
5077
|
|
|
$inserted = 0; |
|
5078
|
|
|
if (!empty($bossList)) { |
|
5079
|
|
|
sort($bossList); |
|
5080
|
|
|
$studentId = (int) $studentId; |
|
5081
|
|
|
$studentInfo = api_get_user_info($studentId); |
|
5082
|
|
|
|
|
5083
|
|
|
if (empty($studentInfo)) { |
|
5084
|
|
|
return false; |
|
5085
|
|
|
} |
|
5086
|
|
|
|
|
5087
|
|
|
$previousBossList = self::getStudentBossList($studentId); |
|
5088
|
|
|
$previousBossList = !empty($previousBossList) ? array_column($previousBossList, 'boss_id') : []; |
|
5089
|
|
|
sort($previousBossList); |
|
5090
|
|
|
|
|
5091
|
|
|
// Boss list is the same, nothing changed. |
|
5092
|
|
|
if ($bossList == $previousBossList) { |
|
5093
|
|
|
return false; |
|
5094
|
|
|
} |
|
5095
|
|
|
|
|
5096
|
|
|
$userRelUserTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
|
5097
|
|
|
self::removeAllBossFromStudent($studentId); |
|
5098
|
|
|
|
|
5099
|
|
|
foreach ($bossList as $bossId) { |
|
5100
|
|
|
$bossId = (int) $bossId; |
|
5101
|
|
|
$bossInfo = api_get_user_info($bossId); |
|
5102
|
|
|
|
|
5103
|
|
|
if (empty($bossInfo)) { |
|
5104
|
|
|
continue; |
|
5105
|
|
|
} |
|
5106
|
|
|
|
|
5107
|
|
|
$bossLanguage = $bossInfo['locale']; |
|
5108
|
|
|
$sql = "INSERT IGNORE INTO $userRelUserTable (user_id, friend_user_id, relation_type) |
|
5109
|
|
|
VALUES ($studentId, $bossId, ".UserRelUser::USER_RELATION_TYPE_BOSS.")"; |
|
5110
|
|
|
$insertId = Database::query($sql); |
|
5111
|
|
|
|
|
5112
|
|
|
if ($insertId) { |
|
5113
|
|
|
if ($sendNotification) { |
|
5114
|
|
|
$name = $studentInfo['complete_name']; |
|
5115
|
|
|
$url = api_get_path(WEB_CODE_PATH).'my_space/myStudents.php?student='.$studentId; |
|
5116
|
|
|
$url = Display::url($url, $url); |
|
5117
|
|
|
$subject = sprintf(get_lang('You have been assigned the learner %s', $bossLanguage), $name); |
|
5118
|
|
|
$message = sprintf(get_lang('You have been assigned the learner %s with url %s', $bossLanguage), $name, $url); |
|
5119
|
|
|
MessageManager::send_message_simple( |
|
5120
|
|
|
$bossId, |
|
5121
|
|
|
$subject, |
|
5122
|
|
|
$message |
|
5123
|
|
|
); |
|
5124
|
|
|
} |
|
5125
|
|
|
$inserted++; |
|
5126
|
|
|
} |
|
5127
|
|
|
} |
|
5128
|
|
|
} else { |
|
5129
|
|
|
self::removeAllBossFromStudent($studentId); |
|
5130
|
|
|
} |
|
5131
|
|
|
|
|
5132
|
|
|
return $inserted; |
|
5133
|
|
|
} |
|
5134
|
|
|
|
|
5135
|
|
|
/** |
|
5136
|
|
|
* Get users followed by student boss. |
|
5137
|
|
|
* |
|
5138
|
|
|
* @param int $userId |
|
5139
|
|
|
* @param int $userStatus (STUDENT, COURSEMANAGER, etc) |
|
5140
|
|
|
* @param bool $getOnlyUserId |
|
5141
|
|
|
* @param bool $getSql |
|
5142
|
|
|
* @param bool $getCount |
|
5143
|
|
|
* @param int $from |
|
5144
|
|
|
* @param int $numberItems |
|
5145
|
|
|
* @param int $column |
|
5146
|
|
|
* @param string $direction |
|
5147
|
|
|
* @param int $active |
|
5148
|
|
|
* @param string $lastConnectionDate |
|
5149
|
|
|
* |
|
5150
|
|
|
* @return array users |
|
5151
|
|
|
*/ |
|
5152
|
|
|
public static function getUsersFollowedByStudentBoss( |
|
5153
|
|
|
$userId, |
|
5154
|
|
|
$userStatus = 0, |
|
5155
|
|
|
$getOnlyUserId = false, |
|
5156
|
|
|
$getSql = false, |
|
5157
|
|
|
$getCount = false, |
|
5158
|
|
|
$from = null, |
|
5159
|
|
|
$numberItems = null, |
|
5160
|
|
|
$column = null, |
|
5161
|
|
|
$direction = null, |
|
5162
|
|
|
$active = null, |
|
5163
|
|
|
$lastConnectionDate = null |
|
5164
|
|
|
) { |
|
5165
|
|
|
return self::getUsersFollowedByUser( |
|
|
|
|
|
|
5166
|
|
|
$userId, |
|
5167
|
|
|
$userStatus, |
|
5168
|
|
|
$getOnlyUserId, |
|
5169
|
|
|
$getSql, |
|
5170
|
|
|
$getCount, |
|
5171
|
|
|
$from, |
|
5172
|
|
|
$numberItems, |
|
5173
|
|
|
$column, |
|
5174
|
|
|
$direction, |
|
5175
|
|
|
$active, |
|
5176
|
|
|
$lastConnectionDate, |
|
5177
|
|
|
STUDENT_BOSS |
|
5178
|
|
|
); |
|
5179
|
|
|
} |
|
5180
|
|
|
|
|
5181
|
|
|
/** |
|
5182
|
|
|
* @return array |
|
5183
|
|
|
*/ |
|
5184
|
|
|
public static function getOfficialCodeGrouped() |
|
5185
|
|
|
{ |
|
5186
|
|
|
$user = Database::get_main_table(TABLE_MAIN_USER); |
|
5187
|
|
|
$sql = "SELECT DISTINCT official_code |
|
5188
|
|
|
FROM $user |
|
5189
|
|
|
GROUP BY official_code"; |
|
5190
|
|
|
$result = Database::query($sql); |
|
5191
|
|
|
$values = Database::store_result($result, 'ASSOC'); |
|
5192
|
|
|
$result = []; |
|
5193
|
|
|
foreach ($values as $value) { |
|
5194
|
|
|
$result[$value['official_code']] = $value['official_code']; |
|
5195
|
|
|
} |
|
5196
|
|
|
|
|
5197
|
|
|
return $result; |
|
5198
|
|
|
} |
|
5199
|
|
|
|
|
5200
|
|
|
/** |
|
5201
|
|
|
* @param string $officialCode |
|
5202
|
|
|
* |
|
5203
|
|
|
* @return array |
|
5204
|
|
|
*/ |
|
5205
|
|
|
public static function getUsersByOfficialCode($officialCode) |
|
5206
|
|
|
{ |
|
5207
|
|
|
$user = Database::get_main_table(TABLE_MAIN_USER); |
|
5208
|
|
|
$officialCode = Database::escape_string($officialCode); |
|
5209
|
|
|
|
|
5210
|
|
|
$sql = "SELECT DISTINCT id |
|
5211
|
|
|
FROM $user |
|
5212
|
|
|
WHERE official_code = '$officialCode' |
|
5213
|
|
|
"; |
|
5214
|
|
|
$result = Database::query($sql); |
|
5215
|
|
|
|
|
5216
|
|
|
$users = []; |
|
5217
|
|
|
while ($row = Database::fetch_array($result)) { |
|
5218
|
|
|
$users[] = $row['id']; |
|
5219
|
|
|
} |
|
5220
|
|
|
|
|
5221
|
|
|
return $users; |
|
5222
|
|
|
} |
|
5223
|
|
|
|
|
5224
|
|
|
/** |
|
5225
|
|
|
* Calc the expended time (in seconds) by a user in a course. |
|
5226
|
|
|
* |
|
5227
|
|
|
* @param int $userId The user id |
|
5228
|
|
|
* @param int $courseId The course id |
|
5229
|
|
|
* @param int $sessionId Optional. The session id |
|
5230
|
|
|
* @param string $from Optional. From date |
|
5231
|
|
|
* @param string $until Optional. Until date |
|
5232
|
|
|
* |
|
5233
|
|
|
* @return int The time |
|
5234
|
|
|
*/ |
|
5235
|
|
|
public static function getTimeSpentInCourses( |
|
5236
|
|
|
$userId, |
|
5237
|
|
|
$courseId, |
|
5238
|
|
|
$sessionId = 0, |
|
5239
|
|
|
$from = '', |
|
5240
|
|
|
$until = '' |
|
5241
|
|
|
) { |
|
5242
|
|
|
$userId = (int) $userId; |
|
5243
|
|
|
$sessionId = (int) $sessionId; |
|
5244
|
|
|
|
|
5245
|
|
|
$trackCourseAccessTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
|
5246
|
|
|
$whereConditions = [ |
|
5247
|
|
|
'user_id = ? ' => $userId, |
|
5248
|
|
|
'AND c_id = ? ' => $courseId, |
|
5249
|
|
|
'AND session_id = ? ' => $sessionId, |
|
5250
|
|
|
]; |
|
5251
|
|
|
|
|
5252
|
|
|
if (!empty($from) && !empty($until)) { |
|
5253
|
|
|
$whereConditions["AND (login_course_date >= '?' "] = $from; |
|
5254
|
|
|
$whereConditions["AND logout_course_date <= DATE_ADD('?', INTERVAL 1 DAY)) "] = $until; |
|
5255
|
|
|
} |
|
5256
|
|
|
|
|
5257
|
|
|
$trackResult = Database::select( |
|
5258
|
|
|
'SUM(UNIX_TIMESTAMP(logout_course_date) - UNIX_TIMESTAMP(login_course_date)) as total_time', |
|
5259
|
|
|
$trackCourseAccessTable, |
|
5260
|
|
|
[ |
|
5261
|
|
|
'where' => $whereConditions, |
|
5262
|
|
|
], |
|
5263
|
|
|
'first' |
|
5264
|
|
|
); |
|
5265
|
|
|
|
|
5266
|
|
|
if (false != $trackResult) { |
|
5267
|
|
|
return $trackResult['total_time'] ? $trackResult['total_time'] : 0; |
|
5268
|
|
|
} |
|
5269
|
|
|
|
|
5270
|
|
|
return 0; |
|
5271
|
|
|
} |
|
5272
|
|
|
|
|
5273
|
|
|
/** |
|
5274
|
|
|
* Get the boss user ID from a followed user id. |
|
5275
|
|
|
* |
|
5276
|
|
|
* @param $userId |
|
5277
|
|
|
* |
|
5278
|
|
|
* @return bool |
|
5279
|
|
|
*/ |
|
5280
|
|
|
public static function getFirstStudentBoss($userId) |
|
5281
|
|
|
{ |
|
5282
|
|
|
$userId = (int) $userId; |
|
5283
|
|
|
if ($userId > 0) { |
|
5284
|
|
|
$userRelTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
|
5285
|
|
|
$row = Database::select( |
|
5286
|
|
|
'DISTINCT friend_user_id AS boss_id', |
|
5287
|
|
|
$userRelTable, |
|
5288
|
|
|
[ |
|
5289
|
|
|
'where' => [ |
|
5290
|
|
|
'user_id = ? AND relation_type = ? LIMIT 1' => [ |
|
5291
|
|
|
$userId, |
|
5292
|
|
|
UserRelUser::USER_RELATION_TYPE_BOSS, |
|
5293
|
|
|
], |
|
5294
|
|
|
], |
|
5295
|
|
|
] |
|
5296
|
|
|
); |
|
5297
|
|
|
if (!empty($row)) { |
|
5298
|
|
|
return $row[0]['boss_id']; |
|
5299
|
|
|
} |
|
5300
|
|
|
} |
|
5301
|
|
|
|
|
5302
|
|
|
return false; |
|
5303
|
|
|
} |
|
5304
|
|
|
|
|
5305
|
|
|
/** |
|
5306
|
|
|
* Get the boss user ID from a followed user id. |
|
5307
|
|
|
* |
|
5308
|
|
|
* @param int $userId student id |
|
5309
|
|
|
* |
|
5310
|
|
|
* @return array |
|
5311
|
|
|
*/ |
|
5312
|
|
|
public static function getStudentBossList($userId) |
|
5313
|
|
|
{ |
|
5314
|
|
|
$userId = (int) $userId; |
|
5315
|
|
|
|
|
5316
|
|
|
if ($userId > 0) { |
|
5317
|
|
|
$userRelTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
|
5318
|
|
|
|
|
5319
|
|
|
return Database::select( |
|
5320
|
|
|
'DISTINCT friend_user_id AS boss_id', |
|
5321
|
|
|
$userRelTable, |
|
5322
|
|
|
[ |
|
5323
|
|
|
'where' => [ |
|
5324
|
|
|
'user_id = ? AND relation_type = ? ' => [ |
|
5325
|
|
|
$userId, |
|
5326
|
|
|
UserRelUser::USER_RELATION_TYPE_BOSS, |
|
5327
|
|
|
], |
|
5328
|
|
|
], |
|
5329
|
|
|
] |
|
5330
|
|
|
); |
|
5331
|
|
|
} |
|
5332
|
|
|
|
|
5333
|
|
|
return []; |
|
5334
|
|
|
} |
|
5335
|
|
|
|
|
5336
|
|
|
/** |
|
5337
|
|
|
* @param int $bossId |
|
5338
|
|
|
* @param int $studentId |
|
5339
|
|
|
* |
|
5340
|
|
|
* @return bool |
|
5341
|
|
|
*/ |
|
5342
|
|
|
public static function userIsBossOfStudent($bossId, $studentId) |
|
5343
|
|
|
{ |
|
5344
|
|
|
$result = false; |
|
5345
|
|
|
$bossList = self::getStudentBossList($studentId); |
|
5346
|
|
|
if (!empty($bossList)) { |
|
5347
|
|
|
$bossList = array_column($bossList, 'boss_id'); |
|
5348
|
|
|
if (in_array($bossId, $bossList)) { |
|
5349
|
|
|
$result = true; |
|
5350
|
|
|
} |
|
5351
|
|
|
} |
|
5352
|
|
|
|
|
5353
|
|
|
return $result; |
|
5354
|
|
|
} |
|
5355
|
|
|
|
|
5356
|
|
|
/** |
|
5357
|
|
|
* Displays the name of the user and makes the link to the user profile. |
|
5358
|
|
|
* |
|
5359
|
|
|
* @param array $userInfo |
|
5360
|
|
|
* |
|
5361
|
|
|
* @return string |
|
5362
|
|
|
*/ |
|
5363
|
|
|
public static function getUserProfileLink($userInfo) |
|
5364
|
|
|
{ |
|
5365
|
|
|
if (isset($userInfo) && isset($userInfo['user_id'])) { |
|
5366
|
|
|
return Display::url( |
|
5367
|
|
|
$userInfo['complete_name_with_username'], |
|
5368
|
|
|
$userInfo['profile_url'] |
|
5369
|
|
|
); |
|
5370
|
|
|
} |
|
5371
|
|
|
|
|
5372
|
|
|
return get_lang('Anonymous'); |
|
5373
|
|
|
} |
|
5374
|
|
|
|
|
5375
|
|
|
/** |
|
5376
|
|
|
* Get users whose name matches $firstname and $lastname. |
|
5377
|
|
|
* |
|
5378
|
|
|
* @param string $firstname Firstname to search |
|
5379
|
|
|
* @param string $lastname Lastname to search |
|
5380
|
|
|
* |
|
5381
|
|
|
* @return array The user list |
|
5382
|
|
|
*/ |
|
5383
|
|
|
public static function getUsersByName($firstname, $lastname) |
|
5384
|
|
|
{ |
|
5385
|
|
|
$firstname = Database::escape_string($firstname); |
|
5386
|
|
|
$lastname = Database::escape_string($lastname); |
|
5387
|
|
|
$userTable = Database::get_main_table(TABLE_MAIN_USER); |
|
5388
|
|
|
|
|
5389
|
|
|
$sql = <<<SQL |
|
5390
|
|
|
SELECT id, username, lastname, firstname |
|
5391
|
|
|
FROM $userTable |
|
5392
|
|
|
WHERE |
|
5393
|
|
|
firstname LIKE '$firstname%' AND |
|
5394
|
|
|
lastname LIKE '$lastname%' |
|
5395
|
|
|
SQL; |
|
5396
|
|
|
$result = Database::query($sql); |
|
5397
|
|
|
$users = []; |
|
5398
|
|
|
while ($resultData = Database::fetch_object($result)) { |
|
5399
|
|
|
$users[] = $resultData; |
|
5400
|
|
|
} |
|
5401
|
|
|
|
|
5402
|
|
|
return $users; |
|
5403
|
|
|
} |
|
5404
|
|
|
|
|
5405
|
|
|
/** |
|
5406
|
|
|
* @param int $optionSelected |
|
5407
|
|
|
* |
|
5408
|
|
|
* @return string |
|
5409
|
|
|
*/ |
|
5410
|
|
|
public static function getUserSubscriptionTab($optionSelected = 1) |
|
5411
|
|
|
{ |
|
5412
|
|
|
$allowAdmin = api_get_setting('workflows.allow_user_course_subscription_by_course_admin'); |
|
5413
|
|
|
if (('true' === $allowAdmin && api_is_allowed_to_edit()) || |
|
5414
|
|
|
api_is_platform_admin() |
|
5415
|
|
|
) { |
|
5416
|
|
|
$userPath = api_get_path(WEB_CODE_PATH).'user/'; |
|
5417
|
|
|
|
|
5418
|
|
|
$headers = [ |
|
5419
|
|
|
[ |
|
5420
|
|
|
'url' => $userPath.'user.php?'.api_get_cidreq().'&type='.STUDENT, |
|
5421
|
|
|
'content' => get_lang('Learners'), |
|
5422
|
|
|
], |
|
5423
|
|
|
[ |
|
5424
|
|
|
'url' => $userPath.'user.php?'.api_get_cidreq().'&type='.COURSEMANAGER, |
|
5425
|
|
|
'content' => get_lang('Trainers'), |
|
5426
|
|
|
], |
|
5427
|
|
|
/*[ |
|
5428
|
|
|
'url' => $userPath.'subscribe_user.php?'.api_get_cidreq(), |
|
5429
|
|
|
'content' => get_lang('Learners'), |
|
5430
|
|
|
], |
|
5431
|
|
|
[ |
|
5432
|
|
|
'url' => $userPath.'subscribe_user.php?type=teacher&'.api_get_cidreq(), |
|
5433
|
|
|
'content' => get_lang('Trainers'), |
|
5434
|
|
|
],*/ |
|
5435
|
|
|
[ |
|
5436
|
|
|
'url' => api_get_path(WEB_CODE_PATH).'group/group.php?'.api_get_cidreq(), |
|
5437
|
|
|
'content' => get_lang('Groups'), |
|
5438
|
|
|
], |
|
5439
|
|
|
[ |
|
5440
|
|
|
'url' => $userPath.'class.php?'.api_get_cidreq(), |
|
5441
|
|
|
'content' => get_lang('Classes'), |
|
5442
|
|
|
], |
|
5443
|
|
|
]; |
|
5444
|
|
|
|
|
5445
|
|
|
return Display::tabsOnlyLink($headers, $optionSelected); |
|
5446
|
|
|
} |
|
5447
|
|
|
|
|
5448
|
|
|
return ''; |
|
5449
|
|
|
} |
|
5450
|
|
|
|
|
5451
|
|
|
/** |
|
5452
|
|
|
* Make sure this function is protected because it does NOT check password! |
|
5453
|
|
|
* |
|
5454
|
|
|
* This function defines globals. |
|
5455
|
|
|
* |
|
5456
|
|
|
* @param int $userId |
|
5457
|
|
|
* @param bool $checkIfUserCanLoginAs |
|
5458
|
|
|
* |
|
5459
|
|
|
* @return bool |
|
5460
|
|
|
* |
|
5461
|
|
|
* @author Evie Embrechts |
|
5462
|
|
|
* @author Yannick Warnier <[email protected]> |
|
5463
|
|
|
*/ |
|
5464
|
|
|
public static function loginAsUser($userId, $checkIfUserCanLoginAs = true) |
|
5465
|
|
|
{ |
|
5466
|
|
|
$userId = (int) $userId; |
|
5467
|
|
|
$userInfo = api_get_user_info($userId); |
|
5468
|
|
|
|
|
5469
|
|
|
// Check if the user is allowed to 'login_as' |
|
5470
|
|
|
$canLoginAs = true; |
|
5471
|
|
|
if ($checkIfUserCanLoginAs) { |
|
5472
|
|
|
$canLoginAs = api_can_login_as($userId); |
|
5473
|
|
|
} |
|
5474
|
|
|
|
|
5475
|
|
|
if (!$canLoginAs || empty($userInfo)) { |
|
5476
|
|
|
return false; |
|
5477
|
|
|
} |
|
5478
|
|
|
|
|
5479
|
|
|
if ($userId) { |
|
5480
|
|
|
Event::registerLog([ |
|
|
|
|
|
|
5481
|
|
|
'tool' => 'logout', |
|
5482
|
|
|
'tool_id' => 0, |
|
5483
|
|
|
'tool_id_detail' => 0, |
|
5484
|
|
|
'action' => '', |
|
5485
|
|
|
'info' => 'Change user (login as)', |
|
5486
|
|
|
]); |
|
5487
|
|
|
|
|
5488
|
|
|
// Logout current user |
|
5489
|
|
|
self::loginDelete(api_get_user_id()); |
|
5490
|
|
|
|
|
5491
|
|
|
return true; |
|
5492
|
|
|
} |
|
5493
|
|
|
|
|
5494
|
|
|
return false; |
|
5495
|
|
|
} |
|
5496
|
|
|
|
|
5497
|
|
|
/** |
|
5498
|
|
|
* Remove all login records from the track_e_online stats table, |
|
5499
|
|
|
* for the given user ID. |
|
5500
|
|
|
* |
|
5501
|
|
|
* @param int $userId User ID |
|
5502
|
|
|
*/ |
|
5503
|
|
|
public static function loginDelete($userId) |
|
5504
|
|
|
{ |
|
5505
|
|
|
$online_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE); |
|
5506
|
|
|
$userId = (int) $userId; |
|
5507
|
|
|
$query = "DELETE FROM $online_table WHERE login_user_id = $userId"; |
|
5508
|
|
|
Database::query($query); |
|
5509
|
|
|
} |
|
5510
|
|
|
|
|
5511
|
|
|
/** |
|
5512
|
|
|
* Login as first admin user registered in the platform. |
|
5513
|
|
|
* |
|
5514
|
|
|
* @return array |
|
5515
|
|
|
*/ |
|
5516
|
|
|
public static function logInAsFirstAdmin() |
|
5517
|
|
|
{ |
|
5518
|
|
|
$adminList = self::get_all_administrators(); |
|
5519
|
|
|
|
|
5520
|
|
|
if (!empty($adminList)) { |
|
5521
|
|
|
$userInfo = current($adminList); |
|
5522
|
|
|
if (!empty($userInfo)) { |
|
5523
|
|
|
$result = self::loginAsUser($userInfo['user_id'], false); |
|
5524
|
|
|
if ($result && api_is_platform_admin()) { |
|
5525
|
|
|
return api_get_user_info(); |
|
|
|
|
|
|
5526
|
|
|
} |
|
5527
|
|
|
} |
|
5528
|
|
|
} |
|
5529
|
|
|
|
|
5530
|
|
|
return []; |
|
5531
|
|
|
} |
|
5532
|
|
|
|
|
5533
|
|
|
/** |
|
5534
|
|
|
* Check if user is teacher of a student based in their courses. |
|
5535
|
|
|
* |
|
5536
|
|
|
* @param $teacherId |
|
5537
|
|
|
* @param $studentId |
|
5538
|
|
|
* |
|
5539
|
|
|
* @return array |
|
5540
|
|
|
*/ |
|
5541
|
|
|
public static function getCommonCoursesBetweenTeacherAndStudent($teacherId, $studentId) |
|
5542
|
|
|
{ |
|
5543
|
|
|
$courses = CourseManager::getCoursesFollowedByUser( |
|
5544
|
|
|
$teacherId, |
|
5545
|
|
|
COURSEMANAGER |
|
5546
|
|
|
); |
|
5547
|
|
|
if (empty($courses)) { |
|
5548
|
|
|
return false; |
|
5549
|
|
|
} |
|
5550
|
|
|
|
|
5551
|
|
|
$coursesFromUser = CourseManager::get_courses_list_by_user_id($studentId); |
|
5552
|
|
|
if (empty($coursesFromUser)) { |
|
5553
|
|
|
return false; |
|
5554
|
|
|
} |
|
5555
|
|
|
|
|
5556
|
|
|
$coursesCodeList = array_column($courses, 'code'); |
|
5557
|
|
|
$coursesCodeFromUserList = array_column($coursesFromUser, 'code'); |
|
5558
|
|
|
$commonCourses = array_intersect($coursesCodeList, $coursesCodeFromUserList); |
|
5559
|
|
|
$commonCourses = array_filter($commonCourses); |
|
5560
|
|
|
|
|
5561
|
|
|
if (!empty($commonCourses)) { |
|
5562
|
|
|
return $commonCourses; |
|
5563
|
|
|
} |
|
5564
|
|
|
|
|
5565
|
|
|
return []; |
|
5566
|
|
|
} |
|
5567
|
|
|
|
|
5568
|
|
|
/** |
|
5569
|
|
|
* @param int $teacherId |
|
5570
|
|
|
* @param int $studentId |
|
5571
|
|
|
* |
|
5572
|
|
|
* @return bool |
|
5573
|
|
|
*/ |
|
5574
|
|
|
public static function isTeacherOfStudent($teacherId, $studentId) |
|
5575
|
|
|
{ |
|
5576
|
|
|
$courses = self::getCommonCoursesBetweenTeacherAndStudent( |
|
5577
|
|
|
$teacherId, |
|
5578
|
|
|
$studentId |
|
5579
|
|
|
); |
|
5580
|
|
|
|
|
5581
|
|
|
if (!empty($courses)) { |
|
5582
|
|
|
return true; |
|
5583
|
|
|
} |
|
5584
|
|
|
|
|
5585
|
|
|
return false; |
|
5586
|
|
|
} |
|
5587
|
|
|
|
|
5588
|
|
|
/** |
|
5589
|
|
|
* Send user confirmation mail. |
|
5590
|
|
|
* |
|
5591
|
|
|
* @throws Exception |
|
5592
|
|
|
*/ |
|
5593
|
|
|
public static function sendUserConfirmationMail(User $user) |
|
5594
|
|
|
{ |
|
5595
|
|
|
$uniqueId = api_get_unique_id(); |
|
5596
|
|
|
$user->setConfirmationToken($uniqueId); |
|
5597
|
|
|
|
|
5598
|
|
|
Database::getManager()->persist($user); |
|
5599
|
|
|
Database::getManager()->flush(); |
|
5600
|
|
|
|
|
5601
|
|
|
$url = api_get_path(WEB_CODE_PATH).'auth/user_mail_confirmation.php?token='.$uniqueId; |
|
5602
|
|
|
|
|
5603
|
|
|
// Check if the user was originally set for an automated subscription to a course or session |
|
5604
|
|
|
$courseCodeToRedirect = Session::read('course_redirect'); |
|
5605
|
|
|
$sessionToRedirect = Session::read('session_redirect'); |
|
5606
|
|
|
if (!empty($courseCodeToRedirect)) { |
|
5607
|
|
|
$url .= '&c='.$courseCodeToRedirect; |
|
5608
|
|
|
} |
|
5609
|
|
|
if (!empty($sessionToRedirect)) { |
|
5610
|
|
|
$url .= '&s='.$sessionToRedirect; |
|
5611
|
|
|
} |
|
5612
|
|
|
$mailSubject = get_lang('Registration confirmation'); |
|
5613
|
|
|
$mailBody = get_lang('To complete your platform registration you need confirm your account by clicking the following link') |
|
5614
|
|
|
.PHP_EOL |
|
5615
|
|
|
.Display::url($url, $url); |
|
5616
|
|
|
|
|
5617
|
|
|
api_mail_html( |
|
5618
|
|
|
self::formatUserFullName($user), |
|
5619
|
|
|
$user->getEmail(), |
|
5620
|
|
|
$mailSubject, |
|
5621
|
|
|
$mailBody |
|
5622
|
|
|
); |
|
5623
|
|
|
Display::addFlash(Display::return_message(get_lang('Check your e-mail and follow the instructions.'))); |
|
5624
|
|
|
} |
|
5625
|
|
|
|
|
5626
|
|
|
/** |
|
5627
|
|
|
* Anonymize a user. Replace personal info by anonymous info. |
|
5628
|
|
|
* |
|
5629
|
|
|
* @param int $userId User id |
|
5630
|
|
|
* @param bool $deleteIP Whether to replace the IP address in logs tables by 127.0.0.1 or to leave as is |
|
5631
|
|
|
* |
|
5632
|
|
|
* @throws \Exception |
|
5633
|
|
|
* |
|
5634
|
|
|
* @return bool |
|
5635
|
|
|
* @assert (0) === false |
|
5636
|
|
|
*/ |
|
5637
|
|
|
public static function anonymize($userId, $deleteIP = true) |
|
5638
|
|
|
{ |
|
5639
|
|
|
global $debug; |
|
5640
|
|
|
|
|
5641
|
|
|
$userId = (int) $userId; |
|
5642
|
|
|
|
|
5643
|
|
|
if (empty($userId)) { |
|
5644
|
|
|
return false; |
|
5645
|
|
|
} |
|
5646
|
|
|
|
|
5647
|
|
|
$em = Database::getManager(); |
|
5648
|
|
|
$user = api_get_user_entity($userId); |
|
5649
|
|
|
$uniqueId = uniqid('anon', true); |
|
5650
|
|
|
$user |
|
5651
|
|
|
->setFirstname($uniqueId) |
|
5652
|
|
|
->setLastname($uniqueId) |
|
5653
|
|
|
->setBiography('') |
|
5654
|
|
|
->setAddress('') |
|
5655
|
|
|
//->setCurriculumItems(null) |
|
5656
|
|
|
->setDateOfBirth(null) |
|
5657
|
|
|
->setCompetences('') |
|
5658
|
|
|
->setDiplomas('') |
|
5659
|
|
|
->setOpenarea('') |
|
5660
|
|
|
->setTeach('') |
|
5661
|
|
|
->setProductions(null) |
|
5662
|
|
|
->setOpenid('') |
|
5663
|
|
|
->setEmailCanonical($uniqueId.'@example.com') |
|
5664
|
|
|
->setEmail($uniqueId.'@example.com') |
|
5665
|
|
|
->setUsername($uniqueId) |
|
5666
|
|
|
->setUsernameCanonical($uniqueId) |
|
5667
|
|
|
->setPhone('') |
|
5668
|
|
|
->setOfficialCode('') |
|
5669
|
|
|
; |
|
5670
|
|
|
|
|
5671
|
|
|
self::deleteUserPicture($userId); |
|
5672
|
|
|
self::cleanUserRequestsOfRemoval($userId); |
|
5673
|
|
|
|
|
5674
|
|
|
// The IP address is a border-case personal data, as it does |
|
5675
|
|
|
// not directly allow for personal identification (it is not |
|
5676
|
|
|
// a completely safe value in most countries - the IP could |
|
5677
|
|
|
// be used by neighbours and crackers) |
|
5678
|
|
|
if ($deleteIP) { |
|
5679
|
|
|
$substitute = '127.0.0.1'; |
|
5680
|
|
|
$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS); |
|
5681
|
|
|
$sql = "UPDATE $table set user_ip = '$substitute' WHERE access_user_id = $userId"; |
|
5682
|
|
|
$res = Database::query($sql); |
|
5683
|
|
|
if (false === $res && $debug > 0) { |
|
5684
|
|
|
error_log("Could not anonymize IP address for user $userId ($sql)"); |
|
5685
|
|
|
} |
|
5686
|
|
|
|
|
5687
|
|
|
$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
|
5688
|
|
|
$sql = "UPDATE $table set user_ip = '$substitute' WHERE user_id = $userId"; |
|
5689
|
|
|
$res = Database::query($sql); |
|
5690
|
|
|
if (false === $res && $debug > 0) { |
|
5691
|
|
|
error_log("Could not anonymize IP address for user $userId ($sql)"); |
|
5692
|
|
|
} |
|
5693
|
|
|
|
|
5694
|
|
|
$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
|
5695
|
|
|
$sql = "UPDATE $table SET user_ip = '$substitute' WHERE exe_user_id = $userId"; |
|
5696
|
|
|
$res = Database::query($sql); |
|
5697
|
|
|
if (false === $res && $debug > 0) { |
|
5698
|
|
|
error_log("Could not anonymize IP address for user $userId ($sql)"); |
|
5699
|
|
|
} |
|
5700
|
|
|
|
|
5701
|
|
|
$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN); |
|
5702
|
|
|
$sql = "UPDATE $table SET user_ip = '$substitute' WHERE login_user_id = $userId"; |
|
5703
|
|
|
$res = Database::query($sql); |
|
5704
|
|
|
if (false === $res && $debug > 0) { |
|
5705
|
|
|
error_log("Could not anonymize IP address for user $userId ($sql)"); |
|
5706
|
|
|
} |
|
5707
|
|
|
|
|
5708
|
|
|
$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE); |
|
5709
|
|
|
$sql = "UPDATE $table set user_ip = '$substitute' WHERE login_user_id = $userId"; |
|
5710
|
|
|
$res = Database::query($sql); |
|
5711
|
|
|
if (false === $res && $debug > 0) { |
|
5712
|
|
|
error_log("Could not anonymize IP address for user $userId ($sql)"); |
|
5713
|
|
|
} |
|
5714
|
|
|
|
|
5715
|
|
|
$table = Database::get_course_table(TABLE_WIKI); |
|
5716
|
|
|
$sql = "UPDATE $table set user_ip = '$substitute' WHERE user_id = $userId"; |
|
5717
|
|
|
$res = Database::query($sql); |
|
5718
|
|
|
if (false === $res && $debug > 0) { |
|
5719
|
|
|
error_log("Could not anonymize IP address for user $userId ($sql)"); |
|
5720
|
|
|
} |
|
5721
|
|
|
|
|
5722
|
|
|
$table = Database::get_main_table(TABLE_TICKET_MESSAGE); |
|
5723
|
|
|
$sql = "UPDATE $table set ip_address = '$substitute' WHERE sys_insert_user_id = $userId"; |
|
5724
|
|
|
$res = Database::query($sql); |
|
5725
|
|
|
if (false === $res && $debug > 0) { |
|
5726
|
|
|
error_log("Could not anonymize IP address for user $userId ($sql)"); |
|
5727
|
|
|
} |
|
5728
|
|
|
|
|
5729
|
|
|
$table = Database::get_course_table(TABLE_WIKI); |
|
5730
|
|
|
$sql = "UPDATE $table set user_ip = '$substitute' WHERE user_id = $userId"; |
|
5731
|
|
|
$res = Database::query($sql); |
|
5732
|
|
|
if (false === $res && $debug > 0) { |
|
5733
|
|
|
error_log("Could not anonymize IP address for user $userId ($sql)"); |
|
5734
|
|
|
} |
|
5735
|
|
|
} |
|
5736
|
|
|
|
|
5737
|
|
|
$extraFieldRepository = $em->getRepository(EntityExtraField::class); |
|
5738
|
|
|
$autoRemoveFields = $extraFieldRepository->findBy([ |
|
5739
|
|
|
'autoRemove' => 1, |
|
5740
|
|
|
'itemType' => EntityExtraField::USER_FIELD_TYPE |
|
5741
|
|
|
]); |
|
5742
|
|
|
|
|
5743
|
|
|
foreach ($autoRemoveFields as $field) { |
|
5744
|
|
|
$extraFieldValueRepository = $em->getRepository(EntityExtraFieldValues::class); |
|
5745
|
|
|
$extraFieldValue = $extraFieldValueRepository->findOneBy([ |
|
5746
|
|
|
'field' => $field, |
|
5747
|
|
|
'itemId' => $userId |
|
5748
|
|
|
]); |
|
5749
|
|
|
|
|
5750
|
|
|
if ($extraFieldValue) { |
|
5751
|
|
|
$em->remove($extraFieldValue); |
|
5752
|
|
|
} |
|
5753
|
|
|
} |
|
5754
|
|
|
|
|
5755
|
|
|
$em->persist($user); |
|
5756
|
|
|
$em->flush(); |
|
5757
|
|
|
Event::addEvent(LOG_USER_ANONYMIZE, LOG_USER_ID, $userId); |
|
5758
|
|
|
|
|
5759
|
|
|
return true; |
|
5760
|
|
|
} |
|
5761
|
|
|
|
|
5762
|
|
|
/** |
|
5763
|
|
|
* @param int $userId |
|
5764
|
|
|
* |
|
5765
|
|
|
* @throws Exception |
|
5766
|
|
|
* |
|
5767
|
|
|
* @return string |
|
5768
|
|
|
*/ |
|
5769
|
|
|
public static function anonymizeUserWithVerification($userId) |
|
5770
|
|
|
{ |
|
5771
|
|
|
$allowDelete = ('true' === api_get_setting('session.allow_delete_user_for_session_admin')); |
|
5772
|
|
|
|
|
5773
|
|
|
$message = ''; |
|
5774
|
|
|
if (api_is_platform_admin() || |
|
5775
|
|
|
($allowDelete && api_is_session_admin()) |
|
5776
|
|
|
) { |
|
5777
|
|
|
$userToUpdateInfo = api_get_user_info($userId); |
|
5778
|
|
|
$currentUserId = api_get_user_id(); |
|
5779
|
|
|
|
|
5780
|
|
|
if ($userToUpdateInfo && |
|
5781
|
|
|
api_global_admin_can_edit_admin($userId, null, $allowDelete) |
|
5782
|
|
|
) { |
|
5783
|
|
|
if ($userId != $currentUserId && |
|
5784
|
|
|
self::anonymize($userId) |
|
5785
|
|
|
) { |
|
5786
|
|
|
$message = Display::return_message( |
|
5787
|
|
|
sprintf(get_lang("User %s's information anonymized."), $userToUpdateInfo['complete_name_with_username']), |
|
5788
|
|
|
'confirmation' |
|
5789
|
|
|
); |
|
5790
|
|
|
} else { |
|
5791
|
|
|
$message = Display::return_message( |
|
5792
|
|
|
sprintf(get_lang("We could not anonymize user %s's information. Please try again or check the logs."), $userToUpdateInfo['complete_name_with_username']), |
|
5793
|
|
|
'error' |
|
5794
|
|
|
); |
|
5795
|
|
|
} |
|
5796
|
|
|
} else { |
|
5797
|
|
|
$message = Display::return_message( |
|
5798
|
|
|
sprintf(get_lang('You don\'t have permissions to anonymize user %s. You need the same permissions as to delete users.'), $userToUpdateInfo['complete_name_with_username']), |
|
5799
|
|
|
'error' |
|
5800
|
|
|
); |
|
5801
|
|
|
} |
|
5802
|
|
|
} |
|
5803
|
|
|
|
|
5804
|
|
|
return $message; |
|
5805
|
|
|
} |
|
5806
|
|
|
|
|
5807
|
|
|
/** |
|
5808
|
|
|
* @param int $userId |
|
5809
|
|
|
* |
|
5810
|
|
|
* @throws Exception |
|
5811
|
|
|
* |
|
5812
|
|
|
* @return string |
|
5813
|
|
|
*/ |
|
5814
|
|
|
public static function deleteUserWithVerification($userId, bool $destroy = false) |
|
5815
|
|
|
{ |
|
5816
|
|
|
$allowDelete = ('true' === api_get_setting('session.allow_delete_user_for_session_admin')); |
|
5817
|
|
|
$message = Display::return_message(get_lang('You cannot delete this user'), 'error'); |
|
5818
|
|
|
$userToUpdateInfo = api_get_user_info($userId); |
|
5819
|
|
|
|
|
5820
|
|
|
// User must exist. |
|
5821
|
|
|
if (empty($userToUpdateInfo)) { |
|
5822
|
|
|
return $message; |
|
5823
|
|
|
} |
|
5824
|
|
|
|
|
5825
|
|
|
$currentUserId = api_get_user_id(); |
|
5826
|
|
|
|
|
5827
|
|
|
// Cannot delete myself. |
|
5828
|
|
|
if ($userId == $currentUserId) { |
|
5829
|
|
|
return $message; |
|
5830
|
|
|
} |
|
5831
|
|
|
|
|
5832
|
|
|
if (api_is_platform_admin() || |
|
5833
|
|
|
($allowDelete && api_is_session_admin()) |
|
5834
|
|
|
) { |
|
5835
|
|
|
if (api_global_admin_can_edit_admin($userId, null, $allowDelete)) { |
|
5836
|
|
|
if (self::delete_user($userId, $destroy)) { |
|
5837
|
|
|
$message = Display::return_message( |
|
5838
|
|
|
get_lang('The user has been deleted').': '.$userToUpdateInfo['complete_name_with_username'], |
|
5839
|
|
|
'confirmation' |
|
5840
|
|
|
); |
|
5841
|
|
|
} else { |
|
5842
|
|
|
$message = Display::return_message(get_lang('This user cannot be deleted because he is still teacher in a course. You can either remove his teacher status from these courses and then delete his account, or disable his account instead of deleting it.'), 'error'); |
|
5843
|
|
|
} |
|
5844
|
|
|
} |
|
5845
|
|
|
} |
|
5846
|
|
|
|
|
5847
|
|
|
return $message; |
|
5848
|
|
|
} |
|
5849
|
|
|
|
|
5850
|
|
|
/** |
|
5851
|
|
|
* @return array |
|
5852
|
|
|
*/ |
|
5853
|
|
|
public static function createDataPrivacyExtraFields() |
|
5854
|
|
|
{ |
|
5855
|
|
|
self::create_extra_field( |
|
5856
|
|
|
'request_for_legal_agreement_consent_removal_justification', |
|
5857
|
|
|
1, //text |
|
5858
|
|
|
'Request for legal agreement consent removal justification ', |
|
5859
|
|
|
'' |
|
5860
|
|
|
); |
|
5861
|
|
|
|
|
5862
|
|
|
self::create_extra_field( |
|
5863
|
|
|
'request_for_delete_account_justification', |
|
5864
|
|
|
1, //text |
|
5865
|
|
|
'Request for delete account justification', |
|
5866
|
|
|
'' |
|
5867
|
|
|
); |
|
5868
|
|
|
|
|
5869
|
|
|
$extraFieldId = self::create_extra_field( |
|
5870
|
|
|
'request_for_legal_agreement_consent_removal', |
|
5871
|
|
|
1, //text |
|
5872
|
|
|
'Request for legal agreement consent removal', |
|
5873
|
|
|
'' |
|
5874
|
|
|
); |
|
5875
|
|
|
|
|
5876
|
|
|
$extraFieldIdDeleteAccount = self::create_extra_field( |
|
5877
|
|
|
'request_for_delete_account', |
|
5878
|
|
|
1, //text |
|
5879
|
|
|
'Request for delete user account', |
|
5880
|
|
|
'' |
|
5881
|
|
|
); |
|
5882
|
|
|
|
|
5883
|
|
|
return [ |
|
5884
|
|
|
'delete_account_extra_field' => $extraFieldIdDeleteAccount, |
|
5885
|
|
|
'delete_legal' => $extraFieldId, |
|
5886
|
|
|
]; |
|
5887
|
|
|
} |
|
5888
|
|
|
|
|
5889
|
|
|
/** |
|
5890
|
|
|
* @param int $userId |
|
5891
|
|
|
*/ |
|
5892
|
|
|
public static function cleanUserRequestsOfRemoval($userId) |
|
5893
|
|
|
{ |
|
5894
|
|
|
$userId = (int) $userId; |
|
5895
|
|
|
|
|
5896
|
|
|
$extraFieldValue = new ExtraFieldValue('user'); |
|
5897
|
|
|
$extraFieldsToDelete = [ |
|
5898
|
|
|
'legal_accept', |
|
5899
|
|
|
'request_for_legal_agreement_consent_removal', |
|
5900
|
|
|
'request_for_legal_agreement_consent_removal_justification', |
|
5901
|
|
|
'request_for_delete_account_justification', // just in case delete also this |
|
5902
|
|
|
'request_for_delete_account', |
|
5903
|
|
|
]; |
|
5904
|
|
|
|
|
5905
|
|
|
foreach ($extraFieldsToDelete as $variable) { |
|
5906
|
|
|
$value = $extraFieldValue->get_values_by_handler_and_field_variable( |
|
5907
|
|
|
$userId, |
|
5908
|
|
|
$variable |
|
5909
|
|
|
); |
|
5910
|
|
|
if ($value && isset($value['id'])) { |
|
5911
|
|
|
$extraFieldValue->delete($value['id']); |
|
5912
|
|
|
} |
|
5913
|
|
|
} |
|
5914
|
|
|
} |
|
5915
|
|
|
|
|
5916
|
|
|
/** |
|
5917
|
|
|
* @param int $searchYear |
|
5918
|
|
|
* |
|
5919
|
|
|
* @throws Exception |
|
5920
|
|
|
* |
|
5921
|
|
|
* @return array |
|
5922
|
|
|
*/ |
|
5923
|
|
|
public static function getSubscribedSessionsByYear(array $userInfo, $searchYear) |
|
5924
|
|
|
{ |
|
5925
|
|
|
$timezone = new DateTimeZone(api_get_timezone()); |
|
5926
|
|
|
|
|
5927
|
|
|
$sessions = []; |
|
5928
|
|
|
if (DRH == $userInfo['status']) { |
|
5929
|
|
|
$sessions = SessionManager::get_sessions_followed_by_drh($userInfo['id']); |
|
5930
|
|
|
} elseif (api_is_platform_admin(true)) { |
|
5931
|
|
|
$sessions = SessionManager::getSessionsForAdmin($userInfo['id']); |
|
5932
|
|
|
} else { |
|
5933
|
|
|
$sessionsByCategory = self::get_sessions_by_category($userInfo['id'], false, true, true); |
|
5934
|
|
|
$sessionsByCategory = array_column($sessionsByCategory, 'sessions'); |
|
5935
|
|
|
|
|
5936
|
|
|
foreach ($sessionsByCategory as $sessionsInCategory) { |
|
5937
|
|
|
$sessions = array_merge($sessions, $sessionsInCategory); |
|
5938
|
|
|
} |
|
5939
|
|
|
} |
|
5940
|
|
|
|
|
5941
|
|
|
$sessions = array_map( |
|
5942
|
|
|
function ($sessionInfo) { |
|
5943
|
|
|
if (!isset($sessionInfo['session_id'])) { |
|
5944
|
|
|
$sessionInfo['session_id'] = $sessionInfo['id']; |
|
5945
|
|
|
} |
|
5946
|
|
|
if (!isset($sessionInfo['session_name'])) { |
|
5947
|
|
|
$sessionInfo['session_name'] = $sessionInfo['name']; |
|
5948
|
|
|
} |
|
5949
|
|
|
|
|
5950
|
|
|
return $sessionInfo; |
|
5951
|
|
|
}, |
|
5952
|
|
|
$sessions |
|
5953
|
|
|
); |
|
5954
|
|
|
|
|
5955
|
|
|
$calendarSessions = []; |
|
5956
|
|
|
|
|
5957
|
|
|
foreach ($sessions as $sessionInfo) { |
|
5958
|
|
|
if (!empty($sessionInfo['duration'])) { |
|
5959
|
|
|
$courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser( |
|
5960
|
|
|
$sessionInfo['session_id'], |
|
5961
|
|
|
$userInfo['id'] |
|
5962
|
|
|
); |
|
5963
|
|
|
|
|
5964
|
|
|
if (empty($courseAccess)) { |
|
5965
|
|
|
continue; |
|
5966
|
|
|
} |
|
5967
|
|
|
|
|
5968
|
|
|
$firstAcessDate = new DateTime(api_get_local_time($courseAccess['login_course_date']), $timezone); |
|
5969
|
|
|
$lastAccessDate = clone $firstAcessDate; |
|
5970
|
|
|
$lastAccessDate->modify("+{$sessionInfo['duration']} days"); |
|
5971
|
|
|
|
|
5972
|
|
|
$firstAccessYear = (int) $firstAcessDate->format('Y'); |
|
5973
|
|
|
$lastAccessYear = (int) $lastAccessDate->format('Y'); |
|
5974
|
|
|
|
|
5975
|
|
|
if ($firstAccessYear <= $searchYear && $lastAccessYear >= $searchYear) { |
|
5976
|
|
|
$calendarSessions[$sessionInfo['session_id']] = [ |
|
5977
|
|
|
'name' => $sessionInfo['session_name'], |
|
5978
|
|
|
'access_start_date' => $firstAcessDate->format('Y-m-d h:i:s'), |
|
5979
|
|
|
'access_end_date' => $lastAccessDate->format('Y-m-d h:i:s'), |
|
5980
|
|
|
]; |
|
5981
|
|
|
} |
|
5982
|
|
|
|
|
5983
|
|
|
continue; |
|
5984
|
|
|
} |
|
5985
|
|
|
|
|
5986
|
|
|
$accessStartDate = !empty($sessionInfo['access_start_date']) |
|
5987
|
|
|
? new DateTime(api_get_local_time($sessionInfo['access_start_date']), $timezone) |
|
5988
|
|
|
: null; |
|
5989
|
|
|
$accessEndDate = !empty($sessionInfo['access_end_date']) |
|
5990
|
|
|
? new DateTime(api_get_local_time($sessionInfo['access_end_date']), $timezone) |
|
5991
|
|
|
: null; |
|
5992
|
|
|
$accessStartYear = $accessStartDate ? (int) $accessStartDate->format('Y') : 0; |
|
5993
|
|
|
$accessEndYear = $accessEndDate ? (int) $accessEndDate->format('Y') : 0; |
|
5994
|
|
|
|
|
5995
|
|
|
$isValid = false; |
|
5996
|
|
|
|
|
5997
|
|
|
if ($accessStartYear && $accessEndYear) { |
|
5998
|
|
|
if ($accessStartYear <= $searchYear && $accessEndYear >= $searchYear) { |
|
5999
|
|
|
$isValid = true; |
|
6000
|
|
|
} |
|
6001
|
|
|
} |
|
6002
|
|
|
|
|
6003
|
|
|
if ($accessStartYear && !$accessEndYear) { |
|
6004
|
|
|
if ($accessStartYear == $searchYear) { |
|
6005
|
|
|
$isValid = true; |
|
6006
|
|
|
} |
|
6007
|
|
|
} |
|
6008
|
|
|
|
|
6009
|
|
|
if (!$accessStartYear && $accessEndYear) { |
|
6010
|
|
|
if ($accessEndYear == $searchYear) { |
|
6011
|
|
|
$isValid = true; |
|
6012
|
|
|
} |
|
6013
|
|
|
} |
|
6014
|
|
|
|
|
6015
|
|
|
if ($isValid) { |
|
6016
|
|
|
$calendarSessions[$sessionInfo['session_id']] = [ |
|
6017
|
|
|
'name' => $sessionInfo['session_name'], |
|
6018
|
|
|
'access_start_date' => $accessStartDate ? $accessStartDate->format('Y-m-d h:i:s') : null, |
|
6019
|
|
|
'access_end_date' => $accessEndDate ? $accessEndDate->format('Y-m-d h:i:s') : null, |
|
6020
|
|
|
]; |
|
6021
|
|
|
} |
|
6022
|
|
|
} |
|
6023
|
|
|
|
|
6024
|
|
|
return $calendarSessions; |
|
6025
|
|
|
} |
|
6026
|
|
|
|
|
6027
|
|
|
/** |
|
6028
|
|
|
* Get sessions info for planification calendar. |
|
6029
|
|
|
* |
|
6030
|
|
|
* @param array $sessionsList Session list from UserManager::getSubscribedSessionsByYear |
|
6031
|
|
|
* @param int $searchYear |
|
6032
|
|
|
* |
|
6033
|
|
|
* @throws Exception |
|
6034
|
|
|
* |
|
6035
|
|
|
* @return array |
|
6036
|
|
|
*/ |
|
6037
|
|
|
public static function getSessionsCalendarByYear(array $sessionsList, $searchYear) |
|
6038
|
|
|
{ |
|
6039
|
|
|
$timezone = new DateTimeZone(api_get_timezone()); |
|
6040
|
|
|
$calendar = []; |
|
6041
|
|
|
|
|
6042
|
|
|
foreach ($sessionsList as $sessionId => $sessionInfo) { |
|
6043
|
|
|
$startDate = $sessionInfo['access_start_date'] |
|
6044
|
|
|
? new DateTime(api_get_local_time($sessionInfo['access_start_date']), $timezone) |
|
6045
|
|
|
: null; |
|
6046
|
|
|
$endDate = $sessionInfo['access_end_date'] |
|
6047
|
|
|
? new DateTime(api_get_local_time($sessionInfo['access_end_date']), $timezone) |
|
6048
|
|
|
: null; |
|
6049
|
|
|
|
|
6050
|
|
|
$startYear = $startDate ? (int) $startDate->format('Y') : 0; |
|
6051
|
|
|
$startWeekYear = $startDate ? (int) $startDate->format('o') : 0; |
|
6052
|
|
|
$startWeek = $startDate ? (int) $startDate->format('W') : 0; |
|
6053
|
|
|
$endYear = $endDate ? (int) $endDate->format('Y') : 0; |
|
6054
|
|
|
$endWeekYear = $endDate ? (int) $endDate->format('o') : 0; |
|
6055
|
|
|
$endWeek = $endDate ? (int) $endDate->format('W') : 0; |
|
6056
|
|
|
|
|
6057
|
|
|
$start = $startWeekYear < $searchYear ? 0 : $startWeek - 1; |
|
6058
|
|
|
$duration = $endWeekYear > $searchYear ? 52 - $start : $endWeek - $start; |
|
6059
|
|
|
|
|
6060
|
|
|
$calendar[] = [ |
|
6061
|
|
|
'id' => $sessionId, |
|
6062
|
|
|
'name' => $sessionInfo['name'], |
|
6063
|
|
|
'human_date' => SessionManager::convertSessionDateToString($startDate, $endDate, false, true), |
|
6064
|
|
|
'start_in_last_year' => $startYear < $searchYear, |
|
6065
|
|
|
'end_in_next_year' => $endYear > $searchYear, |
|
6066
|
|
|
'no_start' => !$startWeek, |
|
6067
|
|
|
'no_end' => !$endWeek, |
|
6068
|
|
|
'start' => $start, |
|
6069
|
|
|
'duration' => $duration > 0 ? $duration : 1, |
|
6070
|
|
|
]; |
|
6071
|
|
|
} |
|
6072
|
|
|
|
|
6073
|
|
|
usort( |
|
6074
|
|
|
$calendar, |
|
6075
|
|
|
function ($sA, $sB) { |
|
6076
|
|
|
if ($sA['start'] == $sB['start']) { |
|
6077
|
|
|
return 0; |
|
6078
|
|
|
} |
|
6079
|
|
|
|
|
6080
|
|
|
if ($sA['start'] < $sB['start']) { |
|
6081
|
|
|
return -1; |
|
6082
|
|
|
} |
|
6083
|
|
|
|
|
6084
|
|
|
return 1; |
|
6085
|
|
|
} |
|
6086
|
|
|
); |
|
6087
|
|
|
|
|
6088
|
|
|
return $calendar; |
|
6089
|
|
|
} |
|
6090
|
|
|
|
|
6091
|
|
|
/** |
|
6092
|
|
|
* Return the user's full name. Optionally with the username. |
|
6093
|
|
|
*/ |
|
6094
|
|
|
public static function formatUserFullName(User $user, bool $includeUsername = false): string |
|
6095
|
|
|
{ |
|
6096
|
|
|
$fullName = api_get_person_name($user->getFirstname(), $user->getLastname()); |
|
6097
|
|
|
|
|
6098
|
|
|
if ($includeUsername && 'false' === api_get_setting('profile.hide_username_with_complete_name')) { |
|
6099
|
|
|
$username = $user->getUsername(); |
|
6100
|
|
|
|
|
6101
|
|
|
return "$fullName ($username)"; |
|
6102
|
|
|
} |
|
6103
|
|
|
|
|
6104
|
|
|
return $fullName; |
|
6105
|
|
|
} |
|
6106
|
|
|
|
|
6107
|
|
|
/** |
|
6108
|
|
|
* @param int $userId |
|
6109
|
|
|
* |
|
6110
|
|
|
* @return array |
|
6111
|
|
|
*/ |
|
6112
|
|
|
public static function getUserCareers($userId) |
|
6113
|
|
|
{ |
|
6114
|
|
|
$table = Database::get_main_table(TABLE_MAIN_USER_CAREER); |
|
6115
|
|
|
$tableCareer = Database::get_main_table(TABLE_CAREER); |
|
6116
|
|
|
$userId = (int) $userId; |
|
6117
|
|
|
|
|
6118
|
|
|
$sql = "SELECT c.id, c.title |
|
6119
|
|
|
FROM $table uc |
|
6120
|
|
|
INNER JOIN $tableCareer c |
|
6121
|
|
|
ON uc.career_id = c.id |
|
6122
|
|
|
WHERE user_id = $userId |
|
6123
|
|
|
ORDER BY uc.created_at |
|
6124
|
|
|
"; |
|
6125
|
|
|
$result = Database::query($sql); |
|
6126
|
|
|
|
|
6127
|
|
|
return Database::store_result($result, 'ASSOC'); |
|
6128
|
|
|
} |
|
6129
|
|
|
|
|
6130
|
|
|
/** |
|
6131
|
|
|
* @param int $userId |
|
6132
|
|
|
* @param int $careerId |
|
6133
|
|
|
*/ |
|
6134
|
|
|
public static function addUserCareer($userId, $careerId) |
|
6135
|
|
|
{ |
|
6136
|
|
|
if ('true' !== api_get_setting('session.allow_career_users')) { |
|
6137
|
|
|
return false; |
|
6138
|
|
|
} |
|
6139
|
|
|
|
|
6140
|
|
|
if (false === self::userHasCareer($userId, $careerId)) { |
|
6141
|
|
|
$params = ['user_id' => $userId, 'career_id' => $careerId, 'created_at' => api_get_utc_datetime(), 'updated_at' => api_get_utc_datetime()]; |
|
6142
|
|
|
$table = Database::get_main_table(TABLE_MAIN_USER_CAREER); |
|
6143
|
|
|
Database::insert($table, $params); |
|
6144
|
|
|
} |
|
6145
|
|
|
|
|
6146
|
|
|
return true; |
|
6147
|
|
|
} |
|
6148
|
|
|
|
|
6149
|
|
|
/** |
|
6150
|
|
|
* @param int $userCareerId |
|
6151
|
|
|
* @param array $data |
|
6152
|
|
|
* |
|
6153
|
|
|
* @return bool |
|
6154
|
|
|
*/ |
|
6155
|
|
|
public static function updateUserCareer($userCareerId, $data) |
|
6156
|
|
|
{ |
|
6157
|
|
|
if ('true' !== api_get_setting('session.allow_career_users')) { |
|
6158
|
|
|
return false; |
|
6159
|
|
|
} |
|
6160
|
|
|
|
|
6161
|
|
|
$params = ['extra_data' => $data, 'updated_at' => api_get_utc_datetime()]; |
|
6162
|
|
|
$table = Database::get_main_table(TABLE_MAIN_USER_CAREER); |
|
6163
|
|
|
Database::update( |
|
6164
|
|
|
$table, |
|
6165
|
|
|
$params, |
|
6166
|
|
|
['id = ?' => (int) $userCareerId] |
|
6167
|
|
|
); |
|
6168
|
|
|
|
|
6169
|
|
|
return true; |
|
6170
|
|
|
} |
|
6171
|
|
|
|
|
6172
|
|
|
/** |
|
6173
|
|
|
* @param int $userId |
|
6174
|
|
|
* @param int $careerId |
|
6175
|
|
|
* |
|
6176
|
|
|
* @return array |
|
6177
|
|
|
*/ |
|
6178
|
|
|
public static function getUserCareer($userId, $careerId) |
|
6179
|
|
|
{ |
|
6180
|
|
|
$userId = (int) $userId; |
|
6181
|
|
|
$careerId = (int) $careerId; |
|
6182
|
|
|
$table = Database::get_main_table(TABLE_MAIN_USER_CAREER); |
|
6183
|
|
|
|
|
6184
|
|
|
$sql = "SELECT * FROM $table WHERE user_id = $userId AND career_id = $careerId"; |
|
6185
|
|
|
$result = Database::query($sql); |
|
6186
|
|
|
|
|
6187
|
|
|
return Database::fetch_assoc($result); |
|
|
|
|
|
|
6188
|
|
|
} |
|
6189
|
|
|
|
|
6190
|
|
|
/** |
|
6191
|
|
|
* @param int $userId |
|
6192
|
|
|
* @param int $careerId |
|
6193
|
|
|
* |
|
6194
|
|
|
* @return bool |
|
6195
|
|
|
*/ |
|
6196
|
|
|
public static function userHasCareer($userId, $careerId) |
|
6197
|
|
|
{ |
|
6198
|
|
|
$userId = (int) $userId; |
|
6199
|
|
|
$careerId = (int) $careerId; |
|
6200
|
|
|
$table = Database::get_main_table(TABLE_MAIN_USER_CAREER); |
|
6201
|
|
|
|
|
6202
|
|
|
$sql = "SELECT id FROM $table WHERE user_id = $userId AND career_id = $careerId"; |
|
6203
|
|
|
$result = Database::query($sql); |
|
6204
|
|
|
|
|
6205
|
|
|
return Database::num_rows($result) > 0; |
|
6206
|
|
|
} |
|
6207
|
|
|
|
|
6208
|
|
|
/** |
|
6209
|
|
|
* Disables or enables a user. |
|
6210
|
|
|
* |
|
6211
|
|
|
* @param int $user_id |
|
6212
|
|
|
* @param int $active Enable or disable |
|
6213
|
|
|
* |
|
6214
|
|
|
* @return bool True on success, false on failure |
|
6215
|
|
|
* @assert (-1,0) === false |
|
6216
|
|
|
* @assert (1,1) === true |
|
6217
|
|
|
*/ |
|
6218
|
|
|
public static function change_active_state($user_id, $active) |
|
6219
|
|
|
{ |
|
6220
|
|
|
$user_id = (int) $user_id; |
|
6221
|
|
|
$active = (int) $active; |
|
6222
|
|
|
|
|
6223
|
|
|
if (empty($user_id)) { |
|
6224
|
|
|
return false; |
|
6225
|
|
|
} |
|
6226
|
|
|
|
|
6227
|
|
|
$table_user = Database::get_main_table(TABLE_MAIN_USER); |
|
6228
|
|
|
$sql = "UPDATE $table_user SET active = '$active' WHERE id = $user_id"; |
|
6229
|
|
|
$r = Database::query($sql); |
|
6230
|
|
|
$ev = LOG_USER_DISABLE; |
|
6231
|
|
|
if (1 == $active) { |
|
6232
|
|
|
$ev = LOG_USER_ENABLE; |
|
6233
|
|
|
} |
|
6234
|
|
|
if (false !== $r) { |
|
6235
|
|
|
Event::addEvent($ev, LOG_USER_ID, $user_id); |
|
6236
|
|
|
} |
|
6237
|
|
|
|
|
6238
|
|
|
return $r; |
|
6239
|
|
|
} |
|
6240
|
|
|
|
|
6241
|
|
|
/** |
|
6242
|
|
|
* Get either a Gravatar URL or complete image tag for a specified email address. |
|
6243
|
|
|
* |
|
6244
|
|
|
* @param string $email The email address |
|
6245
|
|
|
* @param int $s Size in pixels, defaults to 80px [ 1 - 2048 ] |
|
6246
|
|
|
* @param string $d Default imageset to use [ 404 | mm | identicon | monsterid | wavatar ] |
|
6247
|
|
|
* @param string $r Maximum rating (inclusive) [ g | pg | r | x ] |
|
6248
|
|
|
* @param bool $img True to return a complete IMG tag False for just the URL |
|
6249
|
|
|
* @param array $atts Optional, additional key/value attributes to include in the IMG tag |
|
6250
|
|
|
* |
|
6251
|
|
|
* @return string containing either just a URL or a complete image tag |
|
6252
|
|
|
* @source http://gravatar.com/site/implement/images/php/ |
|
6253
|
|
|
*/ |
|
6254
|
|
|
private static function getGravatar( |
|
|
|
|
|
|
6255
|
|
|
$email, |
|
6256
|
|
|
$s = 80, |
|
6257
|
|
|
$d = 'mm', |
|
6258
|
|
|
$r = 'g', |
|
6259
|
|
|
$img = false, |
|
6260
|
|
|
$atts = [] |
|
6261
|
|
|
) { |
|
6262
|
|
|
$url = 'http://www.gravatar.com/avatar/'; |
|
6263
|
|
|
if (!empty($_SERVER['HTTPS'])) { |
|
6264
|
|
|
$url = 'https://secure.gravatar.com/avatar/'; |
|
6265
|
|
|
} |
|
6266
|
|
|
$url .= md5(strtolower(trim($email))); |
|
6267
|
|
|
$url .= "?s=$s&d=$d&r=$r"; |
|
6268
|
|
|
if ($img) { |
|
6269
|
|
|
$url = '<img src="'.$url.'"'; |
|
6270
|
|
|
foreach ($atts as $key => $val) { |
|
6271
|
|
|
$url .= ' '.$key.'="'.$val.'"'; |
|
6272
|
|
|
} |
|
6273
|
|
|
$url .= ' />'; |
|
6274
|
|
|
} |
|
6275
|
|
|
|
|
6276
|
|
|
return $url; |
|
6277
|
|
|
} |
|
6278
|
|
|
|
|
6279
|
|
|
/** |
|
6280
|
|
|
* Count users in courses and if they have certificate. |
|
6281
|
|
|
* This function is resource intensive. |
|
6282
|
|
|
* |
|
6283
|
|
|
* @return array |
|
6284
|
|
|
* @throws Exception |
|
6285
|
|
|
* @throws \Doctrine\DBAL\Exception |
|
6286
|
|
|
*/ |
|
6287
|
|
|
public static function countUsersWhoFinishedCourses() |
|
6288
|
|
|
{ |
|
6289
|
|
|
$courses = []; |
|
6290
|
|
|
$currentAccessUrlId = api_get_current_access_url_id(); |
|
6291
|
|
|
$sql = "SELECT course.code, course.id as cid, cru.user_id |
|
6292
|
|
|
FROM course_rel_user cru |
|
6293
|
|
|
JOIN course ON cru.c_id = course.id |
|
6294
|
|
|
JOIN access_url_rel_user auru on cru.user_id = auru.user_id |
|
6295
|
|
|
JOIN access_url_rel_course ON course.id = access_url_rel_course.c_id |
|
6296
|
|
|
WHERE access_url_rel_course.access_url_id = $currentAccessUrlId |
|
6297
|
|
|
ORDER BY course.code |
|
6298
|
|
|
"; |
|
6299
|
|
|
$res = Database::query($sql); |
|
6300
|
|
|
if (Database::num_rows($res) > 0) { |
|
6301
|
|
|
while ($row = Database::fetch_array($res)) { |
|
6302
|
|
|
if (!isset($courses[$row['code']])) { |
|
6303
|
|
|
$courses[$row['code']] = [ |
|
6304
|
|
|
'subscribed' => 0, |
|
6305
|
|
|
'finished' => 0, |
|
6306
|
|
|
]; |
|
6307
|
|
|
} |
|
6308
|
|
|
$courses[$row['code']]['subscribed']++; |
|
6309
|
|
|
$entityManager = Database::getManager(); |
|
6310
|
|
|
$repository = $entityManager->getRepository(GradebookCategory::class); |
|
6311
|
|
|
//todo check when have more than 1 gradebook |
|
6312
|
|
|
/** @var GradebookCategory $gradebook */ |
|
6313
|
|
|
$gradebook = $repository->findOneBy(['course' => $row['cid']]); |
|
6314
|
|
|
if (!empty($gradebook)) { |
|
6315
|
|
|
$finished = 0; |
|
6316
|
|
|
Database::getManager()->persist($gradebook); |
|
6317
|
|
|
$certificateRepo = $entityManager->getRepository(\Chamilo\CoreBundle\Entity\GradebookCertificate::class); |
|
6318
|
|
|
$finished = $certificateRepo->getCertificateByUserId($gradebook->getId(), $row['user_id']); |
|
6319
|
|
|
if (!empty($finished)) { |
|
6320
|
|
|
$courses[$row['code']]['finished']++; |
|
6321
|
|
|
} |
|
6322
|
|
|
} |
|
6323
|
|
|
} |
|
6324
|
|
|
} |
|
6325
|
|
|
return $courses; |
|
6326
|
|
|
} |
|
6327
|
|
|
|
|
6328
|
|
|
/** |
|
6329
|
|
|
* Count users in sessions and if they have certificate. |
|
6330
|
|
|
* This function is resource intensive. |
|
6331
|
|
|
* |
|
6332
|
|
|
* @return array |
|
6333
|
|
|
* @throws Exception |
|
6334
|
|
|
* @throws \Doctrine\DBAL\Exception |
|
6335
|
|
|
*/ |
|
6336
|
|
|
public static function countUsersWhoFinishedCoursesInSessions() |
|
6337
|
|
|
{ |
|
6338
|
|
|
$coursesInSessions = []; |
|
6339
|
|
|
$currentAccessUrlId = api_get_current_access_url_id(); |
|
6340
|
|
|
$sql = "SELECT course.code, srcru.session_id, srcru.user_id, session.title |
|
6341
|
|
|
FROM session_rel_course_rel_user srcru |
|
6342
|
|
|
JOIN course ON srcru.c_id = course.id |
|
6343
|
|
|
JOIN access_url_rel_session aurs on srcru.session_id = aurs.session_id |
|
6344
|
|
|
JOIN session ON srcru.session_id = session.id |
|
6345
|
|
|
WHERE aurs.access_url_id = $currentAccessUrlId |
|
6346
|
|
|
ORDER BY course.code, session.title |
|
6347
|
|
|
"; |
|
6348
|
|
|
$res = Database::query($sql); |
|
6349
|
|
|
if (Database::num_rows($res) > 0) { |
|
6350
|
|
|
while ($row = Database::fetch_array($res)) { |
|
6351
|
|
|
$index = $row['code'].' ('.$row['title'].')'; |
|
6352
|
|
|
if (!isset($coursesInSessions[$index])) { |
|
6353
|
|
|
$coursesInSessions[$index] = [ |
|
6354
|
|
|
'subscribed' => 0, |
|
6355
|
|
|
'finished' => 0, |
|
6356
|
|
|
]; |
|
6357
|
|
|
} |
|
6358
|
|
|
$coursesInSessions[$index]['subscribed']++; |
|
6359
|
|
|
$entityManager = Database::getManager(); |
|
6360
|
|
|
$repository = $entityManager->getRepository(GradebookCategory::class); |
|
6361
|
|
|
/** @var GradebookCategory $gradebook */ |
|
6362
|
|
|
$gradebook = $repository->findOneBy( |
|
6363
|
|
|
[ |
|
6364
|
|
|
'course' => $row['cid'], |
|
6365
|
|
|
'sessionId' => $row['session_id'], |
|
6366
|
|
|
] |
|
6367
|
|
|
); |
|
6368
|
|
|
if (!empty($gradebook)) { |
|
6369
|
|
|
$finished = 0; |
|
6370
|
|
|
Database::getManager()->persist($gradebook); |
|
6371
|
|
|
$certificateRepo = $entityManager->getRepository(\Chamilo\CoreBundle\Entity\GradebookCertificate::class); |
|
6372
|
|
|
$finished = $certificateRepo->getCertificateByUserId($gradebook->getId(), $row['user_id']); |
|
6373
|
|
|
if (!empty($finished)) { |
|
6374
|
|
|
$coursesInSessions[$index]['finished']++; |
|
6375
|
|
|
} |
|
6376
|
|
|
} |
|
6377
|
|
|
} |
|
6378
|
|
|
} |
|
6379
|
|
|
return $coursesInSessions; |
|
6380
|
|
|
} |
|
6381
|
|
|
|
|
6382
|
|
|
public static function redirectToResetPassword($userId): void |
|
6383
|
|
|
{ |
|
6384
|
|
|
if ('true' !== api_get_setting('security.force_renew_password_at_first_login')) { |
|
6385
|
|
|
return; |
|
6386
|
|
|
} |
|
6387
|
|
|
$askPassword = self::get_extra_user_data_by_field( |
|
6388
|
|
|
$userId, |
|
6389
|
|
|
'ask_new_password' |
|
6390
|
|
|
); |
|
6391
|
|
|
if (!empty($askPassword) && isset($askPassword['ask_new_password']) && |
|
6392
|
|
|
1 === (int) $askPassword['ask_new_password'] |
|
6393
|
|
|
) { |
|
6394
|
|
|
$uniqueId = api_get_unique_id(); |
|
6395
|
|
|
$userObj = api_get_user_entity($userId); |
|
6396
|
|
|
$userObj->setConfirmationToken($uniqueId); |
|
6397
|
|
|
$userObj->setPasswordRequestedAt(new \DateTime()); |
|
6398
|
|
|
Database::getManager()->persist($userObj); |
|
6399
|
|
|
Database::getManager()->flush(); |
|
6400
|
|
|
$url = api_get_path(WEB_CODE_PATH).'auth/reset.php?token='.$uniqueId; |
|
6401
|
|
|
api_location($url); |
|
6402
|
|
|
} |
|
6403
|
|
|
} |
|
6404
|
|
|
|
|
6405
|
|
|
} |
|
6406
|
|
|
|
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.