1 | <?php |
||||||
2 | |||||||
3 | /* For licensing terms, see /license.txt */ |
||||||
4 | |||||||
5 | use Chamilo\CoreBundle\Entity\ExtraField as EntityExtraField; |
||||||
6 | use Chamilo\CoreBundle\Entity\Repository\AccessUrlRepository; |
||||||
7 | use Chamilo\CoreBundle\Entity\Session as SessionEntity; |
||||||
8 | use Chamilo\CoreBundle\Entity\SkillRelUser; |
||||||
0 ignored issues
–
show
|
|||||||
9 | use Chamilo\CoreBundle\Entity\SkillRelUserComment; |
||||||
10 | use Chamilo\CoreBundle\Entity\TrackELoginAttempt; |
||||||
11 | use Chamilo\UserBundle\Entity\User; |
||||||
12 | use Chamilo\UserBundle\Repository\UserRepository; |
||||||
13 | use ChamiloSession as Session; |
||||||
14 | use Symfony\Component\Filesystem\Filesystem; |
||||||
15 | use Symfony\Component\Security\Core\Encoder\EncoderFactory; |
||||||
16 | |||||||
17 | /** |
||||||
18 | * Class UserManager. |
||||||
19 | * |
||||||
20 | * This library provides functions for user management. |
||||||
21 | * Include/require it in your code to use its functionality. |
||||||
22 | * |
||||||
23 | * @author Julio Montoya <[email protected]> Social network groups added 2009/12 |
||||||
24 | */ |
||||||
25 | class UserManager |
||||||
26 | { |
||||||
27 | // This constants are deprecated use the constants located in ExtraField |
||||||
28 | public const USER_FIELD_TYPE_TEXT = 1; |
||||||
29 | public const USER_FIELD_TYPE_TEXTAREA = 2; |
||||||
30 | public const USER_FIELD_TYPE_RADIO = 3; |
||||||
31 | public const USER_FIELD_TYPE_SELECT = 4; |
||||||
32 | public const USER_FIELD_TYPE_SELECT_MULTIPLE = 5; |
||||||
33 | public const USER_FIELD_TYPE_DATE = 6; |
||||||
34 | public const USER_FIELD_TYPE_DATETIME = 7; |
||||||
35 | public const USER_FIELD_TYPE_DOUBLE_SELECT = 8; |
||||||
36 | public const USER_FIELD_TYPE_DIVIDER = 9; |
||||||
37 | public const USER_FIELD_TYPE_TAG = 10; |
||||||
38 | public const USER_FIELD_TYPE_TIMEZONE = 11; |
||||||
39 | public const USER_FIELD_TYPE_SOCIAL_PROFILE = 12; |
||||||
40 | public const USER_FIELD_TYPE_FILE = 13; |
||||||
41 | public const USER_FIELD_TYPE_MOBILE_PHONE_NUMBER = 14; |
||||||
42 | |||||||
43 | private static $encryptionMethod; |
||||||
44 | |||||||
45 | /** |
||||||
46 | * Constructor. |
||||||
47 | * |
||||||
48 | * @assert () === null |
||||||
49 | */ |
||||||
50 | public function __construct() |
||||||
51 | { |
||||||
52 | } |
||||||
53 | |||||||
54 | /** |
||||||
55 | * Repository is use to query the DB, selects, etc. |
||||||
56 | * |
||||||
57 | * @return UserRepository |
||||||
58 | */ |
||||||
59 | public static function getRepository() |
||||||
60 | { |
||||||
61 | /** @var UserRepository $userRepository */ |
||||||
62 | |||||||
63 | return Database::getManager()->getRepository('ChamiloUserBundle:User'); |
||||||
64 | } |
||||||
65 | |||||||
66 | /** |
||||||
67 | * Create/update/delete methods are available in the UserManager |
||||||
68 | * (based in the Sonata\UserBundle\Entity\UserManager). |
||||||
69 | * |
||||||
70 | * @return Chamilo\UserBundle\Entity\Manager\UserManager |
||||||
71 | */ |
||||||
72 | public static function getManager() |
||||||
73 | { |
||||||
74 | static $userManager; |
||||||
75 | |||||||
76 | if (!isset($userManager)) { |
||||||
77 | $encoderFactory = self::getEncoderFactory(); |
||||||
78 | $passwordUpdater = new \FOS\UserBundle\Util\PasswordUpdater($encoderFactory); |
||||||
79 | $canonicalFieldUpdater = new \FOS\UserBundle\Util\CanonicalFieldsUpdater( |
||||||
80 | new \FOS\UserBundle\Util\Canonicalizer(), new \FOS\UserBundle\Util\Canonicalizer() |
||||||
81 | ); |
||||||
82 | $userManager = new Chamilo\UserBundle\Entity\Manager\UserManager( |
||||||
83 | $passwordUpdater, |
||||||
84 | $canonicalFieldUpdater, |
||||||
85 | Database::getManager(), |
||||||
86 | 'Chamilo\\UserBundle\\Entity\\User' |
||||||
87 | ); |
||||||
88 | } |
||||||
89 | |||||||
90 | return $userManager; |
||||||
91 | } |
||||||
92 | |||||||
93 | /** |
||||||
94 | * @param string $encryptionMethod |
||||||
95 | */ |
||||||
96 | public static function setPasswordEncryption($encryptionMethod) |
||||||
97 | { |
||||||
98 | self::$encryptionMethod = $encryptionMethod; |
||||||
99 | } |
||||||
100 | |||||||
101 | /** |
||||||
102 | * @return bool|mixed |
||||||
103 | */ |
||||||
104 | public static function getPasswordEncryption() |
||||||
105 | { |
||||||
106 | $encryptionMethod = self::$encryptionMethod; |
||||||
107 | if (empty($encryptionMethod)) { |
||||||
108 | $encryptionMethod = api_get_configuration_value('password_encryption'); |
||||||
109 | } |
||||||
110 | |||||||
111 | return $encryptionMethod; |
||||||
112 | } |
||||||
113 | |||||||
114 | /** |
||||||
115 | * Validates the password. |
||||||
116 | * |
||||||
117 | * @param $encoded |
||||||
118 | * @param $raw |
||||||
119 | * @param $salt |
||||||
120 | * |
||||||
121 | * @return bool |
||||||
122 | */ |
||||||
123 | public static function isPasswordValid($encoded, $raw, $salt) |
||||||
124 | { |
||||||
125 | $encoder = new \Chamilo\UserBundle\Security\Encoder(self::getPasswordEncryption()); |
||||||
126 | |||||||
127 | return $encoder->isPasswordValid($encoded, $raw, $salt); |
||||||
128 | } |
||||||
129 | |||||||
130 | /** |
||||||
131 | * Detects and returns the type of encryption of the given encrypted |
||||||
132 | * password. |
||||||
133 | * |
||||||
134 | * @param string $encoded The encrypted password |
||||||
135 | * @param string $salt The user salt, if any |
||||||
136 | */ |
||||||
137 | public static function detectPasswordEncryption(string $encoded, string $salt): string |
||||||
138 | { |
||||||
139 | $encryption = false; |
||||||
140 | |||||||
141 | $length = strlen($encoded); |
||||||
142 | |||||||
143 | $pattern = '/^\$2y\$04\$[A-Za-z0-9\.\/]{53}$/'; |
||||||
144 | |||||||
145 | if ($length == 60 && preg_match($pattern, $encoded)) { |
||||||
146 | $encryption = 'bcrypt'; |
||||||
147 | } elseif ($length == 32 && ctype_xdigit($encoded)) { |
||||||
148 | $encryption = 'md5'; |
||||||
149 | } elseif ($length == 40 && ctype_xdigit($encoded)) { |
||||||
150 | $encryption = 'sha1'; |
||||||
151 | } else { |
||||||
152 | $start = strpos($encoded, '{'); |
||||||
153 | if ($start !== false && substr($encoded, -1, 1) == '}') { |
||||||
154 | if (substr($encoded, $start + 1, -1) == $salt) { |
||||||
155 | $encryption = 'none'; |
||||||
156 | } |
||||||
157 | } |
||||||
158 | } |
||||||
159 | |||||||
160 | return $encryption; |
||||||
0 ignored issues
–
show
|
|||||||
161 | } |
||||||
162 | |||||||
163 | /** |
||||||
164 | * Checks if the password is correct for this user. |
||||||
165 | * If the password_conversion setting is true, also update the password |
||||||
166 | * in the database to a new encryption method. |
||||||
167 | * |
||||||
168 | * @param string $encoded Encrypted password |
||||||
169 | * @param string $raw Clear password given through login form |
||||||
170 | * @param string $salt User salt, if any |
||||||
171 | * @param int $userId The user's internal ID |
||||||
172 | */ |
||||||
173 | public static function checkPassword(string $encoded, string $raw, string $salt, int $userId): bool |
||||||
174 | { |
||||||
175 | $result = false; |
||||||
176 | |||||||
177 | if (true === api_get_configuration_value('password_conversion')) { |
||||||
178 | $detectedEncryption = self::detectPasswordEncryption($encoded, $salt); |
||||||
179 | if (self::getPasswordEncryption() != $detectedEncryption) { |
||||||
180 | $encoder = new \Chamilo\UserBundle\Security\Encoder($detectedEncryption); |
||||||
181 | $result = $encoder->isPasswordValid($encoded, $raw, $salt); |
||||||
182 | if ($result) { |
||||||
183 | $raw = $encoder->encodePassword($encoded, $salt); |
||||||
184 | self::updatePassword($userId, $raw); |
||||||
185 | } |
||||||
186 | } else { |
||||||
187 | $result = self::isPasswordValid($encoded, $raw, $salt); |
||||||
188 | } |
||||||
189 | } else { |
||||||
190 | $result = self::isPasswordValid($encoded, $raw, $salt); |
||||||
191 | } |
||||||
192 | |||||||
193 | return $result; |
||||||
194 | } |
||||||
195 | |||||||
196 | /** |
||||||
197 | * Encrypt the password using the current encoder. |
||||||
198 | * |
||||||
199 | * @param string $raw The clear password |
||||||
200 | */ |
||||||
201 | public static function encryptPassword(string $raw, User $user): string |
||||||
202 | { |
||||||
203 | $encoder = self::getEncoder($user); |
||||||
204 | |||||||
205 | return $encoder->encodePassword( |
||||||
206 | $raw, |
||||||
207 | $user->getSalt() |
||||||
208 | ); |
||||||
209 | } |
||||||
210 | |||||||
211 | /** |
||||||
212 | * Update the password of the given user to the given (in-clear) password. |
||||||
213 | * |
||||||
214 | * @param int $userId Internal user ID |
||||||
215 | * @param string $password Password in clear |
||||||
216 | */ |
||||||
217 | public static function updatePassword(int $userId, string $password): void |
||||||
218 | { |
||||||
219 | $repository = self::getRepository(); |
||||||
220 | /** @var User $user */ |
||||||
221 | $user = $repository->find($userId); |
||||||
222 | $userManager = self::getManager(); |
||||||
223 | $user->setPlainPassword($password); |
||||||
224 | $userManager->updateUser($user, true); |
||||||
225 | Event::addEvent(LOG_USER_PASSWORD_UPDATE, LOG_USER_ID, $userId); |
||||||
0 ignored issues
–
show
The method
addEvent() does not exist on Event .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
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.
Loading history...
|
|||||||
226 | } |
||||||
227 | |||||||
228 | /** |
||||||
229 | * Updates user expiration date. |
||||||
230 | * |
||||||
231 | * @param int $userId |
||||||
232 | * @param string $expirationDate |
||||||
233 | */ |
||||||
234 | public static function updateExpirationDate($userId, $expirationDate) |
||||||
235 | { |
||||||
236 | $repository = self::getRepository(); |
||||||
237 | /** @var User $user */ |
||||||
238 | $user = $repository->find($userId); |
||||||
239 | $userManager = self::getManager(); |
||||||
240 | $expirationDate = api_get_utc_datetime($expirationDate, false, true); |
||||||
241 | $user->setExpirationDate($expirationDate); |
||||||
242 | $userManager->updateUser($user, true); |
||||||
243 | } |
||||||
244 | |||||||
245 | /** |
||||||
246 | * Creates a new user for the platform. |
||||||
247 | * |
||||||
248 | * @author Hugues Peeters <[email protected]>, |
||||||
249 | * @author Roan Embrechts <[email protected]> |
||||||
250 | * |
||||||
251 | * @param string $firstName |
||||||
252 | * @param string $lastName |
||||||
253 | * @param int $status (1 for course tutor, 5 for student, 6 for anonymous) |
||||||
254 | * @param string $email |
||||||
255 | * @param string $loginName |
||||||
256 | * @param string $password |
||||||
257 | * @param string $official_code Any official code (optional) |
||||||
258 | * @param string $language User language (optional) |
||||||
259 | * @param string $phone Phone number (optional) |
||||||
260 | * @param string $picture_uri Picture URI (optional) |
||||||
261 | * @param string $authSource Authentication source (defaults to 'platform', dependind on constant) |
||||||
262 | * @param string $expirationDate Account expiration date (optional, defaults to null) |
||||||
263 | * @param int $active Whether the account is enabled or disabled by default |
||||||
264 | * @param int $hr_dept_id The department of HR in which the user is registered (defaults to 0) |
||||||
265 | * @param array $extra Extra fields (prefix labels with "extra_") |
||||||
266 | * @param string $encrypt_method Used if password is given encrypted. Set to an empty string by default |
||||||
267 | * @param bool $send_mail |
||||||
268 | * @param bool $isAdmin |
||||||
269 | * @param string $address |
||||||
270 | * @param bool $sendEmailToAllAdmins |
||||||
271 | * @param FormValidator $form |
||||||
272 | * @param int $creatorId |
||||||
273 | * @param array $emailTemplate |
||||||
274 | * @param string $redirectToURLAfterLogin |
||||||
275 | * |
||||||
276 | * @return mixed new user id - if the new user creation succeeds, false otherwise |
||||||
277 | * @desc The function tries to retrieve user id from the session. |
||||||
278 | * If it exists, the current user id is the creator id. If a problem arises, |
||||||
279 | * @assert ('Sam','Gamegie',5,'[email protected]','jo','jo') > 1 |
||||||
280 | * @assert ('Pippin','Took',null,null,'jo','jo') === false |
||||||
281 | */ |
||||||
282 | public static function create_user( |
||||||
283 | $firstName, |
||||||
284 | $lastName, |
||||||
285 | $status, |
||||||
286 | $email, |
||||||
287 | $loginName, |
||||||
288 | $password, |
||||||
289 | $official_code = '', |
||||||
290 | $language = '', |
||||||
291 | $phone = '', |
||||||
292 | $picture_uri = '', |
||||||
293 | $authSource = PLATFORM_AUTH_SOURCE, |
||||||
294 | $expirationDate = null, |
||||||
295 | $active = 1, |
||||||
296 | $hr_dept_id = 0, |
||||||
297 | $extra = [], |
||||||
298 | $encrypt_method = '', |
||||||
299 | $send_mail = false, |
||||||
300 | $isAdmin = false, |
||||||
301 | $address = '', |
||||||
302 | $sendEmailToAllAdmins = false, |
||||||
303 | $form = null, |
||||||
304 | $creatorId = 0, |
||||||
305 | $emailTemplate = [], |
||||||
306 | $redirectToURLAfterLogin = '' |
||||||
307 | ) { |
||||||
308 | $creatorId = empty($creatorId) ? api_get_user_id() : 0; |
||||||
309 | $creatorInfo = api_get_user_info($creatorId); |
||||||
310 | $creatorEmail = isset($creatorInfo['email']) ? $creatorInfo['email'] : ''; |
||||||
311 | |||||||
312 | $hook = HookCreateUser::create(); |
||||||
313 | if (!empty($hook)) { |
||||||
314 | $hook->notifyCreateUser(HOOK_EVENT_TYPE_PRE); |
||||||
315 | } |
||||||
316 | |||||||
317 | if ('true' === api_get_setting('registration', 'email')) { |
||||||
318 | // Force email validation. |
||||||
319 | if (false === api_valid_email($email)) { |
||||||
320 | Display::addFlash( |
||||||
321 | Display::return_message(get_lang('PleaseEnterValidEmail').' - '.$email, 'warning') |
||||||
322 | ); |
||||||
323 | |||||||
324 | return false; |
||||||
325 | } |
||||||
326 | } else { |
||||||
327 | // Allow empty email. If email is set, check if is valid. |
||||||
328 | if (!empty($email) && false === api_valid_email($email)) { |
||||||
329 | Display::addFlash( |
||||||
330 | Display::return_message(get_lang('PleaseEnterValidEmail').' - '.$email, 'warning') |
||||||
331 | ); |
||||||
332 | |||||||
333 | return false; |
||||||
334 | } |
||||||
335 | } |
||||||
336 | |||||||
337 | if ('true' === api_get_setting('login_is_email')) { |
||||||
338 | if (false === api_valid_email($loginName)) { |
||||||
339 | Display::addFlash( |
||||||
340 | Display::return_message(get_lang('PleaseEnterValidEmail').' - '.$loginName, 'warning') |
||||||
341 | ); |
||||||
342 | |||||||
343 | return false; |
||||||
344 | } |
||||||
345 | } else { |
||||||
346 | if (false === self::is_username_valid($loginName)) { |
||||||
347 | Display::addFlash( |
||||||
348 | Display::return_message(get_lang('UsernameWrong').' - '.$loginName, 'warning') |
||||||
349 | ); |
||||||
350 | |||||||
351 | return false; |
||||||
352 | } |
||||||
353 | } |
||||||
354 | |||||||
355 | // First check wether the login already exists |
||||||
356 | if (!self::is_username_available($loginName)) { |
||||||
357 | Display::addFlash( |
||||||
358 | Display::return_message(get_lang('LoginAlreadyTaken').' - '.$loginName, 'warning') |
||||||
359 | ); |
||||||
360 | |||||||
361 | return false; |
||||||
362 | } |
||||||
363 | |||||||
364 | global $_configuration; |
||||||
365 | $original_password = $password; |
||||||
366 | |||||||
367 | $access_url_id = 1; |
||||||
368 | if (api_get_multiple_access_url()) { |
||||||
369 | $access_url_id = api_get_current_access_url_id(); |
||||||
370 | } else { |
||||||
371 | // In some cases, the first access_url ID might be different from 1 |
||||||
372 | // for example when using a DB cluster or hacking the DB manually. |
||||||
373 | // In this case, we want the first row, not necessarily "1". |
||||||
374 | $dbm = Database::getManager(); |
||||||
375 | /** @var AccessUrlRepository $accessUrlRepository */ |
||||||
376 | $accessUrlRepository = $dbm->getRepository('ChamiloCoreBundle:AccessUrl'); |
||||||
377 | $accessUrl = $accessUrlRepository->getFirstId(); |
||||||
378 | if (!empty($accessUrl[0]) && !empty($accessUrl[0][1])) { |
||||||
379 | $access_url_id = $accessUrl[0][1]; |
||||||
380 | } |
||||||
381 | } |
||||||
382 | |||||||
383 | if (isset($_configuration[$access_url_id]) && |
||||||
384 | is_array($_configuration[$access_url_id]) && |
||||||
385 | isset($_configuration[$access_url_id]['hosting_limit_users']) && |
||||||
386 | $_configuration[$access_url_id]['hosting_limit_users'] > 0) { |
||||||
387 | $num = self::get_number_of_users(null, $access_url_id); |
||||||
388 | if ($num >= $_configuration[$access_url_id]['hosting_limit_users']) { |
||||||
389 | api_warn_hosting_contact('hosting_limit_users'); |
||||||
390 | Display::addFlash( |
||||||
391 | Display::return_message( |
||||||
392 | get_lang('PortalUsersLimitReached'), |
||||||
393 | 'warning' |
||||||
394 | ) |
||||||
395 | ); |
||||||
396 | |||||||
397 | return false; |
||||||
398 | } |
||||||
399 | } |
||||||
400 | |||||||
401 | if ($status === 1 && |
||||||
402 | isset($_configuration[$access_url_id]) && |
||||||
403 | is_array($_configuration[$access_url_id]) && |
||||||
404 | isset($_configuration[$access_url_id]['hosting_limit_teachers']) && |
||||||
405 | $_configuration[$access_url_id]['hosting_limit_teachers'] > 0 |
||||||
406 | ) { |
||||||
407 | $num = self::get_number_of_users(1, $access_url_id); |
||||||
408 | if ($num >= $_configuration[$access_url_id]['hosting_limit_teachers']) { |
||||||
409 | Display::addFlash( |
||||||
410 | Display::return_message( |
||||||
411 | get_lang('PortalTeachersLimitReached'), |
||||||
412 | 'warning' |
||||||
413 | ) |
||||||
414 | ); |
||||||
415 | api_warn_hosting_contact('hosting_limit_teachers'); |
||||||
416 | |||||||
417 | return false; |
||||||
418 | } |
||||||
419 | } |
||||||
420 | |||||||
421 | if (empty($password)) { |
||||||
422 | if ($authSource === PLATFORM_AUTH_SOURCE) { |
||||||
423 | Display::addFlash( |
||||||
424 | Display::return_message( |
||||||
425 | get_lang('ThisFieldIsRequired').': '.get_lang( |
||||||
426 | 'Password' |
||||||
427 | ), |
||||||
428 | 'warning' |
||||||
429 | ) |
||||||
430 | ); |
||||||
431 | |||||||
432 | return false; |
||||||
433 | } |
||||||
434 | |||||||
435 | // We use the authSource as password. |
||||||
436 | // The real validation will be by processed by the auth |
||||||
437 | // source not Chamilo |
||||||
438 | $password = $authSource; |
||||||
439 | } |
||||||
440 | |||||||
441 | // database table definition |
||||||
442 | $table_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
443 | |||||||
444 | // Checking the user language |
||||||
445 | $languages = api_get_languages(); |
||||||
446 | $language = strtolower($language); |
||||||
447 | |||||||
448 | if (isset($languages['folder'])) { |
||||||
449 | if (!in_array($language, $languages['folder'])) { |
||||||
450 | $language = api_get_setting('platformLanguage'); |
||||||
451 | } |
||||||
452 | } |
||||||
453 | |||||||
454 | $currentDate = api_get_utc_datetime(); |
||||||
455 | $now = new DateTime(); |
||||||
456 | |||||||
457 | if (empty($expirationDate) || $expirationDate == '0000-00-00 00:00:00') { |
||||||
458 | // Default expiration date |
||||||
459 | // if there is a default duration of a valid account then |
||||||
460 | // we have to change the expiration_date accordingly |
||||||
461 | // Accept 0000-00-00 00:00:00 as a null value to avoid issues with |
||||||
462 | // third party code using this method with the previous (pre-1.10) |
||||||
463 | // value of 0000... |
||||||
464 | if (api_get_setting('account_valid_duration') != '') { |
||||||
465 | $expirationDate = new DateTime($currentDate); |
||||||
466 | $days = (int) api_get_setting('account_valid_duration'); |
||||||
467 | $expirationDate->modify('+'.$days.' day'); |
||||||
468 | } |
||||||
469 | } else { |
||||||
470 | $expirationDate = api_get_utc_datetime($expirationDate); |
||||||
471 | $expirationDate = new \DateTime($expirationDate, new DateTimeZone('UTC')); |
||||||
472 | } |
||||||
473 | |||||||
474 | $userManager = self::getManager(); |
||||||
475 | |||||||
476 | /** @var User $user */ |
||||||
477 | $user = $userManager->createUser(); |
||||||
478 | |||||||
479 | $user |
||||||
480 | ->setLastname($lastName) |
||||||
481 | ->setFirstname($firstName) |
||||||
482 | ->setUsername($loginName) |
||||||
483 | ->setStatus($status) |
||||||
484 | ->setPlainPassword($password) |
||||||
485 | ->setEmail($email) |
||||||
486 | ->setOfficialCode($official_code) |
||||||
487 | ->setPictureUri($picture_uri) |
||||||
488 | ->setCreatorId($creatorId) |
||||||
489 | ->setAuthSource($authSource) |
||||||
490 | ->setPhone($phone) |
||||||
491 | ->setAddress($address) |
||||||
492 | ->setLanguage($language) |
||||||
493 | ->setRegistrationDate($now) |
||||||
494 | ->setHrDeptId($hr_dept_id) |
||||||
495 | ->setActive($active) |
||||||
496 | ->setEnabled($active) |
||||||
497 | ; |
||||||
498 | |||||||
499 | if (!empty($expirationDate)) { |
||||||
500 | $user->setExpirationDate($expirationDate); |
||||||
501 | } |
||||||
502 | |||||||
503 | $userManager->updateUser($user); |
||||||
504 | $userId = $user->getId(); |
||||||
505 | |||||||
506 | if (!empty($userId)) { |
||||||
507 | $return = $userId; |
||||||
508 | $sql = "UPDATE $table_user SET user_id = $return WHERE id = $return"; |
||||||
509 | Database::query($sql); |
||||||
510 | |||||||
511 | if ($isAdmin) { |
||||||
512 | self::addUserAsAdmin($user); |
||||||
513 | } |
||||||
514 | |||||||
515 | if (api_get_multiple_access_url()) { |
||||||
516 | UrlManager::add_user_to_url($userId, api_get_current_access_url_id()); |
||||||
517 | } else { |
||||||
518 | //we are adding by default the access_url_user table with access_url_id = 1 |
||||||
519 | UrlManager::add_user_to_url($userId, 1); |
||||||
520 | } |
||||||
521 | |||||||
522 | $extra['item_id'] = $userId; |
||||||
523 | |||||||
524 | if (is_array($extra) && count($extra) > 0) { |
||||||
525 | $userFieldValue = new ExtraFieldValue('user'); |
||||||
526 | // Force saving of extra fields (otherwise, if the current |
||||||
527 | // user is not admin, fields not visible to the user - most |
||||||
528 | // of them - are just ignored) |
||||||
529 | $userFieldValue->saveFieldValues( |
||||||
530 | $extra, |
||||||
531 | true, |
||||||
532 | null, |
||||||
533 | null, |
||||||
534 | null, |
||||||
535 | true |
||||||
536 | ); |
||||||
537 | } else { |
||||||
538 | // Create notify settings by default |
||||||
539 | self::update_extra_field_value( |
||||||
540 | $userId, |
||||||
541 | 'mail_notify_invitation', |
||||||
542 | '1' |
||||||
543 | ); |
||||||
544 | self::update_extra_field_value( |
||||||
545 | $userId, |
||||||
546 | 'mail_notify_message', |
||||||
547 | '1' |
||||||
548 | ); |
||||||
549 | self::update_extra_field_value( |
||||||
550 | $userId, |
||||||
551 | 'mail_notify_group_message', |
||||||
552 | '1' |
||||||
553 | ); |
||||||
554 | } |
||||||
555 | |||||||
556 | self::update_extra_field_value( |
||||||
557 | $userId, |
||||||
558 | 'already_logged_in', |
||||||
559 | 'false' |
||||||
560 | ); |
||||||
561 | |||||||
562 | if (!empty($redirectToURLAfterLogin) && api_get_configuration_value('plugin_redirection_enabled')) { |
||||||
563 | RedirectionPlugin::insert($userId, $redirectToURLAfterLogin); |
||||||
564 | } |
||||||
565 | |||||||
566 | if (!empty($email) && $send_mail) { |
||||||
567 | $recipient_name = api_get_person_name( |
||||||
568 | $firstName, |
||||||
569 | $lastName, |
||||||
570 | null, |
||||||
571 | PERSON_NAME_EMAIL_ADDRESS |
||||||
572 | ); |
||||||
573 | $tplSubject = new Template( |
||||||
574 | null, |
||||||
575 | false, |
||||||
576 | false, |
||||||
577 | false, |
||||||
578 | false, |
||||||
579 | false |
||||||
580 | ); |
||||||
581 | // the complete_name is not used in the default Chamilo template but used in a specific template -refs BT#21334 |
||||||
582 | $tplSubject->assign('complete_name', stripslashes(api_get_person_name($firstName, $lastName))); |
||||||
583 | $layoutSubject = $tplSubject->get_template('mail/subject_registration_platform.tpl'); |
||||||
584 | $emailSubject = $tplSubject->fetch($layoutSubject); |
||||||
585 | $sender_name = api_get_person_name( |
||||||
586 | api_get_setting('administratorName'), |
||||||
587 | api_get_setting('administratorSurname'), |
||||||
588 | null, |
||||||
589 | PERSON_NAME_EMAIL_ADDRESS |
||||||
590 | ); |
||||||
591 | $email_admin = api_get_setting('emailAdministrator'); |
||||||
592 | |||||||
593 | $url = api_get_path(WEB_PATH); |
||||||
594 | if (api_is_multiple_url_enabled()) { |
||||||
595 | $access_url_id = api_get_current_access_url_id(); |
||||||
596 | if ($access_url_id != -1) { |
||||||
597 | $urlInfo = api_get_access_url($access_url_id); |
||||||
598 | if ($urlInfo) { |
||||||
0 ignored issues
–
show
The expression
$urlInfo of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using
Loading history...
|
|||||||
599 | $url = $urlInfo['url']; |
||||||
600 | } |
||||||
601 | } |
||||||
602 | } |
||||||
603 | |||||||
604 | $tplContent = new Template( |
||||||
605 | null, |
||||||
606 | false, |
||||||
607 | false, |
||||||
608 | false, |
||||||
609 | false, |
||||||
610 | false |
||||||
611 | ); |
||||||
612 | // variables for the default template |
||||||
613 | $tplContent->assign('complete_name', stripslashes(api_get_person_name($firstName, $lastName))); |
||||||
614 | $tplContent->assign('login_name', $loginName); |
||||||
615 | $tplContent->assign('original_password', stripslashes($original_password)); |
||||||
616 | $tplContent->assign('mailWebPath', $url); |
||||||
617 | $tplContent->assign('new_user', $user); |
||||||
618 | // Adding this variable but not used in default template, used for task BT19518 with a customized template |
||||||
619 | $tplContent->assign('status_type', $status); |
||||||
620 | |||||||
621 | $layoutContent = $tplContent->get_template('mail/content_registration_platform.tpl'); |
||||||
622 | $emailBody = $tplContent->fetch($layoutContent); |
||||||
623 | |||||||
624 | $userInfo = api_get_user_info($userId); |
||||||
625 | $mailTemplateManager = new MailTemplateManager(); |
||||||
626 | |||||||
627 | /* MANAGE EVENT WITH MAIL */ |
||||||
628 | if (EventsMail::check_if_using_class('user_registration')) { |
||||||
629 | $values["about_user"] = $return; |
||||||
630 | $values["password"] = $original_password; |
||||||
631 | $values["send_to"] = [$return]; |
||||||
632 | $values["prior_lang"] = null; |
||||||
633 | EventsDispatcher::events('user_registration', $values); |
||||||
634 | } else { |
||||||
635 | $phoneNumber = isset($extra['mobile_phone_number']) ? $extra['mobile_phone_number'] : null; |
||||||
636 | $additionalParameters = [ |
||||||
637 | 'smsType' => SmsPlugin::WELCOME_LOGIN_PASSWORD, |
||||||
638 | 'userId' => $return, |
||||||
639 | 'mobilePhoneNumber' => $phoneNumber, |
||||||
640 | 'password' => $original_password, |
||||||
641 | ]; |
||||||
642 | |||||||
643 | $emailBodyTemplate = ''; |
||||||
644 | if (!empty($emailTemplate)) { |
||||||
645 | if (isset($emailTemplate['content_registration_platform.tpl']) && |
||||||
646 | !empty($emailTemplate['content_registration_platform.tpl']) |
||||||
647 | ) { |
||||||
648 | $emailBodyTemplate = $mailTemplateManager->parseTemplate( |
||||||
649 | $emailTemplate['content_registration_platform.tpl'], |
||||||
650 | $userInfo |
||||||
651 | ); |
||||||
652 | } |
||||||
653 | } |
||||||
654 | |||||||
655 | $twoEmail = api_get_configuration_value('send_two_inscription_confirmation_mail'); |
||||||
656 | if ($twoEmail === true) { |
||||||
657 | $layoutContent = $tplContent->get_template('mail/new_user_first_email_confirmation.tpl'); |
||||||
658 | $emailBody = $tplContent->fetch($layoutContent); |
||||||
659 | |||||||
660 | if (!empty($emailTemplate) && |
||||||
661 | isset($emailTemplate['new_user_first_email_confirmation.tpl']) && |
||||||
662 | !empty($emailTemplate['new_user_first_email_confirmation.tpl']) |
||||||
663 | ) { |
||||||
664 | $emailBody = $mailTemplateManager->parseTemplate( |
||||||
665 | $emailTemplate['new_user_first_email_confirmation.tpl'], |
||||||
666 | $userInfo |
||||||
667 | ); |
||||||
668 | } |
||||||
669 | |||||||
670 | api_mail_html( |
||||||
671 | $recipient_name, |
||||||
672 | $email, |
||||||
673 | $emailSubject, |
||||||
674 | $emailBody, |
||||||
675 | $sender_name, |
||||||
676 | $email_admin, |
||||||
677 | null, |
||||||
678 | null, |
||||||
679 | null, |
||||||
680 | $additionalParameters, |
||||||
681 | $creatorEmail |
||||||
682 | ); |
||||||
683 | |||||||
684 | $layoutContent = $tplContent->get_template('mail/new_user_second_email_confirmation.tpl'); |
||||||
685 | $emailBody = $tplContent->fetch($layoutContent); |
||||||
686 | |||||||
687 | if (!empty($emailTemplate) && |
||||||
688 | isset($emailTemplate['new_user_second_email_confirmation.tpl']) && |
||||||
689 | !empty($emailTemplate['new_user_second_email_confirmation.tpl']) |
||||||
690 | ) { |
||||||
691 | $emailBody = $mailTemplateManager->parseTemplate( |
||||||
692 | $emailTemplate['new_user_second_email_confirmation.tpl'], |
||||||
693 | $userInfo |
||||||
694 | ); |
||||||
695 | } |
||||||
696 | |||||||
697 | api_mail_html( |
||||||
698 | $recipient_name, |
||||||
699 | $email, |
||||||
700 | $emailSubject, |
||||||
701 | $emailBody, |
||||||
702 | $sender_name, |
||||||
703 | $email_admin, |
||||||
704 | null, |
||||||
705 | null, |
||||||
706 | null, |
||||||
707 | $additionalParameters, |
||||||
708 | $creatorEmail |
||||||
709 | ); |
||||||
710 | } else { |
||||||
711 | if (!empty($emailBodyTemplate)) { |
||||||
712 | $emailBody = $emailBodyTemplate; |
||||||
713 | } |
||||||
714 | $sendToInbox = api_get_configuration_value('send_inscription_msg_to_inbox'); |
||||||
715 | if ($sendToInbox) { |
||||||
716 | $adminList = self::get_all_administrators(); |
||||||
717 | $senderId = 1; |
||||||
718 | if (!empty($adminList)) { |
||||||
719 | $adminInfo = current($adminList); |
||||||
720 | $senderId = $adminInfo['user_id']; |
||||||
721 | } |
||||||
722 | |||||||
723 | MessageManager::send_message_simple( |
||||||
724 | $userId, |
||||||
725 | $emailSubject, |
||||||
726 | $emailBody, |
||||||
727 | $senderId |
||||||
728 | ); |
||||||
729 | } else { |
||||||
730 | api_mail_html( |
||||||
731 | $recipient_name, |
||||||
732 | $email, |
||||||
733 | $emailSubject, |
||||||
734 | $emailBody, |
||||||
735 | $sender_name, |
||||||
736 | $email_admin, |
||||||
737 | null, |
||||||
738 | null, |
||||||
739 | null, |
||||||
740 | $additionalParameters, |
||||||
741 | $creatorEmail |
||||||
742 | ); |
||||||
743 | } |
||||||
744 | } |
||||||
745 | |||||||
746 | $notification = api_get_configuration_value('send_notification_when_user_added'); |
||||||
747 | if (!empty($notification) && isset($notification['admins']) && is_array($notification['admins'])) { |
||||||
748 | foreach ($notification['admins'] as $adminId) { |
||||||
749 | $emailSubjectToAdmin = get_lang('UserAdded').': '.api_get_person_name($firstName, $lastName); |
||||||
750 | MessageManager::send_message_simple($adminId, $emailSubjectToAdmin, $emailBody, $userId); |
||||||
751 | } |
||||||
752 | } |
||||||
753 | } |
||||||
754 | |||||||
755 | if ($sendEmailToAllAdmins) { |
||||||
756 | $adminList = self::get_all_administrators(); |
||||||
757 | |||||||
758 | $tplContent = new Template( |
||||||
759 | null, |
||||||
760 | false, |
||||||
761 | false, |
||||||
762 | false, |
||||||
763 | false, |
||||||
764 | false |
||||||
765 | ); |
||||||
766 | // variables for the default template |
||||||
767 | $tplContent->assign('complete_name', stripslashes(api_get_person_name($firstName, $lastName))); |
||||||
768 | $tplContent->assign('user_added', $user); |
||||||
769 | $renderer = FormValidator::getDefaultRenderer(); |
||||||
770 | // Form template |
||||||
771 | $elementTemplate = ' {label}: {element} <br />'; |
||||||
772 | $renderer->setElementTemplate($elementTemplate); |
||||||
773 | /** @var FormValidator $form */ |
||||||
774 | $form->freeze(null, $elementTemplate); |
||||||
775 | $form->removeElement('submit'); |
||||||
776 | $formData = $form->returnForm(); |
||||||
777 | $url = api_get_path(WEB_CODE_PATH).'admin/user_information.php?user_id='.$user->getId(); |
||||||
778 | $tplContent->assign('link', Display::url($url, $url)); |
||||||
779 | $tplContent->assign('form', $formData); |
||||||
780 | |||||||
781 | $layoutContent = $tplContent->get_template('mail/content_registration_platform_to_admin.tpl'); |
||||||
782 | $emailBody = $tplContent->fetch($layoutContent); |
||||||
783 | |||||||
784 | if (!empty($emailTemplate) && |
||||||
785 | isset($emailTemplate['content_registration_platform_to_admin.tpl']) && |
||||||
786 | !empty($emailTemplate['content_registration_platform_to_admin.tpl']) |
||||||
787 | ) { |
||||||
788 | $emailBody = $mailTemplateManager->parseTemplate( |
||||||
789 | $emailTemplate['content_registration_platform_to_admin.tpl'], |
||||||
790 | $userInfo |
||||||
791 | ); |
||||||
792 | } |
||||||
793 | |||||||
794 | $subject = get_lang('UserAdded'); |
||||||
795 | foreach ($adminList as $adminId => $data) { |
||||||
796 | MessageManager::send_message_simple( |
||||||
797 | $adminId, |
||||||
798 | $subject, |
||||||
799 | $emailBody, |
||||||
800 | $userId |
||||||
801 | ); |
||||||
802 | } |
||||||
803 | } |
||||||
804 | /* ENDS MANAGE EVENT WITH MAIL */ |
||||||
805 | } |
||||||
806 | |||||||
807 | if (!empty($hook)) { |
||||||
808 | $hook->setEventData([ |
||||||
809 | 'return' => $userId, |
||||||
810 | 'originalPassword' => $original_password, |
||||||
811 | ]); |
||||||
812 | $hook->notifyCreateUser(HOOK_EVENT_TYPE_POST); |
||||||
813 | } |
||||||
814 | Event::addEvent(LOG_USER_CREATE, LOG_USER_ID, $userId); |
||||||
815 | } else { |
||||||
816 | Display::addFlash( |
||||||
817 | Display::return_message(get_lang('ErrorContactPlatformAdmin')) |
||||||
818 | ); |
||||||
819 | |||||||
820 | return false; |
||||||
821 | } |
||||||
822 | |||||||
823 | return $return; |
||||||
824 | } |
||||||
825 | |||||||
826 | /** |
||||||
827 | * Ensure the CAS-authenticated user exists in the database. |
||||||
828 | * |
||||||
829 | * @param $casUser string the CAS user identifier |
||||||
830 | * |
||||||
831 | * @throws Exception if more than one user share the same CAS user identifier |
||||||
832 | * |
||||||
833 | * @return string|bool the recognised user login name or false if not found |
||||||
834 | */ |
||||||
835 | public static function casUserLoginName($casUser) |
||||||
836 | { |
||||||
837 | $loginName = false; |
||||||
838 | |||||||
839 | // look inside the casUser extra field |
||||||
840 | if (UserManager::is_extra_field_available('cas_user')) { |
||||||
841 | $valueModel = new ExtraFieldValue('user'); |
||||||
842 | $itemList = $valueModel->get_item_id_from_field_variable_and_field_value( |
||||||
843 | 'cas_user', |
||||||
844 | $casUser, |
||||||
845 | false, |
||||||
846 | false, |
||||||
847 | true |
||||||
848 | ); |
||||||
849 | if (false !== $itemList) { |
||||||
850 | // at least one user has $casUser in the 'cas_user' extra field |
||||||
851 | // we attempt to load each candidate user because there might be deleted ones |
||||||
852 | // (extra field values of a deleted user might remain) |
||||||
853 | foreach ($itemList as $item) { |
||||||
854 | $userId = intval($item['item_id']); |
||||||
855 | $user = UserManager::getRepository()->find($userId); |
||||||
856 | if (!is_null($user)) { |
||||||
857 | if (false === $loginName) { |
||||||
858 | $loginName = $user->getUsername(); |
||||||
859 | } else { |
||||||
860 | throw new Exception(get_lang('MoreThanOneUserMatched')); |
||||||
861 | } |
||||||
862 | } |
||||||
863 | } |
||||||
864 | } |
||||||
865 | } |
||||||
866 | |||||||
867 | if (false === $loginName) { |
||||||
868 | // no matching 'cas_user' extra field value, or no such extra field |
||||||
869 | // falling back to the old behaviour: $casUser must be the login name |
||||||
870 | $userId = UserManager::get_user_id_from_username($casUser); |
||||||
871 | if (false !== $userId) { |
||||||
872 | $loginName = $casUser; |
||||||
873 | } |
||||||
874 | } |
||||||
875 | |||||||
876 | return $loginName; |
||||||
877 | } |
||||||
878 | |||||||
879 | /** |
||||||
880 | * Checks the availability of extra field 'cas_user' |
||||||
881 | * and creates it if missing. |
||||||
882 | * |
||||||
883 | * @throws Exception on failure |
||||||
884 | */ |
||||||
885 | public static function ensureCASUserExtraFieldExists() |
||||||
886 | { |
||||||
887 | if (!self::is_extra_field_available('cas_user')) { |
||||||
888 | $extraField = new ExtraField('user'); |
||||||
889 | if (false === $extraField->save( |
||||||
890 | [ |
||||||
891 | 'variable' => 'cas_user', |
||||||
892 | 'field_type' => ExtraField::FIELD_TYPE_TEXT, |
||||||
893 | 'display_text' => get_lang('CAS User Identifier'), |
||||||
894 | 'visible_to_self' => true, |
||||||
895 | 'filter' => true, |
||||||
896 | ] |
||||||
897 | )) { |
||||||
898 | throw new Exception(get_lang('FailedToCreateExtraFieldCasUser')); |
||||||
899 | } |
||||||
900 | |||||||
901 | $rules = api_get_configuration_value('cas_user_map'); |
||||||
902 | if (!empty($rules) && isset($rules['extra'])) { |
||||||
903 | foreach ($rules['extra'] as $extra) { |
||||||
904 | $extraField->save( |
||||||
905 | [ |
||||||
906 | 'variable' => $extra, |
||||||
907 | 'field_type' => ExtraField::FIELD_TYPE_TEXT, |
||||||
908 | 'display_text' => $extra, |
||||||
909 | 'visible_to_self' => false, |
||||||
910 | 'filter' => false, |
||||||
911 | ] |
||||||
912 | ); |
||||||
913 | } |
||||||
914 | } |
||||||
915 | } |
||||||
916 | } |
||||||
917 | |||||||
918 | /** |
||||||
919 | * Create a CAS-authenticated user from scratch, from its CAS user identifier, with temporary default values. |
||||||
920 | * |
||||||
921 | * @param string $casUser the CAS user identifier |
||||||
922 | * |
||||||
923 | * @throws Exception on error |
||||||
924 | * |
||||||
925 | * @return string the login name of the new user |
||||||
926 | */ |
||||||
927 | public static function createCASAuthenticatedUserFromScratch($casUser) |
||||||
928 | { |
||||||
929 | self::ensureCASUserExtraFieldExists(); |
||||||
930 | |||||||
931 | $loginName = 'cas_user_'.$casUser; |
||||||
932 | $defaultValue = get_lang('EditInProfile'); |
||||||
933 | $defaultEmailValue = get_lang('EditInProfile'); |
||||||
934 | require_once __DIR__.'/../../auth/external_login/functions.inc.php'; |
||||||
935 | if ('true' === api_get_setting('login_is_email')) { |
||||||
936 | $defaultEmailValue = $casUser; |
||||||
937 | } |
||||||
938 | $userId = external_add_user( |
||||||
939 | [ |
||||||
940 | 'username' => $loginName, |
||||||
941 | 'auth_source' => CAS_AUTH_SOURCE, |
||||||
942 | 'firstname' => $defaultValue, |
||||||
943 | 'lastname' => $defaultValue, |
||||||
944 | 'email' => $defaultEmailValue, |
||||||
945 | ] |
||||||
946 | ); |
||||||
947 | if (false === $userId) { |
||||||
948 | throw new Exception(get_lang('FailedUserCreation')); |
||||||
949 | } |
||||||
950 | // Not checking function update_extra_field_value return value because not reliable |
||||||
951 | self::update_extra_field_value($userId, 'cas_user', $casUser); |
||||||
952 | |||||||
953 | return $loginName; |
||||||
954 | } |
||||||
955 | |||||||
956 | public static function updateCasUser($_user) |
||||||
957 | { |
||||||
958 | $rules = api_get_configuration_value('cas_user_map'); |
||||||
959 | |||||||
960 | if (empty($_user)) { |
||||||
961 | return false; |
||||||
962 | } |
||||||
963 | |||||||
964 | if (!empty($rules)) { |
||||||
965 | $userEntity = api_get_user_entity($_user['id']); |
||||||
966 | $attributes = phpCAS::getAttributes(); |
||||||
967 | if (isset($rules['fields'])) { |
||||||
968 | $isAdmin = false; |
||||||
969 | foreach ($rules['fields'] as $field => $attributeName) { |
||||||
970 | if (!isset($attributes[$attributeName])) { |
||||||
971 | continue; |
||||||
972 | } |
||||||
973 | $value = $attributes[$attributeName]; |
||||||
974 | // Check replace. |
||||||
975 | if (isset($rules['replace'][$attributeName])) { |
||||||
976 | $value = $rules['replace'][$attributeName][$value]; |
||||||
977 | } |
||||||
978 | |||||||
979 | switch ($field) { |
||||||
980 | case 'email': |
||||||
981 | $userEntity->setEmail($value); |
||||||
982 | break; |
||||||
983 | case 'firstname': |
||||||
984 | $userEntity->setFirstname($value); |
||||||
985 | break; |
||||||
986 | case 'lastname': |
||||||
987 | $userEntity->setLastname($value); |
||||||
988 | break; |
||||||
989 | case 'active': |
||||||
990 | $userEntity->setActive('false' === $value); |
||||||
991 | break; |
||||||
992 | case 'status': |
||||||
993 | if (PLATFORM_ADMIN === (int) $value) { |
||||||
994 | $value = COURSEMANAGER; |
||||||
995 | $isAdmin = true; |
||||||
996 | } |
||||||
997 | $userEntity->setStatus($value); |
||||||
998 | break; |
||||||
999 | } |
||||||
1000 | |||||||
1001 | Database::getManager()->persist($userEntity); |
||||||
1002 | Database::getManager()->flush(); |
||||||
1003 | |||||||
1004 | if ($isAdmin) { |
||||||
1005 | self::addUserAsAdmin($userEntity); |
||||||
1006 | } |
||||||
1007 | } |
||||||
1008 | } |
||||||
1009 | |||||||
1010 | if (isset($rules['extra'])) { |
||||||
1011 | foreach ($rules['extra'] as $variable) { |
||||||
1012 | if (isset($attributes[$variable])) { |
||||||
1013 | self::update_extra_field_value( |
||||||
1014 | $_user['id'], |
||||||
1015 | $variable, |
||||||
1016 | $attributes[$variable] |
||||||
1017 | ); |
||||||
1018 | } |
||||||
1019 | } |
||||||
1020 | } |
||||||
1021 | } |
||||||
1022 | } |
||||||
1023 | |||||||
1024 | /** |
||||||
1025 | * Create a CAS-authenticated user from LDAP, from its CAS user identifier. |
||||||
1026 | * |
||||||
1027 | * @param $casUser |
||||||
1028 | * |
||||||
1029 | * @throws Exception |
||||||
1030 | * |
||||||
1031 | * @return string login name of the new user |
||||||
1032 | */ |
||||||
1033 | public static function createCASAuthenticatedUserFromLDAP($casUser) |
||||||
1034 | { |
||||||
1035 | self::ensureCASUserExtraFieldExists(); |
||||||
1036 | |||||||
1037 | require_once __DIR__.'/../../auth/external_login/ldap.inc.php'; |
||||||
1038 | $login = extldapCasUserLogin($casUser); |
||||||
1039 | if (false !== $login) { |
||||||
1040 | $ldapUser = extldap_authenticate($login, 'nopass', true); |
||||||
1041 | if (false !== $ldapUser) { |
||||||
1042 | require_once __DIR__.'/../../auth/external_login/functions.inc.php'; |
||||||
1043 | $user = extldap_get_chamilo_user($ldapUser); |
||||||
1044 | $user['username'] = $login; |
||||||
1045 | $user['auth_source'] = CAS_AUTH_SOURCE; |
||||||
1046 | $userId = external_add_user($user); |
||||||
1047 | if (false !== $userId) { |
||||||
1048 | // Not checking function update_extra_field_value return value because not reliable |
||||||
1049 | self::update_extra_field_value($userId, 'cas_user', $casUser); |
||||||
1050 | |||||||
1051 | return $login; |
||||||
1052 | } else { |
||||||
1053 | throw new Exception('Could not create the new user '.$login); |
||||||
1054 | } |
||||||
1055 | } else { |
||||||
1056 | throw new Exception('Could not load the new user from LDAP using its login '.$login); |
||||||
0 ignored issues
–
show
Are you sure
$login of type string|true can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
1057 | } |
||||||
1058 | } else { |
||||||
1059 | throw new Exception('Could not find the new user from LDAP using its cas user identifier '.$casUser); |
||||||
1060 | } |
||||||
1061 | } |
||||||
1062 | |||||||
1063 | /** |
||||||
1064 | * updates user record in database from its LDAP record |
||||||
1065 | * copies relevant LDAP attribute values : firstname, lastname and email. |
||||||
1066 | * |
||||||
1067 | * @param $login string the user login name |
||||||
1068 | * |
||||||
1069 | * @throws Exception when the user login name is not found in the LDAP or in the database |
||||||
1070 | */ |
||||||
1071 | public static function updateUserFromLDAP($login) |
||||||
1072 | { |
||||||
1073 | require_once __DIR__.'/../../auth/external_login/ldap.inc.php'; |
||||||
1074 | |||||||
1075 | $ldapUser = extldap_authenticate($login, 'nopass', true); |
||||||
1076 | if (false === $ldapUser) { |
||||||
1077 | throw new Exception(get_lang('NoSuchUserInLDAP')); |
||||||
1078 | } |
||||||
1079 | |||||||
1080 | $user = extldap_get_chamilo_user($ldapUser); |
||||||
1081 | $userInfo = api_get_user_info_from_username($login); |
||||||
1082 | if (false === $userInfo) { |
||||||
1083 | throw new Exception(get_lang('NoSuchUserInInternalDatabase')); |
||||||
1084 | } |
||||||
1085 | |||||||
1086 | $userId = UserManager::update_user( |
||||||
1087 | $userInfo['user_id'], |
||||||
1088 | $user["firstname"], |
||||||
1089 | $user["lastname"], |
||||||
1090 | $login, |
||||||
1091 | null, |
||||||
1092 | $userInfo['auth_source'], |
||||||
1093 | $user["email"], |
||||||
1094 | $userInfo['status'], |
||||||
1095 | $userInfo['official_code'], |
||||||
1096 | $userInfo['phone'], |
||||||
1097 | $userInfo['picture_uri'], |
||||||
1098 | $userInfo['expiration_date'], |
||||||
1099 | $userInfo['active'], |
||||||
1100 | $userInfo['creator_id'], |
||||||
1101 | $userInfo['hr_dept_id'], |
||||||
1102 | null, |
||||||
1103 | $userInfo['language'] |
||||||
1104 | ); |
||||||
1105 | if (false === $userId) { |
||||||
1106 | throw new Exception(get_lang('CouldNotUpdateUser')); |
||||||
1107 | } |
||||||
1108 | } |
||||||
1109 | |||||||
1110 | /** |
||||||
1111 | * Can user be deleted? This function checks whether there's a course |
||||||
1112 | * in which the given user is the |
||||||
1113 | * only course administrator. If that is the case, the user can't be |
||||||
1114 | * deleted because the course would remain without a course admin. |
||||||
1115 | * |
||||||
1116 | * @param int $user_id The user id |
||||||
1117 | * |
||||||
1118 | * @return bool true if user can be deleted |
||||||
1119 | * |
||||||
1120 | * @assert (null) === false |
||||||
1121 | * @assert (-1) === false |
||||||
1122 | * @assert ('abc') === false |
||||||
1123 | */ |
||||||
1124 | public static function canDeleteUser($user_id) |
||||||
1125 | { |
||||||
1126 | $deny = api_get_configuration_value('deny_delete_users'); |
||||||
1127 | |||||||
1128 | if ($deny) { |
||||||
1129 | return false; |
||||||
1130 | } |
||||||
1131 | |||||||
1132 | $table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
||||||
1133 | $user_id = (int) $user_id; |
||||||
1134 | |||||||
1135 | if (empty($user_id)) { |
||||||
1136 | return false; |
||||||
1137 | } |
||||||
1138 | |||||||
1139 | $res = Database::query( |
||||||
1140 | "SELECT c_id FROM $table_course_user WHERE status = 1 AND user_id = $user_id" |
||||||
1141 | ); |
||||||
1142 | while ($course = Database::fetch_assoc($res)) { |
||||||
1143 | $sql = Database::query( |
||||||
1144 | "SELECT COUNT(id) number FROM $table_course_user WHERE status = 1 AND c_id = {$course['c_id']}" |
||||||
1145 | ); |
||||||
1146 | $res2 = Database::fetch_assoc($sql); |
||||||
1147 | |||||||
1148 | if ($res2['number'] == 1) { |
||||||
1149 | return false; |
||||||
1150 | } |
||||||
1151 | } |
||||||
1152 | |||||||
1153 | return true; |
||||||
1154 | } |
||||||
1155 | |||||||
1156 | /** |
||||||
1157 | * Delete a user from the platform, and all its belongings. This is a |
||||||
1158 | * very dangerous function that should only be accessible by |
||||||
1159 | * super-admins. Other roles should only be able to disable a user, |
||||||
1160 | * which removes access to the platform but doesn't delete anything. |
||||||
1161 | * |
||||||
1162 | * @param int The ID of th user to be deleted |
||||||
1163 | * |
||||||
1164 | * @throws Exception |
||||||
1165 | * |
||||||
1166 | * @return bool true if user is successfully deleted, false otherwise |
||||||
1167 | * @assert (null) === false |
||||||
1168 | * @assert ('abc') === false |
||||||
1169 | */ |
||||||
1170 | public static function delete_user($user_id) |
||||||
1171 | { |
||||||
1172 | $user_id = (int) $user_id; |
||||||
1173 | |||||||
1174 | if (empty($user_id)) { |
||||||
1175 | return false; |
||||||
1176 | } |
||||||
1177 | |||||||
1178 | if (!self::canDeleteUser($user_id)) { |
||||||
1179 | return false; |
||||||
1180 | } |
||||||
1181 | |||||||
1182 | $table_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
1183 | $usergroup_rel_user = Database::get_main_table(TABLE_USERGROUP_REL_USER); |
||||||
1184 | $table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
||||||
1185 | $table_course = Database::get_main_table(TABLE_MAIN_COURSE); |
||||||
1186 | $table_session = Database::get_main_table(TABLE_MAIN_SESSION); |
||||||
1187 | $table_admin = Database::get_main_table(TABLE_MAIN_ADMIN); |
||||||
1188 | $table_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER); |
||||||
1189 | $table_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
||||||
1190 | $table_group = Database::get_course_table(TABLE_GROUP_USER); |
||||||
1191 | $table_work = Database::get_course_table(TABLE_STUDENT_PUBLICATION); |
||||||
1192 | |||||||
1193 | // Unsubscribe the user from all groups in all his courses |
||||||
1194 | $sql = "SELECT c.id |
||||||
1195 | FROM $table_course c |
||||||
1196 | INNER JOIN $table_course_user cu |
||||||
1197 | ON (c.id = cu.c_id) |
||||||
1198 | WHERE |
||||||
1199 | cu.user_id = '".$user_id."' AND |
||||||
1200 | relation_type<>".COURSE_RELATION_TYPE_RRHH." |
||||||
1201 | "; |
||||||
1202 | |||||||
1203 | $res = Database::query($sql); |
||||||
1204 | while ($course = Database::fetch_object($res)) { |
||||||
1205 | $sql = "DELETE FROM $table_group |
||||||
1206 | WHERE c_id = {$course->id} AND user_id = $user_id"; |
||||||
1207 | Database::query($sql); |
||||||
1208 | } |
||||||
1209 | |||||||
1210 | // Unsubscribe user from usergroup_rel_user |
||||||
1211 | $sql = "DELETE FROM $usergroup_rel_user WHERE user_id = '".$user_id."'"; |
||||||
1212 | Database::query($sql); |
||||||
1213 | |||||||
1214 | // Unsubscribe user from all courses |
||||||
1215 | $sql = "DELETE FROM $table_course_user WHERE user_id = '".$user_id."'"; |
||||||
1216 | Database::query($sql); |
||||||
1217 | |||||||
1218 | // Unsubscribe user from all courses in sessions |
||||||
1219 | $sql = "DELETE FROM $table_session_course_user WHERE user_id = '".$user_id."'"; |
||||||
1220 | Database::query($sql); |
||||||
1221 | |||||||
1222 | // If the user was added as a id_coach then set the current admin as coach see BT# |
||||||
1223 | $currentUserId = api_get_user_id(); |
||||||
1224 | $sql = "UPDATE $table_session SET id_coach = $currentUserId |
||||||
1225 | WHERE id_coach = '".$user_id."'"; |
||||||
1226 | Database::query($sql); |
||||||
1227 | |||||||
1228 | $sql = "UPDATE $table_session SET session_admin_id = $currentUserId |
||||||
1229 | WHERE session_admin_id = '".$user_id."'"; |
||||||
1230 | Database::query($sql); |
||||||
1231 | |||||||
1232 | // Unsubscribe user from all sessions |
||||||
1233 | $sql = "DELETE FROM $table_session_user |
||||||
1234 | WHERE user_id = '".$user_id."'"; |
||||||
1235 | Database::query($sql); |
||||||
1236 | |||||||
1237 | if (api_get_configuration_value('plugin_redirection_enabled')) { |
||||||
1238 | RedirectionPlugin::deleteUserRedirection($user_id); |
||||||
1239 | } |
||||||
1240 | |||||||
1241 | $user_info = api_get_user_info($user_id); |
||||||
1242 | |||||||
1243 | try { |
||||||
1244 | self::deleteUserFiles($user_id); |
||||||
1245 | } catch (Exception $exception) { |
||||||
1246 | error_log('Delete user exception: '.$exception->getMessage()); |
||||||
1247 | } |
||||||
1248 | |||||||
1249 | // Delete the personal course categories |
||||||
1250 | $course_cat_table = Database::get_main_table(TABLE_USER_COURSE_CATEGORY); |
||||||
1251 | $sql = "DELETE FROM $course_cat_table WHERE user_id = '".$user_id."'"; |
||||||
1252 | Database::query($sql); |
||||||
1253 | |||||||
1254 | // Delete user from the admin table |
||||||
1255 | $sql = "DELETE FROM $table_admin WHERE user_id = '".$user_id."'"; |
||||||
1256 | Database::query($sql); |
||||||
1257 | |||||||
1258 | // Delete the personal agenda-items from this user |
||||||
1259 | $agenda_table = Database::get_main_table(TABLE_PERSONAL_AGENDA); |
||||||
1260 | $sql = "DELETE FROM $agenda_table WHERE user = '".$user_id."'"; |
||||||
1261 | Database::query($sql); |
||||||
1262 | |||||||
1263 | $gradebook_results_table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_RESULT); |
||||||
1264 | $sql = 'DELETE FROM '.$gradebook_results_table.' WHERE user_id = '.$user_id; |
||||||
1265 | Database::query($sql); |
||||||
1266 | |||||||
1267 | $extraFieldValue = new ExtraFieldValue('user'); |
||||||
1268 | $extraFieldValue->deleteValuesByItem($user_id); |
||||||
1269 | |||||||
1270 | UrlManager::deleteUserFromAllUrls($user_id); |
||||||
1271 | |||||||
1272 | if (api_get_setting('allow_social_tool') === 'true') { |
||||||
1273 | $userGroup = new UserGroup(); |
||||||
1274 | //Delete user from portal groups |
||||||
1275 | $group_list = $userGroup->get_groups_by_user($user_id); |
||||||
1276 | if (!empty($group_list)) { |
||||||
1277 | foreach ($group_list as $group_id => $data) { |
||||||
1278 | $userGroup->delete_user_rel_group($user_id, $group_id); |
||||||
1279 | } |
||||||
1280 | } |
||||||
1281 | |||||||
1282 | // Delete user from friend lists |
||||||
1283 | SocialManager::remove_user_rel_user($user_id, true); |
||||||
1284 | } |
||||||
1285 | |||||||
1286 | // Removing survey invitation |
||||||
1287 | SurveyManager::delete_all_survey_invitations_by_user($user_id); |
||||||
1288 | |||||||
1289 | // Delete students works |
||||||
1290 | $sql = "DELETE FROM $table_work WHERE user_id = $user_id AND c_id <> 0"; |
||||||
1291 | Database::query($sql); |
||||||
1292 | |||||||
1293 | $sql = "UPDATE c_item_property SET to_user_id = NULL |
||||||
1294 | WHERE to_user_id = '".$user_id."'"; |
||||||
1295 | Database::query($sql); |
||||||
1296 | |||||||
1297 | $sql = "UPDATE c_item_property SET insert_user_id = NULL |
||||||
1298 | WHERE insert_user_id = '".$user_id."'"; |
||||||
1299 | Database::query($sql); |
||||||
1300 | |||||||
1301 | $sql = "UPDATE c_item_property SET lastedit_user_id = NULL |
||||||
1302 | WHERE lastedit_user_id = '".$user_id."'"; |
||||||
1303 | Database::query($sql); |
||||||
1304 | |||||||
1305 | // Skills |
||||||
1306 | $em = Database::getManager(); |
||||||
1307 | |||||||
1308 | $criteria = ['user' => $user_id]; |
||||||
1309 | $skills = $em->getRepository('ChamiloCoreBundle:SkillRelUser')->findBy($criteria); |
||||||
1310 | if ($skills) { |
||||||
1311 | /** @var SkillRelUser $skill */ |
||||||
1312 | foreach ($skills as $skill) { |
||||||
1313 | $comments = $skill->getComments(); |
||||||
1314 | if ($comments) { |
||||||
1315 | /** @var SkillRelUserComment $comment */ |
||||||
1316 | foreach ($comments as $comment) { |
||||||
1317 | $em->remove($comment); |
||||||
1318 | } |
||||||
1319 | } |
||||||
1320 | $em->remove($skill); |
||||||
1321 | } |
||||||
1322 | $em->flush(); |
||||||
1323 | } |
||||||
1324 | |||||||
1325 | // ExtraFieldSavedSearch |
||||||
1326 | $criteria = ['user' => $user_id]; |
||||||
1327 | $searchList = $em->getRepository('ChamiloCoreBundle:ExtraFieldSavedSearch')->findBy($criteria); |
||||||
1328 | if ($searchList) { |
||||||
1329 | foreach ($searchList as $search) { |
||||||
1330 | $em->remove($search); |
||||||
1331 | } |
||||||
1332 | $em->flush(); |
||||||
1333 | } |
||||||
1334 | |||||||
1335 | $connection = Database::getManager()->getConnection(); |
||||||
1336 | $tableExists = $connection->getSchemaManager()->tablesExist(['plugin_bbb_room']); |
||||||
1337 | if ($tableExists) { |
||||||
1338 | // Delete user from database |
||||||
1339 | $sql = "DELETE FROM plugin_bbb_room WHERE participant_id = $user_id"; |
||||||
1340 | Database::query($sql); |
||||||
1341 | } |
||||||
1342 | |||||||
1343 | // Delete user/ticket relationships :( |
||||||
1344 | $tableExists = $connection->getSchemaManager()->tablesExist(['ticket_ticket']); |
||||||
1345 | if ($tableExists) { |
||||||
1346 | TicketManager::deleteUserFromTicketSystem($user_id); |
||||||
1347 | } |
||||||
1348 | |||||||
1349 | $tableExists = $connection->getSchemaManager()->tablesExist(['c_lp_category_user']); |
||||||
1350 | if ($tableExists) { |
||||||
1351 | $sql = "DELETE FROM c_lp_category_user WHERE user_id = $user_id"; |
||||||
1352 | Database::query($sql); |
||||||
1353 | } |
||||||
1354 | |||||||
1355 | $app_plugin = new AppPlugin(); |
||||||
1356 | $app_plugin->performActionsWhenDeletingItem('user', $user_id); |
||||||
1357 | |||||||
1358 | // Delete user from database |
||||||
1359 | $sql = "DELETE FROM $table_user WHERE id = '".$user_id."'"; |
||||||
1360 | Database::query($sql); |
||||||
1361 | |||||||
1362 | // Add event to system log |
||||||
1363 | $user_id_manager = api_get_user_id(); |
||||||
1364 | |||||||
1365 | Event::addEvent( |
||||||
1366 | LOG_USER_DELETE, |
||||||
1367 | LOG_USER_ID, |
||||||
1368 | $user_id, |
||||||
1369 | api_get_utc_datetime(), |
||||||
1370 | $user_id_manager |
||||||
1371 | ); |
||||||
1372 | |||||||
1373 | Event::addEvent( |
||||||
1374 | LOG_USER_DELETE, |
||||||
1375 | LOG_USER_OBJECT, |
||||||
1376 | $user_info, |
||||||
1377 | api_get_utc_datetime(), |
||||||
1378 | $user_id_manager |
||||||
1379 | ); |
||||||
1380 | $cacheAvailable = api_get_configuration_value('apc'); |
||||||
1381 | if ($cacheAvailable === true) { |
||||||
1382 | $apcVar = api_get_configuration_value('apc_prefix').'userinfo_'.$user_id; |
||||||
1383 | if (apcu_exists($apcVar)) { |
||||||
1384 | apcu_delete($apcVar); |
||||||
1385 | } |
||||||
1386 | } |
||||||
1387 | |||||||
1388 | return true; |
||||||
1389 | } |
||||||
1390 | |||||||
1391 | /** |
||||||
1392 | * Deletes users completely. Can be called either as: |
||||||
1393 | * - UserManager::delete_users(1, 2, 3); or |
||||||
1394 | * - UserManager::delete_users(array(1, 2, 3));. |
||||||
1395 | * |
||||||
1396 | * @param array|int $ids |
||||||
1397 | * |
||||||
1398 | * @return bool True if at least one user was successfuly deleted. False otherwise. |
||||||
1399 | * |
||||||
1400 | * @author Laurent Opprecht |
||||||
1401 | * |
||||||
1402 | * @uses \UserManager::delete_user() to actually delete each user |
||||||
1403 | * @assert (null) === false |
||||||
1404 | * @assert (-1) === false |
||||||
1405 | * @assert (array(-1)) === false |
||||||
1406 | */ |
||||||
1407 | public static function delete_users($ids = []) |
||||||
1408 | { |
||||||
1409 | $result = false; |
||||||
1410 | $ids = is_array($ids) ? $ids : func_get_args(); |
||||||
1411 | if (!is_array($ids) || count($ids) == 0) { |
||||||
1412 | return false; |
||||||
1413 | } |
||||||
1414 | $ids = array_map('intval', $ids); |
||||||
1415 | foreach ($ids as $id) { |
||||||
1416 | if (empty($id) || $id < 1) { |
||||||
1417 | continue; |
||||||
1418 | } |
||||||
1419 | $deleted = self::delete_user($id); |
||||||
1420 | $result = $deleted || $result; |
||||||
1421 | } |
||||||
1422 | |||||||
1423 | return $result; |
||||||
1424 | } |
||||||
1425 | |||||||
1426 | /** |
||||||
1427 | * Disable users. Can be called either as: |
||||||
1428 | * - UserManager::deactivate_users(1, 2, 3); |
||||||
1429 | * - UserManager::deactivate_users(array(1, 2, 3));. |
||||||
1430 | * |
||||||
1431 | * @param array|int $ids |
||||||
1432 | * |
||||||
1433 | * @return bool |
||||||
1434 | * |
||||||
1435 | * @author Laurent Opprecht |
||||||
1436 | * @assert (null) === false |
||||||
1437 | * @assert (array(-1)) === false |
||||||
1438 | */ |
||||||
1439 | public static function deactivate_users($ids = []) |
||||||
1440 | { |
||||||
1441 | if (empty($ids)) { |
||||||
1442 | return false; |
||||||
1443 | } |
||||||
1444 | |||||||
1445 | $table_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
1446 | |||||||
1447 | $ids = is_array($ids) ? $ids : func_get_args(); |
||||||
1448 | $ids = array_map('intval', $ids); |
||||||
1449 | $ids = implode(',', $ids); |
||||||
1450 | |||||||
1451 | $sql = "UPDATE $table_user SET active = 0 WHERE id IN ($ids)"; |
||||||
1452 | $r = Database::query($sql); |
||||||
1453 | if ($r !== false) { |
||||||
1454 | Event::addEvent(LOG_USER_DISABLE, LOG_USER_ID, $ids); |
||||||
1455 | |||||||
1456 | return true; |
||||||
1457 | } |
||||||
1458 | |||||||
1459 | return false; |
||||||
1460 | } |
||||||
1461 | |||||||
1462 | /** |
||||||
1463 | * Enable users. Can be called either as: |
||||||
1464 | * - UserManager::activate_users(1, 2, 3); |
||||||
1465 | * - UserManager::activate_users(array(1, 2, 3));. |
||||||
1466 | * |
||||||
1467 | * @param array|int IDs of the users to enable |
||||||
1468 | * |
||||||
1469 | * @return bool |
||||||
1470 | * |
||||||
1471 | * @author Laurent Opprecht |
||||||
1472 | * @assert (null) === false |
||||||
1473 | * @assert (array(-1)) === false |
||||||
1474 | */ |
||||||
1475 | public static function activate_users($ids = []) |
||||||
1476 | { |
||||||
1477 | if (empty($ids)) { |
||||||
1478 | return false; |
||||||
1479 | } |
||||||
1480 | |||||||
1481 | $table_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
1482 | |||||||
1483 | $ids = is_array($ids) ? $ids : func_get_args(); |
||||||
1484 | $ids = array_map('intval', $ids); |
||||||
1485 | $ids = implode(',', $ids); |
||||||
1486 | |||||||
1487 | $sql = "UPDATE $table_user SET active = 1 WHERE id IN ($ids)"; |
||||||
1488 | $r = Database::query($sql); |
||||||
1489 | if ($r !== false) { |
||||||
1490 | Event::addEvent(LOG_USER_ENABLE, LOG_USER_ID, $ids); |
||||||
1491 | |||||||
1492 | return true; |
||||||
1493 | } |
||||||
1494 | |||||||
1495 | return false; |
||||||
1496 | } |
||||||
1497 | |||||||
1498 | /** |
||||||
1499 | * Update user information with new openid. |
||||||
1500 | * |
||||||
1501 | * @param int $user_id |
||||||
1502 | * @param string $openid |
||||||
1503 | * |
||||||
1504 | * @return bool true if the user information was updated |
||||||
1505 | * @assert (false,'') === false |
||||||
1506 | * @assert (-1,'') === false |
||||||
1507 | */ |
||||||
1508 | public static function update_openid($user_id, $openid) |
||||||
1509 | { |
||||||
1510 | $table_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
1511 | if ($user_id != strval(intval($user_id))) { |
||||||
1512 | return false; |
||||||
1513 | } |
||||||
1514 | if ($user_id === false) { |
||||||
1515 | return false; |
||||||
1516 | } |
||||||
1517 | $sql = "UPDATE $table_user SET |
||||||
1518 | openid='".Database::escape_string($openid)."'"; |
||||||
1519 | $sql .= " WHERE id= $user_id"; |
||||||
1520 | |||||||
1521 | if (Database::query($sql) !== false) { |
||||||
1522 | return true; |
||||||
1523 | } |
||||||
1524 | |||||||
1525 | return false; |
||||||
1526 | } |
||||||
1527 | |||||||
1528 | /** |
||||||
1529 | * Update user information with all the parameters passed to this function. |
||||||
1530 | * |
||||||
1531 | * @param int $user_id The ID of the user to be updated |
||||||
1532 | * @param string $firstname The user's firstname |
||||||
1533 | * @param string $lastname The user's lastname |
||||||
1534 | * @param string $username The user's username (login) |
||||||
1535 | * @param string $password The user's password |
||||||
1536 | * @param string $auth_source The authentication source (default: "platform") |
||||||
1537 | * @param string $email The user's e-mail address |
||||||
1538 | * @param int $status The user's status |
||||||
1539 | * @param string $official_code The user's official code (usually just an internal institutional code) |
||||||
1540 | * @param string $phone The user's phone number |
||||||
1541 | * @param string $picture_uri The user's picture URL (internal to the Chamilo directory) |
||||||
1542 | * @param string $expiration_date The date at which this user will be automatically disabled |
||||||
1543 | * @param int $active Whether this account needs to be enabled (1) or disabled (0) |
||||||
1544 | * @param int $creator_id The user ID of the person who registered this user (optional, defaults to null) |
||||||
1545 | * @param int $hr_dept_id The department of HR in which the user is registered (optional, defaults to 0) |
||||||
1546 | * @param array $extra Additional fields to add to this user as extra fields (defaults to null) |
||||||
1547 | * @param string $language The language to which the user account will be set |
||||||
1548 | * @param string $encrypt_method The cipher method. This parameter is deprecated. It will use the system's default |
||||||
1549 | * @param bool $send_email Whether to send an e-mail to the user after the update is complete |
||||||
1550 | * @param int $reset_password Method used to reset password (0, 1, 2 or 3 - see usage examples for details) |
||||||
1551 | * @param string $address |
||||||
1552 | * @param array $emailTemplate |
||||||
1553 | * |
||||||
1554 | * @return bool|int False on error, or the user ID if the user information was updated |
||||||
1555 | * @assert (false, false, false, false, false, false, false, false, false, false, false, false, false) === false |
||||||
1556 | */ |
||||||
1557 | public static function update_user( |
||||||
1558 | $user_id, |
||||||
1559 | $firstname, |
||||||
1560 | $lastname, |
||||||
1561 | $username, |
||||||
1562 | $password, |
||||||
1563 | $auth_source, |
||||||
1564 | $email, |
||||||
1565 | $status, |
||||||
1566 | $official_code, |
||||||
1567 | $phone, |
||||||
1568 | $picture_uri, |
||||||
1569 | $expiration_date, |
||||||
1570 | $active, |
||||||
1571 | $creator_id = null, |
||||||
1572 | $hr_dept_id = 0, |
||||||
1573 | $extra = null, |
||||||
1574 | $language = 'english', |
||||||
1575 | $encrypt_method = '', |
||||||
1576 | $send_email = false, |
||||||
1577 | $reset_password = 0, |
||||||
1578 | $address = null, |
||||||
1579 | $emailTemplate = [] |
||||||
1580 | ) { |
||||||
1581 | $hook = HookUpdateUser::create(); |
||||||
1582 | if (!empty($hook)) { |
||||||
1583 | $hook->notifyUpdateUser(HOOK_EVENT_TYPE_PRE); |
||||||
1584 | } |
||||||
1585 | $original_password = $password; |
||||||
1586 | $user_id = (int) $user_id; |
||||||
1587 | $creator_id = (int) $creator_id; |
||||||
1588 | |||||||
1589 | if (empty($user_id)) { |
||||||
1590 | return false; |
||||||
1591 | } |
||||||
1592 | |||||||
1593 | $userManager = self::getManager(); |
||||||
1594 | /** @var User $user */ |
||||||
1595 | $user = self::getRepository()->find($user_id); |
||||||
1596 | |||||||
1597 | if (empty($user)) { |
||||||
1598 | return false; |
||||||
1599 | } |
||||||
1600 | |||||||
1601 | if ($reset_password == 0) { |
||||||
1602 | $password = null; |
||||||
1603 | $auth_source = $user->getAuthSource(); |
||||||
1604 | } elseif ($reset_password == 1) { |
||||||
1605 | $original_password = $password = api_generate_password(); |
||||||
1606 | $auth_source = PLATFORM_AUTH_SOURCE; |
||||||
1607 | } elseif ($reset_password == 2) { |
||||||
1608 | //$password = $password; |
||||||
1609 | $auth_source = PLATFORM_AUTH_SOURCE; |
||||||
1610 | } elseif ($reset_password == 3) { |
||||||
1611 | //$password = $password; |
||||||
1612 | //$auth_source = $auth_source; |
||||||
1613 | } |
||||||
1614 | |||||||
1615 | // Checking the user language |
||||||
1616 | $languages = api_get_languages(); |
||||||
1617 | if (!in_array($language, $languages['folder'])) { |
||||||
1618 | $language = api_get_setting('platformLanguage'); |
||||||
1619 | } |
||||||
1620 | |||||||
1621 | $change_active = 0; |
||||||
1622 | $isUserActive = $user->getActive(); |
||||||
1623 | if ($isUserActive != $active) { |
||||||
1624 | $change_active = 1; |
||||||
1625 | } |
||||||
1626 | |||||||
1627 | $originalUsername = $user->getUsername(); |
||||||
1628 | |||||||
1629 | // If username is different from original then check if it exists. |
||||||
1630 | if ($originalUsername !== $username) { |
||||||
1631 | $available = self::is_username_available($username); |
||||||
1632 | if ($available === false) { |
||||||
1633 | return false; |
||||||
1634 | } |
||||||
1635 | } |
||||||
1636 | |||||||
1637 | if (!empty($expiration_date)) { |
||||||
1638 | $expiration_date = api_get_utc_datetime($expiration_date); |
||||||
1639 | $expiration_date = new \DateTime( |
||||||
1640 | $expiration_date, |
||||||
1641 | new DateTimeZone('UTC') |
||||||
1642 | ); |
||||||
1643 | } |
||||||
1644 | |||||||
1645 | $user |
||||||
1646 | ->setLastname($lastname) |
||||||
1647 | ->setFirstname($firstname) |
||||||
1648 | ->setUsername($username) |
||||||
1649 | ->setStatus($status) |
||||||
1650 | ->setAuthSource($auth_source) |
||||||
1651 | ->setLanguage($language) |
||||||
1652 | ->setEmail($email) |
||||||
1653 | ->setOfficialCode($official_code) |
||||||
1654 | ->setPhone($phone) |
||||||
1655 | ->setAddress($address) |
||||||
1656 | ->setPictureUri($picture_uri) |
||||||
1657 | ->setExpirationDate($expiration_date) |
||||||
1658 | ->setActive($active) |
||||||
1659 | ->setEnabled($active) |
||||||
1660 | ->setHrDeptId($hr_dept_id) |
||||||
1661 | ; |
||||||
1662 | |||||||
1663 | if (!is_null($password)) { |
||||||
1664 | $user->setPlainPassword($password); |
||||||
1665 | Event::addEvent(LOG_USER_PASSWORD_UPDATE, LOG_USER_ID, $user_id); |
||||||
1666 | $date = api_get_local_time( |
||||||
1667 | null, |
||||||
1668 | null, |
||||||
1669 | null, |
||||||
1670 | null, |
||||||
1671 | null, |
||||||
1672 | null, |
||||||
1673 | 'Y-m-d' |
||||||
1674 | ); |
||||||
1675 | $extraFieldValue = new ExtraFieldValue('user'); |
||||||
1676 | $extraFieldValue->save( |
||||||
1677 | [ |
||||||
1678 | 'item_id' => $user->getId(), |
||||||
1679 | 'variable' => 'password_updated_at', |
||||||
1680 | 'value' => $date, |
||||||
1681 | ] |
||||||
1682 | ); |
||||||
1683 | } |
||||||
1684 | |||||||
1685 | $userManager->updateUser($user, true); |
||||||
1686 | Event::addEvent(LOG_USER_UPDATE, LOG_USER_ID, $user_id); |
||||||
1687 | |||||||
1688 | if ($change_active == 1) { |
||||||
1689 | if ($active == 1) { |
||||||
1690 | $event_title = LOG_USER_ENABLE; |
||||||
1691 | } else { |
||||||
1692 | $event_title = LOG_USER_DISABLE; |
||||||
1693 | } |
||||||
1694 | Event::addEvent($event_title, LOG_USER_ID, $user_id); |
||||||
1695 | } |
||||||
1696 | |||||||
1697 | if (is_array($extra) && count($extra) > 0) { |
||||||
1698 | $res = true; |
||||||
1699 | foreach ($extra as $fname => $fvalue) { |
||||||
1700 | $res = $res && self::update_extra_field_value( |
||||||
1701 | $user_id, |
||||||
1702 | $fname, |
||||||
1703 | $fvalue |
||||||
1704 | ); |
||||||
1705 | } |
||||||
1706 | } |
||||||
1707 | |||||||
1708 | if (!empty($email) && $send_email) { |
||||||
1709 | $recipient_name = api_get_person_name($firstname, $lastname, null, PERSON_NAME_EMAIL_ADDRESS); |
||||||
1710 | $sender_name = api_get_person_name( |
||||||
1711 | api_get_setting('administratorName'), |
||||||
1712 | api_get_setting('administratorSurname'), |
||||||
1713 | null, |
||||||
1714 | PERSON_NAME_EMAIL_ADDRESS |
||||||
1715 | ); |
||||||
1716 | $email_admin = api_get_setting('emailAdministrator'); |
||||||
1717 | $url = api_get_path(WEB_PATH); |
||||||
1718 | if (api_is_multiple_url_enabled()) { |
||||||
1719 | $access_url_id = api_get_current_access_url_id(); |
||||||
1720 | if ($access_url_id != -1) { |
||||||
1721 | $url = api_get_access_url($access_url_id); |
||||||
1722 | $url = $url['url']; |
||||||
1723 | } |
||||||
1724 | } |
||||||
1725 | |||||||
1726 | $tplContent = new Template( |
||||||
1727 | null, |
||||||
1728 | false, |
||||||
1729 | false, |
||||||
1730 | false, |
||||||
1731 | false, |
||||||
1732 | false |
||||||
1733 | ); |
||||||
1734 | $tplContent->assign('complete_name', stripslashes(api_get_person_name($firstname, $lastname))); |
||||||
1735 | $tplContent->assign('login_name', $username); |
||||||
1736 | $originalPassword = ''; |
||||||
1737 | if ($reset_password > 0) { |
||||||
1738 | $originalPassword = stripslashes($original_password); |
||||||
1739 | } |
||||||
1740 | $tplContent->assign('original_password', $originalPassword); |
||||||
1741 | // variables for the default template |
||||||
1742 | $tplContent->assign('portal_url', $url); |
||||||
1743 | // Adding this variable but not used in default template, used for task BT19518 with a customized template |
||||||
1744 | $tplContent->assign('status_type', $status); |
||||||
1745 | $creatorInfo = api_get_user_info($creator_id); |
||||||
1746 | $creatorEmail = isset($creatorInfo['email']) ? $creatorInfo['email'] : ''; |
||||||
1747 | $tplSubject = new Template( |
||||||
1748 | null, |
||||||
1749 | false, |
||||||
1750 | false, |
||||||
1751 | false, |
||||||
1752 | false, |
||||||
1753 | false |
||||||
1754 | ); |
||||||
1755 | // the complete_name is not used in the default Chamilo template but used in a specific template -refs BT#21334 |
||||||
1756 | $tplSubject->assign('complete_name', stripslashes(api_get_person_name($firstName, $lastName))); |
||||||
1757 | $layoutSubject = $tplSubject->get_template('mail/subject_user_edit.tpl'); |
||||||
1758 | $emailSubject = $tplSubject->fetch($layoutSubject); |
||||||
1759 | |||||||
1760 | if (!is_null($password) && api_get_configuration_value('send_two_inscription_confirmation_mail')) { |
||||||
1761 | // The user has a new password *and* we need to tell him so, |
||||||
1762 | // but the configuration is set to send 2 separate e-mails |
||||||
1763 | // (one for username, one for password) when sending pass |
||||||
1764 | $layoutContent = $tplContent->get_template('mail/new_user_first_email_confirmation.tpl'); |
||||||
1765 | $emailBody = $tplContent->fetch($layoutContent); |
||||||
1766 | $mailTemplateManager = new MailTemplateManager(); |
||||||
1767 | if (!empty($emailTemplate) && |
||||||
1768 | isset($emailTemplate['new_user_first_email_confirmation.tpl']) && |
||||||
1769 | !empty($emailTemplate['new_user_first_email_confirmation.tpl']) |
||||||
1770 | ) { |
||||||
1771 | $userInfo = api_get_user_info($user_id); |
||||||
1772 | $emailBody = $mailTemplateManager->parseTemplate( |
||||||
1773 | $emailTemplate['new_user_first_email_confirmation.tpl'], |
||||||
1774 | $userInfo |
||||||
1775 | ); |
||||||
1776 | } |
||||||
1777 | |||||||
1778 | api_mail_html( |
||||||
1779 | $recipient_name, |
||||||
1780 | $email, |
||||||
1781 | $emailSubject, |
||||||
1782 | $emailBody, |
||||||
1783 | $sender_name, |
||||||
1784 | $email_admin, |
||||||
1785 | null, |
||||||
1786 | null, |
||||||
1787 | null, |
||||||
1788 | null, |
||||||
1789 | $creatorEmail |
||||||
1790 | ); |
||||||
1791 | |||||||
1792 | $layoutContent = $tplContent->get_template('mail/new_user_second_email_confirmation.tpl'); |
||||||
1793 | $emailBody = $tplContent->fetch($layoutContent); |
||||||
1794 | $mailTemplateManager = new MailTemplateManager(); |
||||||
1795 | if (!empty($emailTemplate) && |
||||||
1796 | isset($emailTemplate['new_user_second_email_confirmation.tpl']) && |
||||||
1797 | !empty($emailTemplate['new_user_second_email_confirmation.tpl']) |
||||||
1798 | ) { |
||||||
1799 | $userInfo = api_get_user_info($user_id); |
||||||
1800 | $emailBody = $mailTemplateManager->parseTemplate( |
||||||
1801 | $emailTemplate['new_user_second_email_confirmation.tpl'], |
||||||
1802 | $userInfo |
||||||
1803 | ); |
||||||
1804 | } |
||||||
1805 | |||||||
1806 | api_mail_html( |
||||||
1807 | $recipient_name, |
||||||
1808 | $email, |
||||||
1809 | $emailSubject, |
||||||
1810 | $emailBody, |
||||||
1811 | $sender_name, |
||||||
1812 | $email_admin, |
||||||
1813 | null, |
||||||
1814 | null, |
||||||
1815 | null, |
||||||
1816 | null, |
||||||
1817 | $creatorEmail |
||||||
1818 | ); |
||||||
1819 | } else { |
||||||
1820 | $layoutContent = $tplContent->get_template('mail/user_edit_content.tpl'); |
||||||
1821 | $emailBody = $tplContent->fetch($layoutContent); |
||||||
1822 | $mailTemplateManager = new MailTemplateManager(); |
||||||
1823 | if (!empty($emailTemplate) && |
||||||
1824 | isset($emailTemplate['user_edit_content.tpl']) && |
||||||
1825 | !empty($emailTemplate['user_edit_content.tpl']) |
||||||
1826 | ) { |
||||||
1827 | $userInfo = api_get_user_info($user_id); |
||||||
1828 | $emailBody = $mailTemplateManager->parseTemplate( |
||||||
1829 | $emailTemplate['user_edit_content.tpl'], |
||||||
1830 | $userInfo |
||||||
1831 | ); |
||||||
1832 | } |
||||||
1833 | |||||||
1834 | api_mail_html( |
||||||
1835 | $recipient_name, |
||||||
1836 | $email, |
||||||
1837 | $emailSubject, |
||||||
1838 | $emailBody, |
||||||
1839 | $sender_name, |
||||||
1840 | $email_admin, |
||||||
1841 | null, |
||||||
1842 | null, |
||||||
1843 | null, |
||||||
1844 | null, |
||||||
1845 | $creatorEmail |
||||||
1846 | ); |
||||||
1847 | } |
||||||
1848 | } |
||||||
1849 | |||||||
1850 | if (!empty($hook)) { |
||||||
1851 | $hook->setEventData(['user' => $user]); |
||||||
1852 | $hook->notifyUpdateUser(HOOK_EVENT_TYPE_POST); |
||||||
1853 | } |
||||||
1854 | |||||||
1855 | $cacheAvailable = api_get_configuration_value('apc'); |
||||||
1856 | if ($cacheAvailable === true) { |
||||||
1857 | $apcVar = api_get_configuration_value('apc_prefix').'userinfo_'.$user_id; |
||||||
1858 | if (apcu_exists($apcVar)) { |
||||||
1859 | apcu_delete($apcVar); |
||||||
1860 | } |
||||||
1861 | } |
||||||
1862 | |||||||
1863 | return $user->getId(); |
||||||
1864 | } |
||||||
1865 | |||||||
1866 | /** |
||||||
1867 | * Disables a user. |
||||||
1868 | * |
||||||
1869 | * @param int User id |
||||||
1870 | * |
||||||
1871 | * @return bool |
||||||
1872 | * |
||||||
1873 | * @uses \UserManager::change_active_state() to actually disable the user |
||||||
1874 | * @assert (0) === false |
||||||
1875 | */ |
||||||
1876 | public static function disable($user_id) |
||||||
1877 | { |
||||||
1878 | if (empty($user_id)) { |
||||||
1879 | return false; |
||||||
1880 | } |
||||||
1881 | self::change_active_state($user_id, 0); |
||||||
1882 | |||||||
1883 | return true; |
||||||
1884 | } |
||||||
1885 | |||||||
1886 | /** |
||||||
1887 | * Enable a user. |
||||||
1888 | * |
||||||
1889 | * @param int User id |
||||||
1890 | * |
||||||
1891 | * @return bool |
||||||
1892 | * |
||||||
1893 | * @uses \UserManager::change_active_state() to actually disable the user |
||||||
1894 | * @assert (0) === false |
||||||
1895 | */ |
||||||
1896 | public static function enable($user_id) |
||||||
1897 | { |
||||||
1898 | if (empty($user_id)) { |
||||||
1899 | return false; |
||||||
1900 | } |
||||||
1901 | self::change_active_state($user_id, 1); |
||||||
1902 | |||||||
1903 | return true; |
||||||
1904 | } |
||||||
1905 | |||||||
1906 | /** |
||||||
1907 | * Returns the user's id based on the original id and field name in |
||||||
1908 | * the extra fields. Returns 0 if no user was found. This function is |
||||||
1909 | * mostly useful in the context of a web services-based sinchronization. |
||||||
1910 | * |
||||||
1911 | * @param string Original user id |
||||||
1912 | * @param string Original field name |
||||||
1913 | * |
||||||
1914 | * @return int User id |
||||||
1915 | * @assert ('0','---') === 0 |
||||||
1916 | */ |
||||||
1917 | public static function get_user_id_from_original_id( |
||||||
1918 | $original_user_id_value, |
||||||
1919 | $original_user_id_name |
||||||
1920 | ) { |
||||||
1921 | $t_uf = Database::get_main_table(TABLE_EXTRA_FIELD); |
||||||
1922 | $t_ufv = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
||||||
1923 | $extraFieldType = EntityExtraField::USER_FIELD_TYPE; |
||||||
1924 | |||||||
1925 | $original_user_id_name = Database::escape_string($original_user_id_name); |
||||||
1926 | $original_user_id_value = Database::escape_string($original_user_id_value); |
||||||
1927 | |||||||
1928 | $sql = "SELECT item_id as user_id |
||||||
1929 | FROM $t_uf uf |
||||||
1930 | INNER JOIN $t_ufv ufv |
||||||
1931 | ON ufv.field_id = uf.id |
||||||
1932 | WHERE |
||||||
1933 | variable = '$original_user_id_name' AND |
||||||
1934 | value = '$original_user_id_value' AND |
||||||
1935 | extra_field_type = $extraFieldType |
||||||
1936 | "; |
||||||
1937 | $res = Database::query($sql); |
||||||
1938 | $row = Database::fetch_object($res); |
||||||
1939 | if ($row) { |
||||||
1940 | return $row->user_id; |
||||||
1941 | } |
||||||
1942 | |||||||
1943 | return 0; |
||||||
1944 | } |
||||||
1945 | |||||||
1946 | /** |
||||||
1947 | * Check if a username is available. |
||||||
1948 | * |
||||||
1949 | * @param string $username the wanted username |
||||||
1950 | * |
||||||
1951 | * @return bool true if the wanted username is available |
||||||
1952 | * @assert ('') === false |
||||||
1953 | * @assert ('xyzxyzxyz') === true |
||||||
1954 | */ |
||||||
1955 | public static function is_username_available($username) |
||||||
1956 | { |
||||||
1957 | if (empty($username)) { |
||||||
1958 | return false; |
||||||
1959 | } |
||||||
1960 | $table_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
1961 | $sql = "SELECT username FROM $table_user |
||||||
1962 | WHERE username = '".Database::escape_string($username)."'"; |
||||||
1963 | $res = Database::query($sql); |
||||||
1964 | |||||||
1965 | return Database::num_rows($res) == 0; |
||||||
1966 | } |
||||||
1967 | |||||||
1968 | /** |
||||||
1969 | * Creates a username using person's names, i.e. creates jmontoya from Julio Montoya. |
||||||
1970 | * |
||||||
1971 | * @param string $firstname the first name of the user |
||||||
1972 | * @param string $lastname the last name of the user |
||||||
1973 | * |
||||||
1974 | * @return string suggests a username that contains only ASCII-letters and digits, |
||||||
1975 | * without check for uniqueness within the system |
||||||
1976 | * |
||||||
1977 | * @author Julio Montoya Armas |
||||||
1978 | * @author Ivan Tcholakov, 2009 - rework about internationalization. |
||||||
1979 | * @assert ('','') === false |
||||||
1980 | * @assert ('a','b') === 'ab' |
||||||
1981 | */ |
||||||
1982 | public static function create_username($firstname, $lastname) |
||||||
1983 | { |
||||||
1984 | if (empty($firstname) && empty($lastname)) { |
||||||
1985 | return false; |
||||||
1986 | } |
||||||
1987 | |||||||
1988 | // The first letter only. |
||||||
1989 | $firstname = api_substr( |
||||||
1990 | preg_replace(USERNAME_PURIFIER, '', $firstname), |
||||||
1991 | 0, |
||||||
1992 | 1 |
||||||
1993 | ); |
||||||
1994 | //Looking for a space in the lastname |
||||||
1995 | $pos = api_strpos($lastname, ' '); |
||||||
1996 | if ($pos !== false) { |
||||||
1997 | $lastname = api_substr($lastname, 0, $pos); |
||||||
1998 | } |
||||||
1999 | |||||||
2000 | $lastname = preg_replace(USERNAME_PURIFIER, '', $lastname); |
||||||
2001 | $username = $firstname.$lastname; |
||||||
2002 | if (empty($username)) { |
||||||
2003 | $username = 'user'; |
||||||
2004 | } |
||||||
2005 | |||||||
2006 | $username = URLify::transliterate($username); |
||||||
2007 | |||||||
2008 | return strtolower(substr($username, 0, USERNAME_MAX_LENGTH - 3)); |
||||||
2009 | } |
||||||
2010 | |||||||
2011 | /** |
||||||
2012 | * Creates a unique username, using: |
||||||
2013 | * 1. the first name and the last name of a user; |
||||||
2014 | * 2. an already created username but not checked for uniqueness yet. |
||||||
2015 | * |
||||||
2016 | * @param string $firstname The first name of a given user. If the second parameter $lastname is NULL, then this |
||||||
2017 | * parameter is treated as username which is to be checked f |
||||||
2018 | * or uniqueness and to be modified when it is necessary. |
||||||
2019 | * @param string $lastname the last name of the user |
||||||
2020 | * |
||||||
2021 | * @return string Returns a username that contains only ASCII-letters and digits and that is unique in the system. |
||||||
2022 | * Note: When the method is called several times with same parameters, |
||||||
2023 | * its results look like the following sequence: ivan, ivan2, ivan3, ivan4, ... |
||||||
2024 | * |
||||||
2025 | * @author Ivan Tcholakov, 2009 |
||||||
2026 | */ |
||||||
2027 | public static function create_unique_username($firstname, $lastname = null) |
||||||
2028 | { |
||||||
2029 | if (is_null($lastname)) { |
||||||
2030 | // In this case the actual input parameter $firstname should contain ASCII-letters and digits only. |
||||||
2031 | // For making this method tolerant of mistakes, |
||||||
2032 | // let us transliterate and purify the suggested input username anyway. |
||||||
2033 | // So, instead of the sentence $username = $firstname; we place the following: |
||||||
2034 | $username = strtolower(preg_replace(USERNAME_PURIFIER, '', $firstname)); |
||||||
2035 | } else { |
||||||
2036 | $username = self::create_username($firstname, $lastname); |
||||||
2037 | } |
||||||
2038 | if (!self::is_username_available($username)) { |
||||||
2039 | $i = 2; |
||||||
2040 | $temp_username = substr($username, 0, USERNAME_MAX_LENGTH - strlen((string) $i)).$i; |
||||||
2041 | while (!self::is_username_available($temp_username)) { |
||||||
2042 | $i++; |
||||||
2043 | $temp_username = substr($username, 0, USERNAME_MAX_LENGTH - strlen((string) $i)).$i; |
||||||
2044 | } |
||||||
2045 | $username = $temp_username; |
||||||
2046 | } |
||||||
2047 | |||||||
2048 | $username = URLify::transliterate($username); |
||||||
2049 | |||||||
2050 | return $username; |
||||||
2051 | } |
||||||
2052 | |||||||
2053 | /** |
||||||
2054 | * Modifies a given username accordingly to the specification for valid characters and length. |
||||||
2055 | * |
||||||
2056 | * @param $username string The input username |
||||||
2057 | * @param bool $strict (optional) When this flag is TRUE, the result is guaranteed for full compliance, |
||||||
2058 | * otherwise compliance may be partial. The default value is FALSE. |
||||||
2059 | * |
||||||
2060 | * @return string the resulting purified username |
||||||
2061 | */ |
||||||
2062 | public static function purify_username($username, $strict = false) |
||||||
2063 | { |
||||||
2064 | if ($strict) { |
||||||
2065 | // 1. Conversion of unacceptable letters (latinian letters with accents for example) |
||||||
2066 | // into ASCII letters in order they not to be totally removed. |
||||||
2067 | // 2. Applying the strict purifier. |
||||||
2068 | // 3. Length limitation. |
||||||
2069 | if ('true' === api_get_setting('login_is_email')) { |
||||||
2070 | $return = substr(preg_replace(USERNAME_PURIFIER_MAIL, '', $username), 0, USERNAME_MAX_LENGTH); |
||||||
2071 | } else { |
||||||
2072 | $return = substr(preg_replace(USERNAME_PURIFIER, '', $username), 0, USERNAME_MAX_LENGTH); |
||||||
2073 | } |
||||||
2074 | |||||||
2075 | return URLify::transliterate($return); |
||||||
2076 | } |
||||||
2077 | |||||||
2078 | // 1. Applying the shallow purifier. |
||||||
2079 | // 2. Length limitation. |
||||||
2080 | return substr( |
||||||
2081 | preg_replace(USERNAME_PURIFIER_SHALLOW, '', $username), |
||||||
2082 | 0, |
||||||
2083 | USERNAME_MAX_LENGTH |
||||||
2084 | ); |
||||||
2085 | } |
||||||
2086 | |||||||
2087 | /** |
||||||
2088 | * Checks whether the user id exists in the database. |
||||||
2089 | * |
||||||
2090 | * @param int $userId User id |
||||||
2091 | * |
||||||
2092 | * @return bool True if user id was found, false otherwise |
||||||
2093 | */ |
||||||
2094 | public static function is_user_id_valid($userId) |
||||||
2095 | { |
||||||
2096 | $resultData = Database::select( |
||||||
2097 | 'COUNT(1) AS count', |
||||||
2098 | Database::get_main_table(TABLE_MAIN_USER), |
||||||
2099 | [ |
||||||
2100 | 'where' => ['id = ?' => (int) $userId], |
||||||
2101 | ], |
||||||
2102 | 'first' |
||||||
2103 | ); |
||||||
2104 | |||||||
2105 | if ($resultData === false) { |
||||||
2106 | return false; |
||||||
2107 | } |
||||||
2108 | |||||||
2109 | return $resultData['count'] > 0; |
||||||
2110 | } |
||||||
2111 | |||||||
2112 | /** |
||||||
2113 | * Checks whether a given username matches to the specification strictly. |
||||||
2114 | * The empty username is assumed here as invalid. |
||||||
2115 | * Mostly this function is to be used in the user interface built-in validation routines |
||||||
2116 | * for providing feedback while usernames are enterd manually. |
||||||
2117 | * |
||||||
2118 | * @param string $username the input username |
||||||
2119 | * |
||||||
2120 | * @return bool returns TRUE if the username is valid, FALSE otherwise |
||||||
2121 | */ |
||||||
2122 | public static function is_username_valid($username) |
||||||
2123 | { |
||||||
2124 | return !empty($username) && $username == self::purify_username($username, true); |
||||||
2125 | } |
||||||
2126 | |||||||
2127 | /** |
||||||
2128 | * Checks whether a username is empty. If the username contains whitespace characters, |
||||||
2129 | * such as spaces, tabulators, newlines, etc., |
||||||
2130 | * it is assumed as empty too. This function is safe for validation unpurified data (during importing). |
||||||
2131 | * |
||||||
2132 | * @param string $username the given username |
||||||
2133 | * |
||||||
2134 | * @return bool returns TRUE if length of the username exceeds the limit, FALSE otherwise |
||||||
2135 | */ |
||||||
2136 | public static function is_username_empty($username) |
||||||
2137 | { |
||||||
2138 | return strlen(self::purify_username($username, false)) == 0; |
||||||
2139 | } |
||||||
2140 | |||||||
2141 | /** |
||||||
2142 | * Checks whether a username is too long or not. |
||||||
2143 | * |
||||||
2144 | * @param string $username the given username, it should contain only ASCII-letters and digits |
||||||
2145 | * |
||||||
2146 | * @return bool returns TRUE if length of the username exceeds the limit, FALSE otherwise |
||||||
2147 | */ |
||||||
2148 | public static function is_username_too_long($username) |
||||||
2149 | { |
||||||
2150 | return strlen($username) > USERNAME_MAX_LENGTH; |
||||||
2151 | } |
||||||
2152 | |||||||
2153 | /** |
||||||
2154 | * Get the users by ID. |
||||||
2155 | * |
||||||
2156 | * @param array $ids student ids |
||||||
2157 | * @param string $active |
||||||
2158 | * @param string $order |
||||||
2159 | * @param string $limit |
||||||
2160 | * |
||||||
2161 | * @return array $result student information |
||||||
2162 | */ |
||||||
2163 | public static function get_user_list_by_ids($ids = [], $active = null, $order = null, $limit = null) |
||||||
2164 | { |
||||||
2165 | if (empty($ids)) { |
||||||
2166 | return []; |
||||||
2167 | } |
||||||
2168 | |||||||
2169 | $ids = is_array($ids) ? $ids : [$ids]; |
||||||
2170 | $ids = array_map('intval', $ids); |
||||||
2171 | $ids = implode(',', $ids); |
||||||
2172 | |||||||
2173 | $tbl_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
2174 | $sql = "SELECT * FROM $tbl_user WHERE id IN ($ids)"; |
||||||
2175 | if (!is_null($active)) { |
||||||
2176 | $sql .= ' AND active='.($active ? '1' : '0'); |
||||||
2177 | } |
||||||
2178 | |||||||
2179 | if (!is_null($order)) { |
||||||
2180 | $order = Database::escape_string($order); |
||||||
2181 | $sql .= ' ORDER BY '.$order; |
||||||
2182 | } |
||||||
2183 | |||||||
2184 | if (!is_null($limit)) { |
||||||
2185 | $limit = Database::escape_string($limit); |
||||||
2186 | $sql .= ' LIMIT '.$limit; |
||||||
2187 | } |
||||||
2188 | |||||||
2189 | $rs = Database::query($sql); |
||||||
2190 | $result = []; |
||||||
2191 | while ($row = Database::fetch_array($rs)) { |
||||||
2192 | $result[] = $row; |
||||||
2193 | } |
||||||
2194 | |||||||
2195 | return $result; |
||||||
2196 | } |
||||||
2197 | |||||||
2198 | /** |
||||||
2199 | * Get a list of users of which the given conditions match with an = 'cond'. |
||||||
2200 | * |
||||||
2201 | * @param array $conditions a list of condition (example : status=>STUDENT) |
||||||
2202 | * @param array $order_by a list of fields on which sort |
||||||
2203 | * |
||||||
2204 | * @return array an array with all users of the platform |
||||||
2205 | * |
||||||
2206 | * @todo security filter order by |
||||||
2207 | */ |
||||||
2208 | public static function get_user_list( |
||||||
2209 | $conditions = [], |
||||||
2210 | $order_by = [], |
||||||
2211 | $limit_from = false, |
||||||
2212 | $limit_to = false, |
||||||
2213 | $idCampus = null, |
||||||
2214 | $keyword = null, |
||||||
2215 | $lastConnectionDate = null, |
||||||
2216 | $getCount = false, |
||||||
2217 | $filterUsers = null |
||||||
2218 | ) { |
||||||
2219 | $user_table = Database::get_main_table(TABLE_MAIN_USER); |
||||||
2220 | $userUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
||||||
2221 | $return_array = []; |
||||||
2222 | |||||||
2223 | if ($getCount) { |
||||||
2224 | $sql = "SELECT count(user.id) as nbUsers FROM $user_table user "; |
||||||
2225 | } else { |
||||||
2226 | $sql = "SELECT user.* FROM $user_table user "; |
||||||
2227 | } |
||||||
2228 | |||||||
2229 | if (api_is_multiple_url_enabled()) { |
||||||
2230 | if ($idCampus) { |
||||||
2231 | $urlId = $idCampus; |
||||||
2232 | } else { |
||||||
2233 | $urlId = api_get_current_access_url_id(); |
||||||
2234 | } |
||||||
2235 | $sql .= " INNER JOIN $userUrlTable url_user |
||||||
2236 | ON (user.user_id = url_user.user_id) |
||||||
2237 | WHERE url_user.access_url_id = $urlId"; |
||||||
2238 | } else { |
||||||
2239 | $sql .= " WHERE 1=1 "; |
||||||
2240 | } |
||||||
2241 | |||||||
2242 | if (!empty($keyword)) { |
||||||
2243 | $keyword = trim(Database::escape_string($keyword)); |
||||||
2244 | $keywordParts = array_filter(explode(' ', $keyword)); |
||||||
2245 | $extraKeyword = ''; |
||||||
2246 | if (!empty($keywordParts)) { |
||||||
2247 | $keywordPartsFixed = Database::escape_string(implode('%', $keywordParts)); |
||||||
2248 | if (!empty($keywordPartsFixed)) { |
||||||
2249 | $extraKeyword .= " OR |
||||||
2250 | CONCAT(user.firstname, ' ', user.lastname) LIKE '%$keywordPartsFixed%' OR |
||||||
2251 | CONCAT(user.lastname, ' ', user.firstname) LIKE '%$keywordPartsFixed%' "; |
||||||
2252 | } |
||||||
2253 | } |
||||||
2254 | |||||||
2255 | $sql .= " AND ( |
||||||
2256 | user.username LIKE '%$keyword%' OR |
||||||
2257 | user.firstname LIKE '%$keyword%' OR |
||||||
2258 | user.lastname LIKE '%$keyword%' OR |
||||||
2259 | user.official_code LIKE '%$keyword%' OR |
||||||
2260 | user.email LIKE '%$keyword%' OR |
||||||
2261 | CONCAT(user.firstname, ' ', user.lastname) LIKE '%$keyword%' OR |
||||||
2262 | CONCAT(user.lastname, ' ', user.firstname) LIKE '%$keyword%' |
||||||
2263 | $extraKeyword |
||||||
2264 | )"; |
||||||
2265 | } |
||||||
2266 | |||||||
2267 | if (!empty($lastConnectionDate)) { |
||||||
2268 | $lastConnectionDate = Database::escape_string($lastConnectionDate); |
||||||
2269 | $sql .= " AND user.last_login <= '$lastConnectionDate' "; |
||||||
2270 | } |
||||||
2271 | |||||||
2272 | if (count($conditions) > 0) { |
||||||
2273 | foreach ($conditions as $field => $value) { |
||||||
2274 | $field = Database::escape_string($field); |
||||||
2275 | $value = Database::escape_string($value); |
||||||
2276 | $sql .= " AND $field = '$value'"; |
||||||
2277 | } |
||||||
2278 | } |
||||||
2279 | |||||||
2280 | if (!empty($filterUsers)) { |
||||||
2281 | $sql .= " AND user.id IN(".implode(',', $filterUsers).")"; |
||||||
2282 | } |
||||||
2283 | |||||||
2284 | if (count($order_by) > 0) { |
||||||
2285 | $sql .= ' ORDER BY '.Database::escape_string(implode(',', $order_by)); |
||||||
2286 | } |
||||||
2287 | |||||||
2288 | if (is_numeric($limit_from) && is_numeric($limit_from)) { |
||||||
2289 | $limit_from = (int) $limit_from; |
||||||
2290 | $limit_to = (int) $limit_to; |
||||||
2291 | $sql .= " LIMIT $limit_from, $limit_to"; |
||||||
2292 | } |
||||||
2293 | $sql_result = Database::query($sql); |
||||||
2294 | |||||||
2295 | if ($getCount) { |
||||||
2296 | $result = Database::fetch_array($sql_result); |
||||||
2297 | |||||||
2298 | return $result['nbUsers']; |
||||||
2299 | } |
||||||
2300 | |||||||
2301 | while ($result = Database::fetch_array($sql_result)) { |
||||||
2302 | $result['complete_name'] = api_get_person_name($result['firstname'], $result['lastname']); |
||||||
2303 | $return_array[] = $result; |
||||||
2304 | } |
||||||
2305 | |||||||
2306 | return $return_array; |
||||||
2307 | } |
||||||
2308 | |||||||
2309 | public static function getUserListExtraConditions( |
||||||
2310 | $conditions = [], |
||||||
2311 | $order_by = [], |
||||||
2312 | $limit_from = false, |
||||||
2313 | $limit_to = false, |
||||||
2314 | $idCampus = null, |
||||||
2315 | $extraConditions = '', |
||||||
2316 | $getCount = false |
||||||
2317 | ) { |
||||||
2318 | $user_table = Database::get_main_table(TABLE_MAIN_USER); |
||||||
2319 | $userUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
||||||
2320 | $return_array = []; |
||||||
2321 | $sql = "SELECT user.* FROM $user_table user "; |
||||||
2322 | |||||||
2323 | if ($getCount) { |
||||||
2324 | $sql = "SELECT count(user.id) count FROM $user_table user "; |
||||||
2325 | } |
||||||
2326 | |||||||
2327 | if (api_is_multiple_url_enabled()) { |
||||||
2328 | if ($idCampus) { |
||||||
2329 | $urlId = $idCampus; |
||||||
2330 | } else { |
||||||
2331 | $urlId = api_get_current_access_url_id(); |
||||||
2332 | } |
||||||
2333 | $sql .= " INNER JOIN $userUrlTable url_user |
||||||
2334 | ON (user.user_id = url_user.user_id) |
||||||
2335 | WHERE url_user.access_url_id = $urlId"; |
||||||
2336 | } else { |
||||||
2337 | $sql .= " WHERE 1=1 "; |
||||||
2338 | } |
||||||
2339 | |||||||
2340 | $sql .= " AND status <> ".ANONYMOUS." "; |
||||||
2341 | |||||||
2342 | if (count($conditions) > 0) { |
||||||
2343 | foreach ($conditions as $field => $value) { |
||||||
2344 | $field = Database::escape_string($field); |
||||||
2345 | $value = Database::escape_string($value); |
||||||
2346 | $sql .= " AND $field = '$value'"; |
||||||
2347 | } |
||||||
2348 | } |
||||||
2349 | |||||||
2350 | $sql .= str_replace("\'", "'", Database::escape_string($extraConditions)); |
||||||
2351 | |||||||
2352 | if (!empty($order_by) && count($order_by) > 0) { |
||||||
2353 | $sql .= ' ORDER BY '.Database::escape_string(implode(',', $order_by)); |
||||||
2354 | } |
||||||
2355 | |||||||
2356 | if (is_numeric($limit_from) && is_numeric($limit_from)) { |
||||||
2357 | $limit_from = (int) $limit_from; |
||||||
2358 | $limit_to = (int) $limit_to; |
||||||
2359 | $sql .= " LIMIT $limit_from, $limit_to"; |
||||||
2360 | } |
||||||
2361 | |||||||
2362 | $sql_result = Database::query($sql); |
||||||
2363 | |||||||
2364 | if ($getCount) { |
||||||
2365 | $result = Database::fetch_array($sql_result); |
||||||
2366 | |||||||
2367 | return $result['count']; |
||||||
2368 | } |
||||||
2369 | |||||||
2370 | while ($result = Database::fetch_array($sql_result)) { |
||||||
2371 | $result['complete_name'] = api_get_person_name($result['firstname'], $result['lastname']); |
||||||
2372 | $return_array[] = $result; |
||||||
2373 | } |
||||||
2374 | |||||||
2375 | return $return_array; |
||||||
2376 | } |
||||||
2377 | |||||||
2378 | /** |
||||||
2379 | * Get a list of users of which the given conditions match with a LIKE '%cond%'. |
||||||
2380 | * |
||||||
2381 | * @param array $conditions a list of condition (exemple : status=>STUDENT) |
||||||
2382 | * @param array $order_by a list of fields on which sort |
||||||
2383 | * @param bool $simple_like Whether we want a simple LIKE 'abc' or a LIKE '%abc%' |
||||||
2384 | * @param string $condition Whether we want the filters to be combined by AND or OR |
||||||
2385 | * @param array $onlyThisUserList |
||||||
2386 | * |
||||||
2387 | * @return array an array with all users of the platform |
||||||
2388 | * |
||||||
2389 | * @todo optional course code parameter, optional sorting parameters... |
||||||
2390 | * @todo security filter order_by |
||||||
2391 | */ |
||||||
2392 | public static function getUserListLike( |
||||||
2393 | $conditions = [], |
||||||
2394 | $order_by = [], |
||||||
2395 | $simple_like = false, |
||||||
2396 | $condition = 'AND', |
||||||
2397 | $onlyThisUserList = [] |
||||||
2398 | ) { |
||||||
2399 | $user_table = Database::get_main_table(TABLE_MAIN_USER); |
||||||
2400 | $tblAccessUrlRelUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
||||||
2401 | $return_array = []; |
||||||
2402 | $sql_query = "SELECT user.id FROM $user_table user "; |
||||||
2403 | |||||||
2404 | if (api_is_multiple_url_enabled()) { |
||||||
2405 | $sql_query .= " INNER JOIN $tblAccessUrlRelUser auru ON auru.user_id = user.id "; |
||||||
2406 | } |
||||||
2407 | |||||||
2408 | $sql_query .= ' WHERE 1 = 1 '; |
||||||
2409 | if (count($conditions) > 0) { |
||||||
2410 | |||||||
2411 | $andActive = ""; |
||||||
2412 | if (isset($conditions['active'])) { |
||||||
2413 | $andActive = " AND active = " . (int) $conditions['active']; |
||||||
2414 | unset($conditions['active']); |
||||||
2415 | } |
||||||
2416 | |||||||
2417 | $temp_conditions = []; |
||||||
2418 | foreach ($conditions as $field => $value) { |
||||||
2419 | $field = Database::escape_string($field); |
||||||
2420 | $value = Database::escape_string($value); |
||||||
2421 | if ($simple_like) { |
||||||
2422 | $temp_conditions[] = $field." LIKE '$value%'"; |
||||||
2423 | } else { |
||||||
2424 | $temp_conditions[] = $field.' LIKE \'%'.$value.'%\''; |
||||||
2425 | } |
||||||
2426 | } |
||||||
2427 | if (!empty($temp_conditions)) { |
||||||
2428 | $sql_query .= ' AND ('.implode(' '.$condition.' ', $temp_conditions).') '; |
||||||
2429 | } |
||||||
2430 | |||||||
2431 | if (api_is_multiple_url_enabled()) { |
||||||
2432 | $sql_query .= ' AND auru.access_url_id = '.api_get_current_access_url_id(); |
||||||
2433 | } |
||||||
2434 | $sql_query .= $andActive; |
||||||
2435 | } else { |
||||||
2436 | if (api_is_multiple_url_enabled()) { |
||||||
2437 | $sql_query .= ' AND auru.access_url_id = '.api_get_current_access_url_id(); |
||||||
2438 | } |
||||||
2439 | } |
||||||
2440 | |||||||
2441 | if (api_is_session_admin() && (api_get_setting('prevent_session_admins_to_manage_all_users') === 'true')) { |
||||||
2442 | $sql_query .= ' AND user.creator_id = '.api_get_user_id(); |
||||||
2443 | } |
||||||
2444 | |||||||
2445 | if (!empty($onlyThisUserList)) { |
||||||
2446 | $onlyThisUserListToString = implode("','", $onlyThisUserList); |
||||||
2447 | $sql_query .= " AND user.id IN ('$onlyThisUserListToString') "; |
||||||
2448 | } |
||||||
2449 | |||||||
2450 | if (count($order_by) > 0) { |
||||||
2451 | $sql_query .= ' ORDER BY '.Database::escape_string(implode(',', $order_by)); |
||||||
2452 | } |
||||||
2453 | |||||||
2454 | $sql_result = Database::query($sql_query); |
||||||
2455 | while ($result = Database::fetch_array($sql_result)) { |
||||||
2456 | $userInfo = api_get_user_info($result['id']); |
||||||
2457 | $return_array[] = $userInfo; |
||||||
2458 | } |
||||||
2459 | |||||||
2460 | return $return_array; |
||||||
2461 | } |
||||||
2462 | |||||||
2463 | /** |
||||||
2464 | * Get user picture URL or path from user ID (returns an array). |
||||||
2465 | * The return format is a complete path, enabling recovery of the directory |
||||||
2466 | * with dirname() or the file with basename(). This also works for the |
||||||
2467 | * functions dealing with the user's productions, as they are located in |
||||||
2468 | * the same directory. |
||||||
2469 | * |
||||||
2470 | * @param int $id User ID |
||||||
2471 | * @param string $type Type of path to return (can be 'system', 'web') |
||||||
2472 | * @param array $userInfo user information to avoid query the DB |
||||||
2473 | * returns the /main/img/unknown.jpg image set it at true |
||||||
2474 | * |
||||||
2475 | * @return array Array of 2 elements: 'dir' and 'file' which contain |
||||||
2476 | * the dir and file as the name implies if image does not exist it will |
||||||
2477 | * return the unknow image if anonymous parameter is true if not it returns an empty array |
||||||
2478 | */ |
||||||
2479 | public static function get_user_picture_path_by_id( |
||||||
2480 | $id, |
||||||
2481 | $type = 'web', |
||||||
2482 | $userInfo = [] |
||||||
2483 | ) { |
||||||
2484 | switch ($type) { |
||||||
2485 | case 'system': // Base: absolute system path. |
||||||
2486 | $base = api_get_path(SYS_CODE_PATH); |
||||||
2487 | break; |
||||||
2488 | case 'web': // Base: absolute web path. |
||||||
2489 | default: |
||||||
2490 | $base = api_get_path(WEB_CODE_PATH); |
||||||
2491 | break; |
||||||
2492 | } |
||||||
2493 | |||||||
2494 | $anonymousPath = [ |
||||||
2495 | 'dir' => $base.'img/', |
||||||
2496 | 'file' => 'unknown.jpg', |
||||||
2497 | 'email' => '', |
||||||
2498 | ]; |
||||||
2499 | |||||||
2500 | if (empty($id) || empty($type)) { |
||||||
2501 | return $anonymousPath; |
||||||
2502 | } |
||||||
2503 | |||||||
2504 | $id = (int) $id; |
||||||
2505 | if (empty($userInfo)) { |
||||||
2506 | $user_table = Database::get_main_table(TABLE_MAIN_USER); |
||||||
2507 | $sql = "SELECT email, picture_uri FROM $user_table |
||||||
2508 | WHERE id = ".$id; |
||||||
2509 | $res = Database::query($sql); |
||||||
2510 | |||||||
2511 | if (!Database::num_rows($res)) { |
||||||
2512 | return $anonymousPath; |
||||||
2513 | } |
||||||
2514 | $user = Database::fetch_array($res); |
||||||
2515 | if (empty($user['picture_uri'])) { |
||||||
2516 | return $anonymousPath; |
||||||
2517 | } |
||||||
2518 | } else { |
||||||
2519 | $user = $userInfo; |
||||||
2520 | } |
||||||
2521 | |||||||
2522 | $pictureFilename = trim($user['picture_uri']); |
||||||
2523 | |||||||
2524 | $dir = self::getUserPathById($id, $type); |
||||||
2525 | |||||||
2526 | return [ |
||||||
2527 | 'dir' => $dir, |
||||||
2528 | 'file' => $pictureFilename, |
||||||
2529 | 'email' => $user['email'], |
||||||
2530 | ]; |
||||||
2531 | } |
||||||
2532 | |||||||
2533 | /** |
||||||
2534 | * *** READ BEFORE REVIEW THIS FUNCTION *** |
||||||
2535 | * This function is a exact copy from get_user_picture_path_by_id() and it was create it to avoid |
||||||
2536 | * a recursive calls for get_user_picture_path_by_id() in another functions when you update a user picture |
||||||
2537 | * in same script, so you can find this function usage in update_user_picture() function. |
||||||
2538 | * |
||||||
2539 | * @param int $id User ID |
||||||
2540 | * @param string $type Type of path to return (can be 'system', 'web') |
||||||
2541 | * @param array $userInfo user information to avoid query the DB |
||||||
2542 | * returns the /main/img/unknown.jpg image set it at true |
||||||
2543 | * |
||||||
2544 | * @return array Array of 2 elements: 'dir' and 'file' which contain |
||||||
2545 | * the dir and file as the name implies if image does not exist it will |
||||||
2546 | * return the unknown image if anonymous parameter is true if not it returns an empty array |
||||||
2547 | */ |
||||||
2548 | public static function getUserPicturePathById($id, $type = 'web', $userInfo = []) |
||||||
2549 | { |
||||||
2550 | switch ($type) { |
||||||
2551 | case 'system': // Base: absolute system path. |
||||||
2552 | $base = api_get_path(SYS_CODE_PATH); |
||||||
2553 | break; |
||||||
2554 | case 'web': // Base: absolute web path. |
||||||
2555 | default: |
||||||
2556 | $base = api_get_path(WEB_CODE_PATH); |
||||||
2557 | break; |
||||||
2558 | } |
||||||
2559 | |||||||
2560 | $anonymousPath = [ |
||||||
2561 | 'dir' => $base.'img/', |
||||||
2562 | 'file' => 'unknown.jpg', |
||||||
2563 | 'email' => '', |
||||||
2564 | ]; |
||||||
2565 | |||||||
2566 | if (empty($id) || empty($type)) { |
||||||
2567 | return $anonymousPath; |
||||||
2568 | } |
||||||
2569 | |||||||
2570 | $id = (int) $id; |
||||||
2571 | if (empty($userInfo)) { |
||||||
2572 | $user_table = Database::get_main_table(TABLE_MAIN_USER); |
||||||
2573 | $sql = "SELECT email, picture_uri FROM $user_table WHERE id = $id"; |
||||||
2574 | $res = Database::query($sql); |
||||||
2575 | |||||||
2576 | if (!Database::num_rows($res)) { |
||||||
2577 | return $anonymousPath; |
||||||
2578 | } |
||||||
2579 | $user = Database::fetch_array($res); |
||||||
2580 | |||||||
2581 | if (empty($user['picture_uri'])) { |
||||||
2582 | return $anonymousPath; |
||||||
2583 | } |
||||||
2584 | } else { |
||||||
2585 | $user = $userInfo; |
||||||
2586 | } |
||||||
2587 | |||||||
2588 | $pictureFilename = trim($user['picture_uri']); |
||||||
2589 | $dir = self::getUserPathById($id, $type); |
||||||
2590 | |||||||
2591 | return [ |
||||||
2592 | 'dir' => $dir, |
||||||
2593 | 'file' => $pictureFilename, |
||||||
2594 | 'email' => $user['email'], |
||||||
2595 | ]; |
||||||
2596 | } |
||||||
2597 | |||||||
2598 | /** |
||||||
2599 | * Get user path from user ID (returns an array). |
||||||
2600 | * The return format is a complete path to a folder ending with "/" |
||||||
2601 | * In case the first level of subdirectory of users/ does not exist, the |
||||||
2602 | * function will attempt to create it. Probably not the right place to do it |
||||||
2603 | * but at least it avoids headaches in many other places. |
||||||
2604 | * |
||||||
2605 | * @param int $id User ID |
||||||
2606 | * @param string $type Type of path to return (can be 'system', 'web', 'last') |
||||||
2607 | * |
||||||
2608 | * @return string User folder path (i.e. /var/www/chamilo/app/upload/users/1/1/) |
||||||
2609 | */ |
||||||
2610 | public static function getUserPathById($id, $type) |
||||||
2611 | { |
||||||
2612 | $id = (int) $id; |
||||||
2613 | if (!$id) { |
||||||
2614 | return null; |
||||||
2615 | } |
||||||
2616 | |||||||
2617 | $userPath = "users/$id/"; |
||||||
2618 | if (api_get_setting('split_users_upload_directory') === 'true') { |
||||||
2619 | $userPath = 'users/'.substr((string) $id, 0, 1).'/'.$id.'/'; |
||||||
2620 | // In exceptional cases, on some portals, the intermediate base user |
||||||
2621 | // directory might not have been created. Make sure it is before |
||||||
2622 | // going further. |
||||||
2623 | |||||||
2624 | $rootPath = api_get_path(SYS_UPLOAD_PATH).'users/'.substr((string) $id, 0, 1); |
||||||
2625 | if (!is_dir($rootPath)) { |
||||||
2626 | $perm = api_get_permissions_for_new_directories(); |
||||||
2627 | try { |
||||||
2628 | mkdir($rootPath, $perm); |
||||||
2629 | } catch (Exception $e) { |
||||||
2630 | error_log($e->getMessage()); |
||||||
2631 | } |
||||||
2632 | } |
||||||
2633 | } |
||||||
2634 | switch ($type) { |
||||||
2635 | case 'system': // Base: absolute system path. |
||||||
2636 | $userPath = api_get_path(SYS_UPLOAD_PATH).$userPath; |
||||||
2637 | break; |
||||||
2638 | case 'web': // Base: absolute web path. |
||||||
2639 | $userPath = api_get_path(WEB_UPLOAD_PATH).$userPath; |
||||||
2640 | break; |
||||||
2641 | case 'last': // Only the last part starting with users/ |
||||||
2642 | break; |
||||||
2643 | } |
||||||
2644 | |||||||
2645 | return $userPath; |
||||||
2646 | } |
||||||
2647 | |||||||
2648 | /** |
||||||
2649 | * Gets the current user image. |
||||||
2650 | * |
||||||
2651 | * @param string $user_id |
||||||
2652 | * @param int $size it can be USER_IMAGE_SIZE_SMALL, |
||||||
2653 | * USER_IMAGE_SIZE_MEDIUM, USER_IMAGE_SIZE_BIG or USER_IMAGE_SIZE_ORIGINAL |
||||||
2654 | * @param bool $addRandomId |
||||||
2655 | * @param array $userInfo to avoid query the DB |
||||||
2656 | * |
||||||
2657 | * @return string |
||||||
2658 | */ |
||||||
2659 | public static function getUserPicture( |
||||||
2660 | $user_id, |
||||||
2661 | $size = USER_IMAGE_SIZE_MEDIUM, |
||||||
2662 | $addRandomId = true, |
||||||
2663 | $userInfo = [] |
||||||
2664 | ) { |
||||||
2665 | // Make sure userInfo is defined. Otherwise, define it! |
||||||
2666 | if (empty($userInfo) || !is_array($userInfo) || count($userInfo) == 0) { |
||||||
2667 | if (empty($user_id)) { |
||||||
2668 | return ''; |
||||||
2669 | } else { |
||||||
2670 | $userInfo = api_get_user_info($user_id); |
||||||
2671 | } |
||||||
2672 | } |
||||||
2673 | |||||||
2674 | $imageWebPath = self::get_user_picture_path_by_id( |
||||||
2675 | $user_id, |
||||||
2676 | 'web', |
||||||
2677 | $userInfo |
||||||
2678 | ); |
||||||
2679 | $pictureWebFile = $imageWebPath['file']; |
||||||
2680 | $pictureWebDir = $imageWebPath['dir']; |
||||||
2681 | |||||||
2682 | $pictureAnonymousSize = '128'; |
||||||
2683 | $gravatarSize = 22; |
||||||
2684 | $realSizeName = 'small_'; |
||||||
2685 | |||||||
2686 | switch ($size) { |
||||||
2687 | case USER_IMAGE_SIZE_SMALL: |
||||||
2688 | $pictureAnonymousSize = '32'; |
||||||
2689 | $realSizeName = 'small_'; |
||||||
2690 | $gravatarSize = 32; |
||||||
2691 | break; |
||||||
2692 | case USER_IMAGE_SIZE_MEDIUM: |
||||||
2693 | $pictureAnonymousSize = '64'; |
||||||
2694 | $realSizeName = 'medium_'; |
||||||
2695 | $gravatarSize = 64; |
||||||
2696 | break; |
||||||
2697 | case USER_IMAGE_SIZE_ORIGINAL: |
||||||
2698 | $pictureAnonymousSize = '128'; |
||||||
2699 | $realSizeName = ''; |
||||||
2700 | $gravatarSize = 128; |
||||||
2701 | break; |
||||||
2702 | case USER_IMAGE_SIZE_BIG: |
||||||
2703 | $pictureAnonymousSize = '128'; |
||||||
2704 | $realSizeName = 'big_'; |
||||||
2705 | $gravatarSize = 128; |
||||||
2706 | break; |
||||||
2707 | } |
||||||
2708 | |||||||
2709 | $gravatarEnabled = api_get_setting('gravatar_enabled'); |
||||||
2710 | $anonymousPath = Display::returnIconPath('unknown.png', $pictureAnonymousSize); |
||||||
2711 | if ($pictureWebFile == 'unknown.jpg' || empty($pictureWebFile)) { |
||||||
2712 | if ($gravatarEnabled === 'true') { |
||||||
2713 | $file = self::getGravatar( |
||||||
2714 | $imageWebPath['email'], |
||||||
2715 | $gravatarSize, |
||||||
2716 | api_get_setting('gravatar_type') |
||||||
2717 | ); |
||||||
2718 | |||||||
2719 | if ($addRandomId) { |
||||||
2720 | $file .= '&rand='.uniqid(); |
||||||
2721 | } |
||||||
2722 | |||||||
2723 | return $file; |
||||||
2724 | } |
||||||
2725 | |||||||
2726 | return $anonymousPath; |
||||||
2727 | } |
||||||
2728 | |||||||
2729 | $pictureSysPath = self::get_user_picture_path_by_id($user_id, 'system'); |
||||||
2730 | $file = $pictureSysPath['dir'].$realSizeName.$pictureWebFile; |
||||||
2731 | $picture = ''; |
||||||
2732 | if (file_exists($file)) { |
||||||
2733 | $picture = $pictureWebDir.$realSizeName.$pictureWebFile; |
||||||
2734 | } else { |
||||||
2735 | $file = $pictureSysPath['dir'].$pictureWebFile; |
||||||
2736 | if (file_exists($file) && !is_dir($file)) { |
||||||
2737 | $picture = $pictureWebFile['dir'].$pictureWebFile; |
||||||
2738 | } |
||||||
2739 | } |
||||||
2740 | |||||||
2741 | if (empty($picture)) { |
||||||
2742 | return $anonymousPath; |
||||||
2743 | } |
||||||
2744 | |||||||
2745 | if ($addRandomId) { |
||||||
2746 | $picture .= '?rand='.uniqid(); |
||||||
2747 | } |
||||||
2748 | |||||||
2749 | return $picture; |
||||||
2750 | } |
||||||
2751 | |||||||
2752 | /** |
||||||
2753 | * Creates new user photos in various sizes of a user, or deletes user photos. |
||||||
2754 | * Note: This method relies on configuration setting from main/inc/conf/profile.conf.php. |
||||||
2755 | * |
||||||
2756 | * @param int $user_id the user internal identification number |
||||||
2757 | * @param string $file The common file name for the newly created photos. |
||||||
2758 | * It will be checked and modified for compatibility with the file system. |
||||||
2759 | * If full name is provided, path component is ignored. |
||||||
2760 | * If an empty name is provided, then old user photos are deleted only, |
||||||
2761 | * |
||||||
2762 | * @see UserManager::delete_user_picture() as the prefered way for deletion. |
||||||
2763 | * |
||||||
2764 | * @param string $source_file the full system name of the image from which user photos will be created |
||||||
2765 | * @param string $cropParameters Optional string that contents "x,y,width,height" of a cropped image format |
||||||
2766 | * |
||||||
2767 | * @return bool Returns the resulting common file name of created images which usually should be stored in database. |
||||||
2768 | * When deletion is requested returns empty string. |
||||||
2769 | * In case of internal error or negative validation returns FALSE. |
||||||
2770 | */ |
||||||
2771 | public static function update_user_picture( |
||||||
2772 | $user_id, |
||||||
2773 | $file = null, |
||||||
2774 | $source_file = null, |
||||||
2775 | $cropParameters = '' |
||||||
2776 | ) { |
||||||
2777 | if (empty($user_id)) { |
||||||
2778 | return false; |
||||||
2779 | } |
||||||
2780 | $delete = empty($file); |
||||||
2781 | if (empty($source_file)) { |
||||||
2782 | $source_file = $file; |
||||||
2783 | } |
||||||
2784 | |||||||
2785 | // User-reserved directory where photos have to be placed. |
||||||
2786 | $path_info = self::getUserPicturePathById($user_id, 'system'); |
||||||
2787 | $path = $path_info['dir']; |
||||||
2788 | |||||||
2789 | // If this directory does not exist - we create it. |
||||||
2790 | if (!file_exists($path)) { |
||||||
2791 | mkdir($path, api_get_permissions_for_new_directories(), true); |
||||||
2792 | } |
||||||
2793 | |||||||
2794 | // The old photos (if any). |
||||||
2795 | $old_file = $path_info['file']; |
||||||
2796 | |||||||
2797 | // Let us delete them. |
||||||
2798 | if ($old_file != 'unknown.jpg') { |
||||||
2799 | if (KEEP_THE_OLD_IMAGE_AFTER_CHANGE) { |
||||||
0 ignored issues
–
show
|
|||||||
2800 | $prefix = 'saved_'.date('Y_m_d_H_i_s').'_'.uniqid('').'_'; |
||||||
2801 | @rename($path.'small_'.$old_file, $path.$prefix.'small_'.$old_file); |
||||||
2802 | @rename($path.'medium_'.$old_file, $path.$prefix.'medium_'.$old_file); |
||||||
2803 | @rename($path.'big_'.$old_file, $path.$prefix.'big_'.$old_file); |
||||||
2804 | @rename($path.$old_file, $path.$prefix.$old_file); |
||||||
2805 | } else { |
||||||
2806 | @unlink($path.'small_'.$old_file); |
||||||
2807 | @unlink($path.'medium_'.$old_file); |
||||||
2808 | @unlink($path.'big_'.$old_file); |
||||||
2809 | @unlink($path.$old_file); |
||||||
2810 | } |
||||||
2811 | } |
||||||
2812 | |||||||
2813 | // Exit if only deletion has been requested. Return an empty picture name. |
||||||
2814 | if ($delete) { |
||||||
2815 | return ''; |
||||||
2816 | } |
||||||
2817 | |||||||
2818 | // Validation 2. |
||||||
2819 | $allowed_types = api_get_supported_image_extensions(); |
||||||
2820 | $file = str_replace('\\', '/', $file); |
||||||
2821 | $filename = (($pos = strrpos($file, '/')) !== false) ? substr($file, $pos + 1) : $file; |
||||||
2822 | $extension = strtolower(substr(strrchr($filename, '.'), 1)); |
||||||
2823 | if (!in_array($extension, $allowed_types)) { |
||||||
2824 | return false; |
||||||
2825 | } |
||||||
2826 | |||||||
2827 | // This is the common name for the new photos. |
||||||
2828 | if (KEEP_THE_NAME_WHEN_CHANGE_IMAGE && $old_file != 'unknown.jpg') { |
||||||
0 ignored issues
–
show
|
|||||||
2829 | $old_extension = strtolower(substr(strrchr($old_file, '.'), 1)); |
||||||
2830 | $filename = in_array($old_extension, $allowed_types) ? substr($old_file, 0, -strlen($old_extension)) : $old_file; |
||||||
2831 | $filename = (substr($filename, -1) == '.') ? $filename.$extension : $filename.'.'.$extension; |
||||||
2832 | } else { |
||||||
2833 | $filename = api_replace_dangerous_char($filename); |
||||||
2834 | if (PREFIX_IMAGE_FILENAME_WITH_UID) { |
||||||
0 ignored issues
–
show
|
|||||||
2835 | $filename = uniqid('').'_'.$filename; |
||||||
2836 | } |
||||||
2837 | // We always prefix user photos with user ids, so on setting |
||||||
2838 | // api_get_setting('split_users_upload_directory') === 'true' |
||||||
2839 | // the correspondent directories to be found successfully. |
||||||
2840 | $filename = $user_id.'_'.$filename; |
||||||
2841 | } |
||||||
2842 | |||||||
2843 | if (!file_exists($source_file)) { |
||||||
2844 | return false; |
||||||
2845 | } |
||||||
2846 | |||||||
2847 | $mimeContentType = mime_content_type($source_file); |
||||||
2848 | if (false === strpos($mimeContentType, 'image')) { |
||||||
2849 | return false; |
||||||
2850 | } |
||||||
2851 | |||||||
2852 | //Crop the image to adjust 1:1 ratio |
||||||
2853 | $image = new Image($source_file); |
||||||
2854 | $image->crop($cropParameters); |
||||||
2855 | |||||||
2856 | // Storing the new photos in 4 versions with various sizes. |
||||||
2857 | $userPath = self::getUserPathById($user_id, 'system'); |
||||||
2858 | |||||||
2859 | // If this path does not exist - we create it. |
||||||
2860 | if (!file_exists($userPath)) { |
||||||
2861 | mkdir($userPath, api_get_permissions_for_new_directories(), true); |
||||||
2862 | } |
||||||
2863 | $small = new Image($source_file); |
||||||
2864 | $small->resize(32); |
||||||
2865 | $small->send_image($userPath.'small_'.$filename); |
||||||
2866 | $medium = new Image($source_file); |
||||||
2867 | $medium->resize(85); |
||||||
2868 | $medium->send_image($userPath.'medium_'.$filename); |
||||||
2869 | $normal = new Image($source_file); |
||||||
2870 | $normal->resize(200); |
||||||
2871 | $normal->send_image($userPath.$filename); |
||||||
2872 | |||||||
2873 | $big = new Image($source_file); // This is the original picture. |
||||||
2874 | $big->send_image($userPath.'big_'.$filename); |
||||||
2875 | |||||||
2876 | $result = $small && $medium && $normal && $big; |
||||||
2877 | |||||||
2878 | return $result ? $filename : false; |
||||||
2879 | } |
||||||
2880 | |||||||
2881 | /** |
||||||
2882 | * Update User extra field file type into {user_folder}/{$extra_field}. |
||||||
2883 | * |
||||||
2884 | * @param int $user_id The user internal identification number |
||||||
2885 | * @param string $extra_field The $extra_field The extra field name |
||||||
2886 | * @param null $file The filename |
||||||
0 ignored issues
–
show
|
|||||||
2887 | * @param null $source_file The temporal filename |
||||||
0 ignored issues
–
show
|
|||||||
2888 | * |
||||||
2889 | * @return bool|null return filename if success, but false |
||||||
2890 | */ |
||||||
2891 | public static function update_user_extra_file( |
||||||
2892 | $user_id, |
||||||
2893 | $extra_field = '', |
||||||
2894 | $file = null, |
||||||
2895 | $source_file = null |
||||||
2896 | ) { |
||||||
2897 | // Add Filter |
||||||
2898 | $source_file = Security::filter_filename($source_file); |
||||||
2899 | $file = Security::filter_filename($file); |
||||||
2900 | |||||||
2901 | if (empty($user_id)) { |
||||||
2902 | return false; |
||||||
2903 | } |
||||||
2904 | |||||||
2905 | if (empty($source_file)) { |
||||||
2906 | $source_file = $file; |
||||||
2907 | } |
||||||
2908 | |||||||
2909 | // User-reserved directory where extra file have to be placed. |
||||||
2910 | $path_info = self::get_user_picture_path_by_id($user_id, 'system'); |
||||||
2911 | $path = $path_info['dir']; |
||||||
2912 | if (!empty($extra_field)) { |
||||||
2913 | $path .= $extra_field.'/'; |
||||||
2914 | } |
||||||
2915 | // If this directory does not exist - we create it. |
||||||
2916 | if (!file_exists($path)) { |
||||||
2917 | @mkdir($path, api_get_permissions_for_new_directories(), true); |
||||||
2918 | } |
||||||
2919 | |||||||
2920 | if (filter_extension($file)) { |
||||||
2921 | if (@move_uploaded_file($source_file, $path.$file)) { |
||||||
2922 | if ($extra_field) { |
||||||
2923 | return $extra_field.'/'.$file; |
||||||
2924 | } else { |
||||||
2925 | return $file; |
||||||
2926 | } |
||||||
2927 | } |
||||||
2928 | } |
||||||
2929 | |||||||
2930 | return false; // this should be returned if anything went wrong with the upload |
||||||
2931 | } |
||||||
2932 | |||||||
2933 | /** |
||||||
2934 | * Deletes user photos. |
||||||
2935 | * Note: This method relies on configuration setting from main/inc/conf/profile.conf.php. |
||||||
2936 | * |
||||||
2937 | * @param int $userId the user internal identification number |
||||||
2938 | * |
||||||
2939 | * @return mixed returns empty string on success, FALSE on error |
||||||
2940 | */ |
||||||
2941 | public static function deleteUserPicture($userId) |
||||||
2942 | { |
||||||
2943 | return self::update_user_picture($userId); |
||||||
2944 | } |
||||||
2945 | |||||||
2946 | /** |
||||||
2947 | * Returns an XHTML formatted list of productions for a user, or FALSE if he |
||||||
2948 | * doesn't have any. |
||||||
2949 | * |
||||||
2950 | * If there has been a request to remove a production, the function will return |
||||||
2951 | * without building the list unless forced to do so by the optional second |
||||||
2952 | * parameter. This increases performance by avoiding to read through the |
||||||
2953 | * productions on the filesystem before the removal request has been carried |
||||||
2954 | * out because they'll have to be re-read afterwards anyway. |
||||||
2955 | * |
||||||
2956 | * @param int $user_id User id |
||||||
2957 | * @param bool $force Optional parameter to force building after a removal request |
||||||
2958 | * @param bool $showDelete |
||||||
2959 | * |
||||||
2960 | * @return string A string containing the XHTML code to display the production list, or FALSE |
||||||
2961 | */ |
||||||
2962 | public static function build_production_list($user_id, $force = false, $showDelete = false) |
||||||
2963 | { |
||||||
2964 | if (!$force && !empty($_POST['remove_production'])) { |
||||||
2965 | return true; // postpone reading from the filesystem |
||||||
2966 | } |
||||||
2967 | |||||||
2968 | $productions = self::get_user_productions($user_id); |
||||||
2969 | |||||||
2970 | if (empty($productions)) { |
||||||
2971 | return false; |
||||||
2972 | } |
||||||
2973 | |||||||
2974 | $production_dir = self::getUserPathById($user_id, 'web'); |
||||||
2975 | $del_image = Display::returnIconPath('delete.png'); |
||||||
2976 | $add_image = Display::returnIconPath('archive.png'); |
||||||
2977 | $del_text = get_lang('Delete'); |
||||||
2978 | $production_list = ''; |
||||||
2979 | if (count($productions) > 0) { |
||||||
2980 | $production_list = '<div class="files-production"><ul id="productions">'; |
||||||
2981 | foreach ($productions as $file) { |
||||||
2982 | $production_list .= '<li> |
||||||
2983 | <img src="'.$add_image.'" /> |
||||||
2984 | <a href="'.$production_dir.urlencode($file).'" target="_blank"> |
||||||
2985 | '.htmlentities($file).' |
||||||
2986 | </a>'; |
||||||
2987 | if ($showDelete) { |
||||||
2988 | $production_list .= ' |
||||||
2989 | <input |
||||||
2990 | style="width:16px;" |
||||||
2991 | type="image" |
||||||
2992 | name="remove_production['.urlencode($file).']" |
||||||
2993 | src="'.$del_image.'" |
||||||
2994 | alt="'.$del_text.'" |
||||||
2995 | title="'.$del_text.' '.htmlentities($file).'" |
||||||
2996 | onclick="javascript: return confirmation(\''.htmlentities($file).'\');" /></li>'; |
||||||
2997 | } |
||||||
2998 | } |
||||||
2999 | $production_list .= '</ul></div>'; |
||||||
3000 | } |
||||||
3001 | |||||||
3002 | return $production_list; |
||||||
3003 | } |
||||||
3004 | |||||||
3005 | /** |
||||||
3006 | * Returns an array with the user's productions. |
||||||
3007 | * |
||||||
3008 | * @param int $user_id User id |
||||||
3009 | * |
||||||
3010 | * @return array An array containing the user's productions |
||||||
3011 | */ |
||||||
3012 | public static function get_user_productions($user_id) |
||||||
3013 | { |
||||||
3014 | $production_repository = self::getUserPathById($user_id, 'system'); |
||||||
3015 | $productions = []; |
||||||
3016 | |||||||
3017 | if (is_dir($production_repository)) { |
||||||
3018 | $handle = opendir($production_repository); |
||||||
3019 | while ($file = readdir($handle)) { |
||||||
3020 | if ($file == '.' || |
||||||
3021 | $file == '..' || |
||||||
3022 | $file == '.htaccess' || |
||||||
3023 | is_dir($production_repository.$file) |
||||||
3024 | ) { |
||||||
3025 | // skip current/parent directory and .htaccess |
||||||
3026 | continue; |
||||||
3027 | } |
||||||
3028 | |||||||
3029 | if (preg_match('/('.$user_id.'|[0-9a-f]{13}|saved)_.+\.(png|jpg|jpeg|gif)$/i', $file)) { |
||||||
3030 | // User's photos should not be listed as productions. |
||||||
3031 | continue; |
||||||
3032 | } |
||||||
3033 | $productions[] = $file; |
||||||
3034 | } |
||||||
3035 | } |
||||||
3036 | |||||||
3037 | return $productions; |
||||||
3038 | } |
||||||
3039 | |||||||
3040 | /** |
||||||
3041 | * Remove a user production. |
||||||
3042 | * |
||||||
3043 | * @param int $user_id User id |
||||||
3044 | * @param string $production The production to remove |
||||||
3045 | * |
||||||
3046 | * @return bool |
||||||
3047 | */ |
||||||
3048 | public static function remove_user_production($user_id, $production) |
||||||
3049 | { |
||||||
3050 | $production_path = self::get_user_picture_path_by_id($user_id, 'system'); |
||||||
3051 | $production_file = $production_path['dir'].$production; |
||||||
3052 | if (is_file($production_file)) { |
||||||
3053 | unlink($production_file); |
||||||
3054 | |||||||
3055 | return true; |
||||||
3056 | } |
||||||
3057 | |||||||
3058 | return false; |
||||||
3059 | } |
||||||
3060 | |||||||
3061 | /** |
||||||
3062 | * Update an extra field value for a given user. |
||||||
3063 | * |
||||||
3064 | * @param int $userId User ID |
||||||
3065 | * @param string $variable Field variable name |
||||||
3066 | * @param string $value Field value |
||||||
3067 | * |
||||||
3068 | * @return bool true if field updated, false otherwise |
||||||
3069 | */ |
||||||
3070 | public static function update_extra_field_value($userId, $variable, $value = '') |
||||||
3071 | { |
||||||
3072 | $extraFieldValue = new ExtraFieldValue('user'); |
||||||
3073 | $params = [ |
||||||
3074 | 'item_id' => $userId, |
||||||
3075 | 'variable' => $variable, |
||||||
3076 | 'value' => $value, |
||||||
3077 | ]; |
||||||
3078 | |||||||
3079 | return $extraFieldValue->save($params); |
||||||
0 ignored issues
–
show
|
|||||||
3080 | } |
||||||
3081 | |||||||
3082 | /** |
||||||
3083 | * Get an array of extra fields with field details (type, default value and options). |
||||||
3084 | * |
||||||
3085 | * @param int Offset (from which row) |
||||||
3086 | * @param int Number of items |
||||||
3087 | * @param int Column on which sorting is made |
||||||
3088 | * @param string Sorting direction |
||||||
3089 | * @param bool Optional. Whether we get all the fields or just the visible ones |
||||||
0 ignored issues
–
show
|
|||||||
3090 | * @param int Optional. Whether we get all the fields with field_filter 1 or 0 or everything |
||||||
3091 | * |
||||||
3092 | * @return array Extra fields details (e.g. $list[2]['type'], $list[4]['options'][2]['title'] |
||||||
3093 | */ |
||||||
3094 | public static function get_extra_fields( |
||||||
3095 | $from = 0, |
||||||
3096 | $number_of_items = 0, |
||||||
3097 | $column = 5, |
||||||
3098 | $direction = 'ASC', |
||||||
3099 | $all_visibility = true, |
||||||
3100 | $field_filter = null |
||||||
3101 | ) { |
||||||
3102 | $fields = []; |
||||||
3103 | $t_uf = Database::get_main_table(TABLE_EXTRA_FIELD); |
||||||
3104 | $t_ufo = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS); |
||||||
3105 | $columns = [ |
||||||
3106 | 'id', |
||||||
3107 | 'variable', |
||||||
3108 | 'field_type', |
||||||
3109 | 'display_text', |
||||||
3110 | 'default_value', |
||||||
3111 | 'field_order', |
||||||
3112 | 'filter', |
||||||
3113 | ]; |
||||||
3114 | $column = (int) $column; |
||||||
3115 | $sort_direction = ''; |
||||||
3116 | if (!empty($direction)) { |
||||||
3117 | if (in_array(strtoupper($direction), ['ASC', 'DESC'])) { |
||||||
3118 | $sort_direction = strtoupper($direction); |
||||||
3119 | } |
||||||
3120 | } |
||||||
3121 | $extraFieldType = EntityExtraField::USER_FIELD_TYPE; |
||||||
3122 | $sqlf = "SELECT * FROM $t_uf WHERE extra_field_type = $extraFieldType "; |
||||||
3123 | if (!$all_visibility) { |
||||||
3124 | $sqlf .= " AND visible_to_self = 1 "; |
||||||
3125 | } |
||||||
3126 | if (!is_null($field_filter)) { |
||||||
3127 | $field_filter = (int) $field_filter; |
||||||
3128 | $sqlf .= " AND filter = $field_filter "; |
||||||
3129 | } |
||||||
3130 | $sqlf .= " ORDER BY `".$columns[$column]."` $sort_direction "; |
||||||
3131 | if ($number_of_items != 0) { |
||||||
3132 | $sqlf .= " LIMIT ".intval($from).','.intval($number_of_items); |
||||||
3133 | } |
||||||
3134 | $resf = Database::query($sqlf); |
||||||
3135 | if (Database::num_rows($resf) > 0) { |
||||||
3136 | while ($rowf = Database::fetch_array($resf)) { |
||||||
3137 | $fields[$rowf['id']] = [ |
||||||
3138 | 0 => $rowf['id'], |
||||||
3139 | 1 => $rowf['variable'], |
||||||
3140 | 2 => $rowf['field_type'], |
||||||
3141 | 3 => empty($rowf['display_text']) ? '' : $rowf['display_text'], |
||||||
3142 | 4 => $rowf['default_value'], |
||||||
3143 | 5 => $rowf['field_order'], |
||||||
3144 | 6 => $rowf['visible_to_self'], |
||||||
3145 | 7 => $rowf['changeable'], |
||||||
3146 | 8 => $rowf['filter'], |
||||||
3147 | 9 => [], |
||||||
3148 | 10 => '<a name="'.$rowf['id'].'"></a>', |
||||||
3149 | ]; |
||||||
3150 | |||||||
3151 | $sqlo = "SELECT * FROM $t_ufo |
||||||
3152 | WHERE field_id = ".$rowf['id']." |
||||||
3153 | ORDER BY option_order ASC"; |
||||||
3154 | $reso = Database::query($sqlo); |
||||||
3155 | if (Database::num_rows($reso) > 0) { |
||||||
3156 | while ($rowo = Database::fetch_array($reso)) { |
||||||
3157 | $fields[$rowf['id']][9][$rowo['id']] = [ |
||||||
3158 | 0 => $rowo['id'], |
||||||
3159 | 1 => $rowo['option_value'], |
||||||
3160 | 2 => empty($rowo['display_text']) ? '' : $rowo['display_text'], |
||||||
3161 | 3 => $rowo['option_order'], |
||||||
3162 | ]; |
||||||
3163 | } |
||||||
3164 | } |
||||||
3165 | } |
||||||
3166 | } |
||||||
3167 | |||||||
3168 | return $fields; |
||||||
3169 | } |
||||||
3170 | |||||||
3171 | /** |
||||||
3172 | * Build a list of extra file already uploaded in $user_folder/{$extra_field}/. |
||||||
3173 | * |
||||||
3174 | * @param $user_id |
||||||
3175 | * @param $extra_field |
||||||
3176 | * @param bool $force |
||||||
3177 | * @param bool $showDelete |
||||||
3178 | * |
||||||
3179 | * @return bool|string |
||||||
3180 | */ |
||||||
3181 | public static function build_user_extra_file_list( |
||||||
3182 | $user_id, |
||||||
3183 | $extra_field, |
||||||
3184 | $force = false, |
||||||
3185 | $showDelete = false |
||||||
3186 | ) { |
||||||
3187 | if (!$force && !empty($_POST['remove_'.$extra_field])) { |
||||||
3188 | return true; // postpone reading from the filesystem |
||||||
3189 | } |
||||||
3190 | |||||||
3191 | $extra_files = self::get_user_extra_files($user_id, $extra_field); |
||||||
3192 | if (empty($extra_files)) { |
||||||
3193 | return false; |
||||||
3194 | } |
||||||
3195 | |||||||
3196 | $path_info = self::get_user_picture_path_by_id($user_id, 'web'); |
||||||
3197 | $path = $path_info['dir']; |
||||||
3198 | $del_image = Display::returnIconPath('delete.png'); |
||||||
3199 | |||||||
3200 | $del_text = get_lang('Delete'); |
||||||
3201 | $extra_file_list = ''; |
||||||
3202 | if (count($extra_files) > 0) { |
||||||
3203 | $extra_file_list = '<div class="files-production"><ul id="productions">'; |
||||||
3204 | foreach ($extra_files as $file) { |
||||||
3205 | $filename = substr($file, strlen($extra_field) + 1); |
||||||
3206 | $extra_file_list .= '<li>'.Display::return_icon('archive.png'). |
||||||
3207 | '<a href="'.$path.$extra_field.'/'.urlencode($filename).'" target="_blank"> |
||||||
3208 | '.htmlentities($filename). |
||||||
3209 | '</a> '; |
||||||
3210 | if ($showDelete) { |
||||||
3211 | $extra_file_list .= '<input |
||||||
3212 | style="width:16px;" |
||||||
3213 | type="image" |
||||||
3214 | name="remove_extra_'.$extra_field.'['.urlencode($file).']" |
||||||
3215 | src="'.$del_image.'" |
||||||
3216 | alt="'.$del_text.'" |
||||||
3217 | title="'.$del_text.' '.htmlentities($filename).'" |
||||||
3218 | onclick="javascript: return confirmation(\''.htmlentities($filename).'\');" /></li>'; |
||||||
3219 | } |
||||||
3220 | } |
||||||
3221 | $extra_file_list .= '</ul></div>'; |
||||||
3222 | } |
||||||
3223 | |||||||
3224 | return $extra_file_list; |
||||||
3225 | } |
||||||
3226 | |||||||
3227 | /** |
||||||
3228 | * Get valid filenames in $user_folder/{$extra_field}/. |
||||||
3229 | * |
||||||
3230 | * @param $user_id |
||||||
3231 | * @param $extra_field |
||||||
3232 | * @param bool $full_path |
||||||
3233 | * |
||||||
3234 | * @return array |
||||||
3235 | */ |
||||||
3236 | public static function get_user_extra_files($user_id, $extra_field, $full_path = false) |
||||||
3237 | { |
||||||
3238 | if (!$full_path) { |
||||||
3239 | // Nothing to do |
||||||
3240 | } else { |
||||||
3241 | $path_info = self::get_user_picture_path_by_id($user_id, 'system'); |
||||||
3242 | $path = $path_info['dir']; |
||||||
3243 | } |
||||||
3244 | $extra_data = self::get_extra_user_data_by_field($user_id, $extra_field); |
||||||
3245 | $extra_files = $extra_data[$extra_field]; |
||||||
3246 | |||||||
3247 | $files = []; |
||||||
3248 | if (is_array($extra_files)) { |
||||||
3249 | foreach ($extra_files as $key => $value) { |
||||||
3250 | if (!$full_path) { |
||||||
3251 | // Relative path from user folder |
||||||
3252 | $files[] = $value; |
||||||
3253 | } else { |
||||||
3254 | $files[] = $path.$value; |
||||||
3255 | } |
||||||
3256 | } |
||||||
3257 | } elseif (!empty($extra_files)) { |
||||||
3258 | if (!$full_path) { |
||||||
3259 | // Relative path from user folder |
||||||
3260 | $files[] = $extra_files; |
||||||
3261 | } else { |
||||||
3262 | $files[] = $path.$extra_files; |
||||||
3263 | } |
||||||
3264 | } |
||||||
3265 | |||||||
3266 | return $files; // can be an empty array |
||||||
3267 | } |
||||||
3268 | |||||||
3269 | /** |
||||||
3270 | * Remove an {$extra_file} from the user folder $user_folder/{$extra_field}/. |
||||||
3271 | * |
||||||
3272 | * @param int $user_id |
||||||
3273 | * @param string $extra_field |
||||||
3274 | * @param string $extra_file |
||||||
3275 | * |
||||||
3276 | * @return bool |
||||||
3277 | */ |
||||||
3278 | public static function remove_user_extra_file($user_id, $extra_field, $extra_file) |
||||||
3279 | { |
||||||
3280 | $extra_file = Security::filter_filename($extra_file); |
||||||
3281 | $path_info = self::get_user_picture_path_by_id($user_id, 'system'); |
||||||
3282 | if (strpos($extra_file, $extra_field) !== false) { |
||||||
3283 | $path_extra_file = $path_info['dir'].$extra_file; |
||||||
3284 | } else { |
||||||
3285 | $path_extra_file = $path_info['dir'].$extra_field.'/'.$extra_file; |
||||||
3286 | } |
||||||
3287 | if (is_file($path_extra_file)) { |
||||||
3288 | unlink($path_extra_file); |
||||||
3289 | |||||||
3290 | return true; |
||||||
3291 | } |
||||||
3292 | |||||||
3293 | return false; |
||||||
3294 | } |
||||||
3295 | |||||||
3296 | /** |
||||||
3297 | * Creates a new extra field. |
||||||
3298 | * |
||||||
3299 | * @param string $variable Field's internal variable name |
||||||
3300 | * @param int $fieldType Field's type |
||||||
3301 | * @param string $displayText Field's language var name |
||||||
3302 | * @param string $default Field's default value |
||||||
3303 | * |
||||||
3304 | * @return int |
||||||
3305 | */ |
||||||
3306 | public static function create_extra_field( |
||||||
3307 | $variable, |
||||||
3308 | $fieldType, |
||||||
3309 | $displayText, |
||||||
3310 | $default |
||||||
3311 | ) { |
||||||
3312 | $extraField = new ExtraField('user'); |
||||||
3313 | $params = [ |
||||||
3314 | 'variable' => $variable, |
||||||
3315 | 'field_type' => $fieldType, |
||||||
3316 | 'display_text' => $displayText, |
||||||
3317 | 'default_value' => $default, |
||||||
3318 | ]; |
||||||
3319 | |||||||
3320 | return $extraField->save($params); |
||||||
0 ignored issues
–
show
|
|||||||
3321 | } |
||||||
3322 | |||||||
3323 | /** |
||||||
3324 | * Check if a field is available. |
||||||
3325 | * |
||||||
3326 | * @param string $variable |
||||||
3327 | * |
||||||
3328 | * @return bool |
||||||
3329 | */ |
||||||
3330 | public static function is_extra_field_available($variable) |
||||||
3331 | { |
||||||
3332 | $extraField = new ExtraField('user'); |
||||||
3333 | $data = $extraField->get_handler_field_info_by_field_variable($variable); |
||||||
3334 | |||||||
3335 | return !empty($data) ? true : false; |
||||||
3336 | } |
||||||
3337 | |||||||
3338 | /** |
||||||
3339 | * Gets user extra fields data. |
||||||
3340 | * |
||||||
3341 | * @param int User ID |
||||||
3342 | * @param bool Whether to prefix the fields indexes with "extra_" (might be used by formvalidator) |
||||||
3343 | * @param bool Whether to return invisible fields as well |
||||||
3344 | * @param bool Whether to split multiple-selection fields or not |
||||||
3345 | * @param mixed Whether to filter on the value of filter |
||||||
3346 | * |
||||||
3347 | * @return array Array of fields => value for the given user |
||||||
3348 | */ |
||||||
3349 | public static function get_extra_user_data( |
||||||
3350 | $user_id, |
||||||
3351 | $prefix = false, |
||||||
3352 | $allVisibility = true, |
||||||
3353 | $splitMultiple = false, |
||||||
3354 | $fieldFilter = null |
||||||
3355 | ) { |
||||||
3356 | $user_id = (int) $user_id; |
||||||
3357 | |||||||
3358 | if (empty($user_id)) { |
||||||
3359 | return []; |
||||||
3360 | } |
||||||
3361 | |||||||
3362 | $extra_data = []; |
||||||
3363 | $t_uf = Database::get_main_table(TABLE_EXTRA_FIELD); |
||||||
3364 | $t_ufv = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
||||||
3365 | $user_id = (int) $user_id; |
||||||
3366 | $sql = "SELECT f.id as id, f.variable as fvar, f.field_type as type |
||||||
3367 | FROM $t_uf f |
||||||
3368 | WHERE |
||||||
3369 | extra_field_type = ".EntityExtraField::USER_FIELD_TYPE." |
||||||
3370 | "; |
||||||
3371 | $filter_cond = ''; |
||||||
3372 | |||||||
3373 | if (!$allVisibility) { |
||||||
3374 | if (isset($fieldFilter)) { |
||||||
3375 | $fieldFilter = (int) $fieldFilter; |
||||||
3376 | $filter_cond .= " AND filter = $fieldFilter "; |
||||||
3377 | } |
||||||
3378 | $sql .= " AND f.visible_to_self = 1 $filter_cond "; |
||||||
3379 | } else { |
||||||
3380 | if (isset($fieldFilter)) { |
||||||
3381 | $fieldFilter = (int) $fieldFilter; |
||||||
3382 | $sql .= " AND filter = $fieldFilter "; |
||||||
3383 | } |
||||||
3384 | } |
||||||
3385 | |||||||
3386 | $sql .= ' ORDER BY f.field_order'; |
||||||
3387 | |||||||
3388 | $res = Database::query($sql); |
||||||
3389 | if (Database::num_rows($res) > 0) { |
||||||
3390 | while ($row = Database::fetch_array($res)) { |
||||||
3391 | if ($row['type'] == self::USER_FIELD_TYPE_TAG) { |
||||||
3392 | $tags = self::get_user_tags_to_string($user_id, $row['id'], false); |
||||||
3393 | $extra_data['extra_'.$row['fvar']] = $tags; |
||||||
3394 | } else { |
||||||
3395 | $sqlu = "SELECT value as fval |
||||||
3396 | FROM $t_ufv |
||||||
3397 | WHERE field_id = ".$row['id']." AND item_id = ".$user_id; |
||||||
3398 | $resu = Database::query($sqlu); |
||||||
3399 | |||||||
3400 | if (Database::num_rows($resu) > 0) { |
||||||
3401 | $rowu = Database::fetch_array($resu); |
||||||
3402 | $fval = $rowu['fval']; |
||||||
3403 | if ($row['type'] == self::USER_FIELD_TYPE_SELECT_MULTIPLE) { |
||||||
3404 | $fval = explode(';', $rowu['fval']); |
||||||
3405 | } |
||||||
3406 | } else { |
||||||
3407 | // get default value |
||||||
3408 | $sql_df = "SELECT default_value as fval_df FROM $t_uf |
||||||
3409 | WHERE id = ".$row['id']; |
||||||
3410 | $res_df = Database::query($sql_df); |
||||||
3411 | $row_df = Database::fetch_array($res_df); |
||||||
3412 | $fval = $row_df['fval_df']; |
||||||
3413 | } |
||||||
3414 | // We get here (and fill the $extra_data array) even if there |
||||||
3415 | // is no user with data (we fill it with default values) |
||||||
3416 | if ($prefix) { |
||||||
3417 | if ($row['type'] == self::USER_FIELD_TYPE_RADIO) { |
||||||
3418 | $extra_data['extra_'.$row['fvar']]['extra_'.$row['fvar']] = $fval; |
||||||
3419 | } else { |
||||||
3420 | $extra_data['extra_'.$row['fvar']] = $fval; |
||||||
3421 | } |
||||||
3422 | } else { |
||||||
3423 | if ($row['type'] == self::USER_FIELD_TYPE_RADIO) { |
||||||
3424 | $extra_data['extra_'.$row['fvar']]['extra_'.$row['fvar']] = $fval; |
||||||
3425 | } else { |
||||||
3426 | $extra_data[$row['fvar']] = $fval; |
||||||
3427 | } |
||||||
3428 | } |
||||||
3429 | } |
||||||
3430 | } |
||||||
3431 | } |
||||||
3432 | |||||||
3433 | return $extra_data; |
||||||
3434 | } |
||||||
3435 | |||||||
3436 | /** |
||||||
3437 | * Get extra user data by field. |
||||||
3438 | * |
||||||
3439 | * @param int user ID |
||||||
3440 | * @param string the internal variable name of the field |
||||||
3441 | * |
||||||
3442 | * @return array with extra data info of a user i.e array('field_variable'=>'value'); |
||||||
3443 | */ |
||||||
3444 | public static function get_extra_user_data_by_field( |
||||||
3445 | $user_id, |
||||||
3446 | $field_variable, |
||||||
3447 | $prefix = false, |
||||||
3448 | $all_visibility = true, |
||||||
3449 | $splitmultiple = false |
||||||
3450 | ) { |
||||||
3451 | $user_id = (int) $user_id; |
||||||
3452 | |||||||
3453 | if (empty($user_id)) { |
||||||
3454 | return []; |
||||||
3455 | } |
||||||
3456 | |||||||
3457 | $extra_data = []; |
||||||
3458 | $t_uf = Database::get_main_table(TABLE_EXTRA_FIELD); |
||||||
3459 | $t_ufv = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
||||||
3460 | |||||||
3461 | $sql = "SELECT f.id as id, f.variable as fvar, f.field_type as type |
||||||
3462 | FROM $t_uf f |
||||||
3463 | WHERE f.variable = '$field_variable' "; |
||||||
3464 | |||||||
3465 | if (!$all_visibility) { |
||||||
3466 | $sql .= " AND f.visible_to_self = 1 "; |
||||||
3467 | } |
||||||
3468 | |||||||
3469 | $sql .= " AND extra_field_type = ".EntityExtraField::USER_FIELD_TYPE; |
||||||
3470 | $sql .= " ORDER BY f.field_order "; |
||||||
3471 | |||||||
3472 | $res = Database::query($sql); |
||||||
3473 | if (Database::num_rows($res) > 0) { |
||||||
3474 | while ($row = Database::fetch_array($res)) { |
||||||
3475 | $sqlu = "SELECT value as fval FROM $t_ufv v |
||||||
3476 | INNER JOIN $t_uf f |
||||||
3477 | ON (v.field_id = f.id) |
||||||
3478 | WHERE |
||||||
3479 | extra_field_type = ".EntityExtraField::USER_FIELD_TYPE." AND |
||||||
3480 | field_id = ".$row['id']." AND |
||||||
3481 | item_id = ".$user_id; |
||||||
3482 | $resu = Database::query($sqlu); |
||||||
3483 | $fval = ''; |
||||||
3484 | if (Database::num_rows($resu) > 0) { |
||||||
3485 | $rowu = Database::fetch_array($resu); |
||||||
3486 | $fval = $rowu['fval']; |
||||||
3487 | if ($row['type'] == self::USER_FIELD_TYPE_SELECT_MULTIPLE) { |
||||||
3488 | $fval = explode(';', $rowu['fval']); |
||||||
3489 | } |
||||||
3490 | } |
||||||
3491 | if ($prefix) { |
||||||
3492 | $extra_data['extra_'.$row['fvar']] = $fval; |
||||||
3493 | } else { |
||||||
3494 | $extra_data[$row['fvar']] = $fval; |
||||||
3495 | } |
||||||
3496 | } |
||||||
3497 | } |
||||||
3498 | |||||||
3499 | return $extra_data; |
||||||
3500 | } |
||||||
3501 | |||||||
3502 | /** |
||||||
3503 | * Get the extra field information for a certain field (the options as well). |
||||||
3504 | * |
||||||
3505 | * @param string $variable The name of the field we want to know everything about |
||||||
3506 | * |
||||||
3507 | * @return array Array containing all the information about the extra profile field |
||||||
3508 | * (first level of array contains field details, then 'options' sub-array contains options details, |
||||||
3509 | * as returned by the database) |
||||||
3510 | * |
||||||
3511 | * @author Julio Montoya |
||||||
3512 | * |
||||||
3513 | * @since v1.8.6 |
||||||
3514 | */ |
||||||
3515 | public static function get_extra_field_information_by_name($variable) |
||||||
3516 | { |
||||||
3517 | $extraField = new ExtraField('user'); |
||||||
3518 | |||||||
3519 | return $extraField->get_handler_field_info_by_field_variable($variable); |
||||||
0 ignored issues
–
show
|
|||||||
3520 | } |
||||||
3521 | |||||||
3522 | /** |
||||||
3523 | * Get the extra field information for user tag (the options as well). |
||||||
3524 | * |
||||||
3525 | * @param int $variable The name of the field we want to know everything about |
||||||
3526 | * |
||||||
3527 | * @return array Array containing all the information about the extra profile field |
||||||
3528 | * (first level of array contains field details, then 'options' sub-array contains options details, |
||||||
3529 | * as returned by the database) |
||||||
3530 | * |
||||||
3531 | * @author José Loguercio |
||||||
3532 | * |
||||||
3533 | * @since v1.11.0 |
||||||
3534 | */ |
||||||
3535 | public static function get_extra_field_tags_information_by_name($variable) |
||||||
3536 | { |
||||||
3537 | $extraField = new ExtraField('user'); |
||||||
3538 | |||||||
3539 | return $extraField->get_handler_field_info_by_tags($variable); |
||||||
0 ignored issues
–
show
|
|||||||
3540 | } |
||||||
3541 | |||||||
3542 | /** |
||||||
3543 | * @param string $type |
||||||
3544 | * |
||||||
3545 | * @return array |
||||||
3546 | */ |
||||||
3547 | public static function get_all_extra_field_by_type($type) |
||||||
3548 | { |
||||||
3549 | $extraField = new ExtraField('user'); |
||||||
3550 | |||||||
3551 | return $extraField->get_all_extra_field_by_type($type); |
||||||
3552 | } |
||||||
3553 | |||||||
3554 | /** |
||||||
3555 | * Get all the extra field information of a certain field (also the options). |
||||||
3556 | * |
||||||
3557 | * @param int $fieldId the ID of the field we want to know everything of |
||||||
3558 | * |
||||||
3559 | * @return array $return containing all th information about the extra profile field |
||||||
3560 | * |
||||||
3561 | * @author Julio Montoya |
||||||
3562 | * |
||||||
3563 | * @deprecated |
||||||
3564 | * @since v1.8.6 |
||||||
3565 | */ |
||||||
3566 | public static function get_extra_field_information($fieldId) |
||||||
3567 | { |
||||||
3568 | $extraField = new ExtraField('user'); |
||||||
3569 | |||||||
3570 | return $extraField->getFieldInfoByFieldId($fieldId); |
||||||
0 ignored issues
–
show
|
|||||||
3571 | } |
||||||
3572 | |||||||
3573 | /** |
||||||
3574 | * Get extra user data by value. |
||||||
3575 | * |
||||||
3576 | * @param string $variable the internal variable name of the field |
||||||
3577 | * @param string $value the internal value of the field |
||||||
3578 | * @param bool $useLike |
||||||
3579 | * |
||||||
3580 | * @return array with extra data info of a user i.e array('field_variable'=>'value'); |
||||||
3581 | */ |
||||||
3582 | public static function get_extra_user_data_by_value($variable, $value, $useLike = false) |
||||||
3583 | { |
||||||
3584 | $extraFieldValue = new ExtraFieldValue('user'); |
||||||
3585 | $extraField = new ExtraField('user'); |
||||||
3586 | |||||||
3587 | $info = $extraField->get_handler_field_info_by_field_variable($variable); |
||||||
3588 | |||||||
3589 | if (false === $info) { |
||||||
3590 | return []; |
||||||
3591 | } |
||||||
3592 | |||||||
3593 | $data = $extraFieldValue->get_item_id_from_field_variable_and_field_value( |
||||||
3594 | $variable, |
||||||
3595 | $value, |
||||||
3596 | false, |
||||||
3597 | false, |
||||||
3598 | true, |
||||||
3599 | $useLike |
||||||
3600 | ); |
||||||
3601 | |||||||
3602 | $result = []; |
||||||
3603 | if (!empty($data)) { |
||||||
3604 | foreach ($data as $item) { |
||||||
3605 | $result[] = $item['item_id']; |
||||||
3606 | } |
||||||
3607 | } |
||||||
3608 | |||||||
3609 | return $result; |
||||||
3610 | } |
||||||
3611 | |||||||
3612 | /** |
||||||
3613 | * Get extra user data by tags value. |
||||||
3614 | * |
||||||
3615 | * @param int $fieldId the ID of the field we want to know everything of |
||||||
3616 | * @param string $tag the tag name for search |
||||||
3617 | * |
||||||
3618 | * @return array with extra data info of a user |
||||||
3619 | * |
||||||
3620 | * @author José Loguercio |
||||||
3621 | * |
||||||
3622 | * @since v1.11.0 |
||||||
3623 | */ |
||||||
3624 | public static function get_extra_user_data_by_tags($fieldId, $tag) |
||||||
3625 | { |
||||||
3626 | $extraField = new ExtraField('user'); |
||||||
3627 | $result = $extraField->getAllUserPerTag($fieldId, $tag); |
||||||
3628 | $array = []; |
||||||
3629 | foreach ($result as $index => $user) { |
||||||
3630 | $array[] = $user['user_id']; |
||||||
3631 | } |
||||||
3632 | |||||||
3633 | return $array; |
||||||
3634 | } |
||||||
3635 | |||||||
3636 | /** |
||||||
3637 | * Get extra user data by field variable. |
||||||
3638 | * |
||||||
3639 | * @param string $variable field variable |
||||||
3640 | * |
||||||
3641 | * @return array data |
||||||
3642 | */ |
||||||
3643 | public static function get_extra_user_data_by_field_variable($variable) |
||||||
3644 | { |
||||||
3645 | $extraInfo = self::get_extra_field_information_by_name($variable); |
||||||
3646 | $field_id = (int) $extraInfo['id']; |
||||||
3647 | |||||||
3648 | $extraField = new ExtraFieldValue('user'); |
||||||
3649 | $data = $extraField->getValuesByFieldId($field_id); |
||||||
3650 | |||||||
3651 | if (!empty($data)) { |
||||||
3652 | foreach ($data as $row) { |
||||||
3653 | $user_id = $row['item_id']; |
||||||
3654 | $data[$user_id] = $row; |
||||||
3655 | } |
||||||
3656 | } |
||||||
3657 | |||||||
3658 | return $data; |
||||||
0 ignored issues
–
show
The expression
return $data could also return false which is incompatible with the documented return type array . Did you maybe forget to handle an error condition?
If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.
Loading history...
|
|||||||
3659 | } |
||||||
3660 | |||||||
3661 | /** |
||||||
3662 | * Get extra user data tags by field variable. |
||||||
3663 | * |
||||||
3664 | * @param string $variable field variable |
||||||
3665 | * |
||||||
3666 | * @return array |
||||||
3667 | */ |
||||||
3668 | public static function get_extra_user_data_for_tags($variable) |
||||||
3669 | { |
||||||
3670 | $data = self::get_extra_field_tags_information_by_name($variable); |
||||||
3671 | |||||||
3672 | return $data; |
||||||
3673 | } |
||||||
3674 | |||||||
3675 | /** |
||||||
3676 | * Gives a list of [session_category][session_id] for the current user. |
||||||
3677 | * |
||||||
3678 | * @param int $user_id |
||||||
3679 | * @param bool $is_time_over whether to fill the first element or not |
||||||
3680 | * (to give space for courses out of categories) |
||||||
3681 | * @param bool $ignore_visibility_for_admins optional true if limit time from session is over, false otherwise |
||||||
3682 | * @param bool $ignoreTimeLimit ignore time start/end |
||||||
3683 | * @param bool $getCount |
||||||
3684 | * |
||||||
3685 | * @return array list of statuses [session_category][session_id] |
||||||
3686 | * |
||||||
3687 | * @todo ensure multiple access urls are managed correctly |
||||||
3688 | */ |
||||||
3689 | public static function get_sessions_by_category( |
||||||
3690 | $user_id, |
||||||
3691 | $is_time_over = true, |
||||||
3692 | $ignore_visibility_for_admins = false, |
||||||
3693 | $ignoreTimeLimit = false, |
||||||
3694 | $getCount = false |
||||||
3695 | ) { |
||||||
3696 | $user_id = (int) $user_id; |
||||||
3697 | |||||||
3698 | if (empty($user_id)) { |
||||||
3699 | return []; |
||||||
3700 | } |
||||||
3701 | |||||||
3702 | $allowOrder = api_get_configuration_value('session_list_order'); |
||||||
3703 | $position = ''; |
||||||
3704 | if ($allowOrder) { |
||||||
3705 | $position = ', s.position AS position '; |
||||||
3706 | } |
||||||
3707 | |||||||
3708 | // Get the list of sessions per user |
||||||
3709 | $now = new DateTime('now', new DateTimeZone('UTC')); |
||||||
3710 | |||||||
3711 | // LEFT JOIN is used for session_rel_course_rel_user because an inner |
||||||
3712 | // join would not catch session-courses where the user is general |
||||||
3713 | // session coach but which do not have students nor coaches registered |
||||||
3714 | $dqlSelect = ' COUNT(DISTINCT s.id) '; |
||||||
3715 | |||||||
3716 | if (!$getCount) { |
||||||
3717 | $dqlSelect = " DISTINCT |
||||||
3718 | s.id, |
||||||
3719 | s.name, |
||||||
3720 | s.accessStartDate AS access_start_date, |
||||||
3721 | s.accessEndDate AS access_end_date, |
||||||
3722 | s.duration, |
||||||
3723 | sc.id AS session_category_id, |
||||||
3724 | sc.name AS session_category_name, |
||||||
3725 | sc.dateStart AS session_category_date_start, |
||||||
3726 | sc.dateEnd AS session_category_date_end, |
||||||
3727 | s.coachAccessStartDate AS coach_access_start_date, |
||||||
3728 | s.coachAccessEndDate AS coach_access_end_date, |
||||||
3729 | CASE WHEN s.accessEndDate IS NULL THEN 1 ELSE 0 END HIDDEN _isFieldNull |
||||||
3730 | $position |
||||||
3731 | "; |
||||||
3732 | } |
||||||
3733 | |||||||
3734 | $dql = "SELECT $dqlSelect |
||||||
3735 | FROM ChamiloCoreBundle:Session AS s |
||||||
3736 | LEFT JOIN ChamiloCoreBundle:SessionRelCourseRelUser AS scu WITH scu.session = s |
||||||
3737 | INNER JOIN ChamiloCoreBundle:AccessUrlRelSession AS url WITH url.sessionId = s.id |
||||||
3738 | LEFT JOIN ChamiloCoreBundle:SessionCategory AS sc WITH s.category = sc "; |
||||||
3739 | |||||||
3740 | // A single OR operation on scu.user = :user OR s.generalCoach = :user |
||||||
3741 | // is awfully inefficient for large sets of data (1m25s for 58K |
||||||
3742 | // sessions, BT#14115) but executing a similar query twice and grouping |
||||||
3743 | // the results afterwards in PHP takes about 1/1000th of the time |
||||||
3744 | // (0.1s + 0.0s) for the same set of data, so we do it this way... |
||||||
3745 | $dqlStudent = $dql.' WHERE scu.user = :user AND url.accessUrlId = :url '; |
||||||
3746 | $dqlCoach = $dql.' WHERE s.generalCoach = :user AND url.accessUrlId = :url '; |
||||||
3747 | |||||||
3748 | // Default order |
||||||
3749 | $order = 'ORDER BY sc.name, s.name'; |
||||||
3750 | |||||||
3751 | // Order by date if showing all sessions |
||||||
3752 | $showAllSessions = api_get_configuration_value('show_all_sessions_on_my_course_page') === true; |
||||||
3753 | if ($showAllSessions) { |
||||||
3754 | $order = 'ORDER BY s.accessStartDate'; |
||||||
3755 | } |
||||||
3756 | |||||||
3757 | // Order by position |
||||||
3758 | if ($allowOrder) { |
||||||
3759 | $order = 'ORDER BY s.position'; |
||||||
3760 | } |
||||||
3761 | |||||||
3762 | // Order by dates according to settings |
||||||
3763 | $orderBySettings = api_get_configuration_value('my_courses_session_order'); |
||||||
3764 | if (!empty($orderBySettings) && isset($orderBySettings['field']) && isset($orderBySettings['order'])) { |
||||||
3765 | $field = $orderBySettings['field']; |
||||||
3766 | $orderSetting = $orderBySettings['order']; |
||||||
3767 | switch ($field) { |
||||||
3768 | case 'start_date': |
||||||
3769 | $order = " ORDER BY s.accessStartDate $orderSetting"; |
||||||
3770 | break; |
||||||
3771 | case 'end_date': |
||||||
3772 | $order = " ORDER BY s.accessEndDate $orderSetting "; |
||||||
3773 | if ($orderSetting === 'asc') { |
||||||
3774 | // Put null values at the end |
||||||
3775 | // https://stackoverflow.com/questions/12652034/how-can-i-order-by-null-in-dql |
||||||
3776 | $order = ' ORDER BY _isFieldNull asc, s.accessEndDate asc'; |
||||||
3777 | } |
||||||
3778 | break; |
||||||
3779 | case 'name': |
||||||
3780 | $order = " ORDER BY s.name $orderSetting "; |
||||||
3781 | break; |
||||||
3782 | } |
||||||
3783 | } |
||||||
3784 | |||||||
3785 | $dqlStudent .= $order; |
||||||
3786 | $dqlCoach .= $order; |
||||||
3787 | |||||||
3788 | $accessUrlId = api_get_current_access_url_id(); |
||||||
3789 | $dqlStudent = Database::getManager() |
||||||
3790 | ->createQuery($dqlStudent) |
||||||
3791 | ->setParameters( |
||||||
3792 | ['user' => $user_id, 'url' => $accessUrlId] |
||||||
3793 | ) |
||||||
3794 | ; |
||||||
3795 | $dqlCoach = Database::getManager() |
||||||
3796 | ->createQuery($dqlCoach) |
||||||
3797 | ->setParameters( |
||||||
3798 | ['user' => $user_id, 'url' => $accessUrlId] |
||||||
3799 | ) |
||||||
3800 | ; |
||||||
3801 | |||||||
3802 | if ($getCount) { |
||||||
3803 | return $dqlStudent->getSingleScalarResult() + $dqlCoach->getSingleScalarResult(); |
||||||
3804 | } |
||||||
3805 | |||||||
3806 | $sessionDataStudent = $dqlStudent->getResult(); |
||||||
3807 | $sessionDataCoach = $dqlCoach->getResult(); |
||||||
3808 | |||||||
3809 | $sessionData = []; |
||||||
3810 | // First fill $sessionData with student sessions |
||||||
3811 | if (!empty($sessionDataStudent)) { |
||||||
3812 | foreach ($sessionDataStudent as $row) { |
||||||
3813 | $sessionData[$row['id']] = $row; |
||||||
3814 | } |
||||||
3815 | } |
||||||
3816 | |||||||
3817 | // Overwrite session data of the user as a student with session data |
||||||
3818 | // of the user as a coach. |
||||||
3819 | // There shouldn't be such duplicate rows, but just in case... |
||||||
3820 | if (!empty($sessionDataCoach)) { |
||||||
3821 | foreach ($sessionDataCoach as $row) { |
||||||
3822 | $sessionData[$row['id']] = $row; |
||||||
3823 | } |
||||||
3824 | } |
||||||
3825 | |||||||
3826 | $collapsable = api_get_configuration_value('allow_user_session_collapsable'); |
||||||
3827 | $extraField = new ExtraFieldValue('session'); |
||||||
3828 | $collapsableLink = api_get_path(WEB_PATH).'user_portal.php?action=collapse_session'; |
||||||
3829 | |||||||
3830 | if (empty($sessionData)) { |
||||||
3831 | return []; |
||||||
3832 | } |
||||||
3833 | |||||||
3834 | $categories = []; |
||||||
3835 | foreach ($sessionData as $row) { |
||||||
3836 | $session_id = $row['id']; |
||||||
3837 | $coachList = SessionManager::getCoachesBySession($session_id); |
||||||
3838 | $categoryStart = $row['session_category_date_start'] ? $row['session_category_date_start']->format('Y-m-d') : ''; |
||||||
3839 | $categoryEnd = $row['session_category_date_end'] ? $row['session_category_date_end']->format('Y-m-d') : ''; |
||||||
3840 | $courseList = self::get_courses_list_by_session($user_id, $session_id); |
||||||
3841 | |||||||
3842 | $daysLeft = SessionManager::getDayLeftInSession($row, $user_id); |
||||||
3843 | |||||||
3844 | // User portal filters: |
||||||
3845 | if (false === $ignoreTimeLimit) { |
||||||
3846 | if ($is_time_over) { |
||||||
3847 | // History |
||||||
3848 | if ($row['duration']) { |
||||||
3849 | if ($daysLeft >= 0) { |
||||||
3850 | continue; |
||||||
3851 | } |
||||||
3852 | } else { |
||||||
3853 | if (empty($row['access_end_date'])) { |
||||||
3854 | continue; |
||||||
3855 | } else { |
||||||
3856 | if ($row['access_end_date'] > $now) { |
||||||
3857 | continue; |
||||||
3858 | } |
||||||
3859 | } |
||||||
3860 | } |
||||||
3861 | } else { |
||||||
3862 | // Current user portal |
||||||
3863 | $isGeneralCoach = SessionManager::user_is_general_coach($user_id, $row['id']); |
||||||
3864 | $isCoachOfCourse = in_array($user_id, $coachList); |
||||||
3865 | |||||||
3866 | if (api_is_platform_admin() || $isGeneralCoach || $isCoachOfCourse) { |
||||||
3867 | // Teachers can access the session depending in the access_coach date |
||||||
3868 | } else { |
||||||
3869 | if ($row['duration']) { |
||||||
3870 | if ($daysLeft <= 0) { |
||||||
3871 | continue; |
||||||
3872 | } |
||||||
3873 | } else { |
||||||
3874 | if (isset($row['access_end_date']) && |
||||||
3875 | !empty($row['access_end_date']) |
||||||
3876 | ) { |
||||||
3877 | if ($row['access_end_date'] <= $now) { |
||||||
3878 | continue; |
||||||
3879 | } |
||||||
3880 | } |
||||||
3881 | } |
||||||
3882 | } |
||||||
3883 | } |
||||||
3884 | } |
||||||
3885 | |||||||
3886 | $categories[$row['session_category_id']]['session_category'] = [ |
||||||
3887 | 'id' => $row['session_category_id'], |
||||||
3888 | 'name' => $row['session_category_name'], |
||||||
3889 | 'date_start' => $categoryStart, |
||||||
3890 | 'date_end' => $categoryEnd, |
||||||
3891 | ]; |
||||||
3892 | |||||||
3893 | $visibility = api_get_session_visibility( |
||||||
3894 | $session_id, |
||||||
3895 | null, |
||||||
3896 | $ignore_visibility_for_admins |
||||||
3897 | ); |
||||||
3898 | |||||||
3899 | if ($visibility != SESSION_VISIBLE) { |
||||||
3900 | // Course Coach session visibility. |
||||||
3901 | $blockedCourseCount = 0; |
||||||
3902 | $closedVisibilityList = [ |
||||||
3903 | COURSE_VISIBILITY_CLOSED, |
||||||
3904 | COURSE_VISIBILITY_HIDDEN, |
||||||
3905 | ]; |
||||||
3906 | |||||||
3907 | foreach ($courseList as $course) { |
||||||
3908 | // Checking session visibility |
||||||
3909 | $sessionCourseVisibility = api_get_session_visibility( |
||||||
3910 | $session_id, |
||||||
3911 | $course['real_id'], |
||||||
3912 | $ignore_visibility_for_admins |
||||||
3913 | ); |
||||||
3914 | |||||||
3915 | $courseIsVisible = !in_array($course['visibility'], $closedVisibilityList); |
||||||
3916 | if ($courseIsVisible === false || $sessionCourseVisibility == SESSION_INVISIBLE) { |
||||||
3917 | $blockedCourseCount++; |
||||||
3918 | } |
||||||
3919 | } |
||||||
3920 | |||||||
3921 | // If all courses are blocked then no show in the list. |
||||||
3922 | if ($blockedCourseCount === count($courseList)) { |
||||||
3923 | $visibility = SESSION_INVISIBLE; |
||||||
3924 | } else { |
||||||
3925 | $visibility = $sessionCourseVisibility; |
||||||
3926 | } |
||||||
3927 | } |
||||||
3928 | |||||||
3929 | switch ($visibility) { |
||||||
3930 | case SESSION_VISIBLE_READ_ONLY: |
||||||
3931 | case SESSION_VISIBLE: |
||||||
3932 | case SESSION_AVAILABLE: |
||||||
3933 | break; |
||||||
3934 | case SESSION_INVISIBLE: |
||||||
3935 | if ($ignore_visibility_for_admins === false) { |
||||||
3936 | continue 2; |
||||||
3937 | } |
||||||
3938 | } |
||||||
3939 | |||||||
3940 | $collapsed = ''; |
||||||
3941 | $collapsedAction = ''; |
||||||
3942 | if ($collapsable) { |
||||||
3943 | $collapsableData = SessionManager::getCollapsableData( |
||||||
3944 | $user_id, |
||||||
3945 | $session_id, |
||||||
3946 | $extraField, |
||||||
3947 | $collapsableLink |
||||||
3948 | ); |
||||||
3949 | $collapsed = $collapsableData['collapsed']; |
||||||
3950 | $collapsedAction = $collapsableData['collapsable_link']; |
||||||
3951 | } |
||||||
3952 | |||||||
3953 | $categories[$row['session_category_id']]['sessions'][] = [ |
||||||
3954 | 'session_name' => $row['name'], |
||||||
3955 | 'session_id' => $row['id'], |
||||||
3956 | 'access_start_date' => $row['access_start_date'] ? $row['access_start_date']->format('Y-m-d H:i:s') : null, |
||||||
3957 | 'access_end_date' => $row['access_end_date'] ? $row['access_end_date']->format('Y-m-d H:i:s') : null, |
||||||
3958 | 'coach_access_start_date' => $row['coach_access_start_date'] ? $row['coach_access_start_date']->format('Y-m-d H:i:s') : null, |
||||||
3959 | 'coach_access_end_date' => $row['coach_access_end_date'] ? $row['coach_access_end_date']->format('Y-m-d H:i:s') : null, |
||||||
3960 | 'courses' => $courseList, |
||||||
3961 | 'collapsed' => $collapsed, |
||||||
3962 | 'collapsable_link' => $collapsedAction, |
||||||
3963 | 'duration' => $row['duration'], |
||||||
3964 | ]; |
||||||
3965 | } |
||||||
3966 | |||||||
3967 | return $categories; |
||||||
3968 | } |
||||||
3969 | |||||||
3970 | /** |
||||||
3971 | * Gives a list of [session_id-course_code] => [status] for the current user. |
||||||
3972 | * |
||||||
3973 | * @param int $user_id |
||||||
3974 | * @param int $sessionLimit |
||||||
3975 | * |
||||||
3976 | * @return array list of statuses (session_id-course_code => status) |
||||||
3977 | */ |
||||||
3978 | public static function get_personal_session_course_list($user_id, $sessionLimit = null) |
||||||
3979 | { |
||||||
3980 | // Database Table Definitions |
||||||
3981 | $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE); |
||||||
3982 | $tbl_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
3983 | $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION); |
||||||
3984 | $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER); |
||||||
3985 | $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
||||||
3986 | $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
||||||
3987 | |||||||
3988 | $user_id = (int) $user_id; |
||||||
3989 | |||||||
3990 | if (empty($user_id)) { |
||||||
3991 | return []; |
||||||
3992 | } |
||||||
3993 | |||||||
3994 | // We filter the courses from the URL |
||||||
3995 | $join_access_url = $where_access_url = ''; |
||||||
3996 | if (api_get_multiple_access_url()) { |
||||||
3997 | $access_url_id = api_get_current_access_url_id(); |
||||||
3998 | if ($access_url_id != -1) { |
||||||
3999 | $tbl_url_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
||||||
4000 | $join_access_url = "LEFT JOIN $tbl_url_course url_rel_course ON url_rel_course.c_id = course.id"; |
||||||
4001 | $where_access_url = " AND access_url_id = $access_url_id "; |
||||||
4002 | } |
||||||
4003 | } |
||||||
4004 | |||||||
4005 | // Courses in which we subscribed out of any session |
||||||
4006 | $tbl_user_course_category = Database::get_main_table(TABLE_USER_COURSE_CATEGORY); |
||||||
4007 | |||||||
4008 | $sql = "SELECT |
||||||
4009 | course.code, |
||||||
4010 | course_rel_user.status course_rel_status, |
||||||
4011 | course_rel_user.sort sort, |
||||||
4012 | course_rel_user.user_course_cat user_course_cat |
||||||
4013 | FROM $tbl_course_user course_rel_user |
||||||
4014 | LEFT JOIN $tbl_course course |
||||||
4015 | ON course.id = course_rel_user.c_id |
||||||
4016 | LEFT JOIN $tbl_user_course_category user_course_category |
||||||
4017 | ON course_rel_user.user_course_cat = user_course_category.id |
||||||
4018 | $join_access_url |
||||||
4019 | WHERE |
||||||
4020 | course_rel_user.user_id = '".$user_id."' AND |
||||||
4021 | course_rel_user.relation_type <> ".COURSE_RELATION_TYPE_RRHH." |
||||||
4022 | $where_access_url |
||||||
4023 | ORDER BY user_course_category.sort, course_rel_user.sort, course.title ASC"; |
||||||
4024 | |||||||
4025 | $course_list_sql_result = Database::query($sql); |
||||||
4026 | |||||||
4027 | $personal_course_list = []; |
||||||
4028 | if (Database::num_rows($course_list_sql_result) > 0) { |
||||||
4029 | while ($result_row = Database::fetch_array($course_list_sql_result, 'ASSOC')) { |
||||||
4030 | $course_info = api_get_course_info($result_row['code']); |
||||||
4031 | $result_row['course_info'] = $course_info; |
||||||
4032 | $personal_course_list[] = $result_row; |
||||||
4033 | } |
||||||
4034 | } |
||||||
4035 | |||||||
4036 | $coachCourseConditions = ''; |
||||||
4037 | // Getting sessions that are related to a coach in the session_rel_course_rel_user table |
||||||
4038 | if (api_is_allowed_to_create_course()) { |
||||||
4039 | $sessionListFromCourseCoach = []; |
||||||
4040 | $sql = " SELECT DISTINCT session_id |
||||||
4041 | FROM $tbl_session_course_user |
||||||
4042 | WHERE user_id = $user_id AND status = 2 "; |
||||||
4043 | |||||||
4044 | $result = Database::query($sql); |
||||||
4045 | if (Database::num_rows($result)) { |
||||||
4046 | $result = Database::store_result($result); |
||||||
4047 | foreach ($result as $session) { |
||||||
4048 | $sessionListFromCourseCoach[] = $session['session_id']; |
||||||
4049 | } |
||||||
4050 | } |
||||||
4051 | if (!empty($sessionListFromCourseCoach)) { |
||||||
4052 | $condition = implode("','", $sessionListFromCourseCoach); |
||||||
4053 | $coachCourseConditions = " OR ( s.id IN ('$condition'))"; |
||||||
4054 | } |
||||||
4055 | } |
||||||
4056 | |||||||
4057 | // Get the list of sessions where the user is subscribed |
||||||
4058 | // This is divided into two different queries |
||||||
4059 | $sessions = []; |
||||||
4060 | $sessionLimitRestriction = ''; |
||||||
4061 | if (!empty($sessionLimit)) { |
||||||
4062 | $sessionLimit = (int) $sessionLimit; |
||||||
4063 | $sessionLimitRestriction = "LIMIT $sessionLimit"; |
||||||
4064 | } |
||||||
4065 | |||||||
4066 | $sql = "SELECT DISTINCT s.id, name, access_start_date, access_end_date |
||||||
4067 | FROM $tbl_session_user su INNER JOIN $tbl_session s |
||||||
4068 | ON (s.id = su.session_id) |
||||||
4069 | WHERE ( |
||||||
4070 | su.user_id = $user_id AND |
||||||
4071 | su.relation_type <> ".SESSION_RELATION_TYPE_RRHH." |
||||||
4072 | ) |
||||||
4073 | $coachCourseConditions |
||||||
4074 | ORDER BY access_start_date, access_end_date, name |
||||||
4075 | $sessionLimitRestriction |
||||||
4076 | "; |
||||||
4077 | |||||||
4078 | $result = Database::query($sql); |
||||||
4079 | if (Database::num_rows($result) > 0) { |
||||||
4080 | while ($row = Database::fetch_assoc($result)) { |
||||||
4081 | $sessions[$row['id']] = $row; |
||||||
4082 | } |
||||||
4083 | } |
||||||
4084 | |||||||
4085 | $sql = "SELECT DISTINCT |
||||||
4086 | id, name, access_start_date, access_end_date |
||||||
4087 | FROM $tbl_session s |
||||||
4088 | WHERE ( |
||||||
4089 | id_coach = $user_id |
||||||
4090 | ) |
||||||
4091 | $coachCourseConditions |
||||||
4092 | ORDER BY access_start_date, access_end_date, name"; |
||||||
4093 | |||||||
4094 | $result = Database::query($sql); |
||||||
4095 | if (Database::num_rows($result) > 0) { |
||||||
4096 | while ($row = Database::fetch_assoc($result)) { |
||||||
4097 | if (empty($sessions[$row['id']])) { |
||||||
4098 | $sessions[$row['id']] = $row; |
||||||
4099 | } |
||||||
4100 | } |
||||||
4101 | } |
||||||
4102 | |||||||
4103 | if (api_is_allowed_to_create_course()) { |
||||||
4104 | foreach ($sessions as $enreg) { |
||||||
4105 | $session_id = $enreg['id']; |
||||||
4106 | $session_visibility = api_get_session_visibility($session_id); |
||||||
4107 | |||||||
4108 | if ($session_visibility == SESSION_INVISIBLE) { |
||||||
4109 | continue; |
||||||
4110 | } |
||||||
4111 | |||||||
4112 | // This query is horribly slow when more than a few thousand |
||||||
4113 | // users and just a few sessions to which they are subscribed |
||||||
4114 | $sql = "SELECT DISTINCT |
||||||
4115 | course.code code, |
||||||
4116 | course.title i, |
||||||
4117 | ".(api_is_western_name_order() ? "CONCAT(user.firstname,' ',user.lastname)" : "CONCAT(user.lastname,' ',user.firstname)")." t, |
||||||
4118 | email, course.course_language l, |
||||||
4119 | 1 sort, |
||||||
4120 | category_code user_course_cat, |
||||||
4121 | access_start_date, |
||||||
4122 | access_end_date, |
||||||
4123 | session.id as session_id, |
||||||
4124 | session.name as session_name |
||||||
4125 | FROM $tbl_session_course_user as session_course_user |
||||||
4126 | INNER JOIN $tbl_course AS course |
||||||
4127 | ON course.id = session_course_user.c_id |
||||||
4128 | INNER JOIN $tbl_session as session |
||||||
4129 | ON session.id = session_course_user.session_id |
||||||
4130 | LEFT JOIN $tbl_user as user |
||||||
4131 | ON user.id = session_course_user.user_id OR session.id_coach = user.id |
||||||
4132 | WHERE |
||||||
4133 | session_course_user.session_id = $session_id AND ( |
||||||
4134 | (session_course_user.user_id = $user_id AND session_course_user.status = 2) |
||||||
4135 | OR session.id_coach = $user_id |
||||||
4136 | ) |
||||||
4137 | ORDER BY i"; |
||||||
4138 | $course_list_sql_result = Database::query($sql); |
||||||
4139 | while ($result_row = Database::fetch_array($course_list_sql_result, 'ASSOC')) { |
||||||
4140 | $result_row['course_info'] = api_get_course_info($result_row['code']); |
||||||
4141 | $key = $result_row['session_id'].' - '.$result_row['code']; |
||||||
4142 | $personal_course_list[$key] = $result_row; |
||||||
4143 | } |
||||||
4144 | } |
||||||
4145 | } |
||||||
4146 | |||||||
4147 | foreach ($sessions as $enreg) { |
||||||
4148 | $session_id = $enreg['id']; |
||||||
4149 | $session_visibility = api_get_session_visibility($session_id); |
||||||
4150 | if ($session_visibility == SESSION_INVISIBLE) { |
||||||
4151 | continue; |
||||||
4152 | } |
||||||
4153 | |||||||
4154 | /* This query is very similar to the above query, |
||||||
4155 | but it will check the session_rel_course_user table if there are courses registered to our user or not */ |
||||||
4156 | $sql = "SELECT DISTINCT |
||||||
4157 | course.code code, |
||||||
4158 | course.title i, CONCAT(user.lastname,' ',user.firstname) t, |
||||||
4159 | email, |
||||||
4160 | course.course_language l, |
||||||
4161 | 1 sort, |
||||||
4162 | category_code user_course_cat, |
||||||
4163 | access_start_date, |
||||||
4164 | access_end_date, |
||||||
4165 | session.id as session_id, |
||||||
4166 | session.name as session_name, |
||||||
4167 | IF((session_course_user.user_id = 3 AND session_course_user.status=2),'2', '5') |
||||||
4168 | FROM $tbl_session_course_user as session_course_user |
||||||
4169 | INNER JOIN $tbl_course AS course |
||||||
4170 | ON course.id = session_course_user.c_id AND session_course_user.session_id = $session_id |
||||||
4171 | INNER JOIN $tbl_session as session |
||||||
4172 | ON session_course_user.session_id = session.id |
||||||
4173 | LEFT JOIN $tbl_user as user ON user.id = session_course_user.user_id |
||||||
4174 | WHERE session_course_user.user_id = $user_id |
||||||
4175 | ORDER BY i"; |
||||||
4176 | |||||||
4177 | $course_list_sql_result = Database::query($sql); |
||||||
4178 | while ($result_row = Database::fetch_array($course_list_sql_result, 'ASSOC')) { |
||||||
4179 | $result_row['course_info'] = api_get_course_info($result_row['code']); |
||||||
4180 | $key = $result_row['session_id'].' - '.$result_row['code']; |
||||||
4181 | if (!isset($personal_course_list[$key])) { |
||||||
4182 | $personal_course_list[$key] = $result_row; |
||||||
4183 | } |
||||||
4184 | } |
||||||
4185 | } |
||||||
4186 | |||||||
4187 | return $personal_course_list; |
||||||
4188 | } |
||||||
4189 | |||||||
4190 | /** |
||||||
4191 | * Gives a list of courses for the given user in the given session. |
||||||
4192 | * |
||||||
4193 | * @param int $user_id |
||||||
4194 | * @param int $session_id |
||||||
4195 | * |
||||||
4196 | * @return array list of statuses (session_id-course_code => status) |
||||||
4197 | */ |
||||||
4198 | public static function get_courses_list_by_session($user_id, $session_id) |
||||||
4199 | { |
||||||
4200 | // Database Table Definitions |
||||||
4201 | $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION); |
||||||
4202 | $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE); |
||||||
4203 | $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
||||||
4204 | $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE); |
||||||
4205 | |||||||
4206 | $user_id = (int) $user_id; |
||||||
4207 | $session_id = (int) $session_id; |
||||||
4208 | // We filter the courses from the URL |
||||||
4209 | $join_access_url = $where_access_url = ''; |
||||||
4210 | if (api_get_multiple_access_url()) { |
||||||
4211 | $urlId = api_get_current_access_url_id(); |
||||||
4212 | if (-1 != $urlId) { |
||||||
4213 | $tbl_url_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION); |
||||||
4214 | $join_access_url = " , $tbl_url_session url_rel_session "; |
||||||
4215 | $where_access_url = " AND access_url_id = $urlId AND url_rel_session.session_id = $session_id "; |
||||||
4216 | } |
||||||
4217 | } |
||||||
4218 | |||||||
4219 | $exlearnerCondition = ""; |
||||||
4220 | if (false !== api_get_configuration_value('user_edition_extra_field_to_check')) { |
||||||
4221 | $exlearnerCondition = " AND scu.status NOT IN(".COURSE_EXLEARNER.")"; |
||||||
4222 | } |
||||||
4223 | |||||||
4224 | /* This query is very similar to the query below, but it will check the |
||||||
4225 | session_rel_course_user table if there are courses registered |
||||||
4226 | to our user or not */ |
||||||
4227 | $sql = "SELECT DISTINCT |
||||||
4228 | c.title, |
||||||
4229 | c.visibility, |
||||||
4230 | c.id as real_id, |
||||||
4231 | c.code as course_code, |
||||||
4232 | c.course_language, |
||||||
4233 | sc.position, |
||||||
4234 | c.unsubscribe |
||||||
4235 | FROM $tbl_session_course_user as scu |
||||||
4236 | INNER JOIN $tbl_session_course sc |
||||||
4237 | ON (scu.session_id = sc.session_id AND scu.c_id = sc.c_id) |
||||||
4238 | INNER JOIN $tableCourse as c |
||||||
4239 | ON (scu.c_id = c.id) |
||||||
4240 | $join_access_url |
||||||
4241 | WHERE |
||||||
4242 | scu.user_id = $user_id AND |
||||||
4243 | scu.session_id = $session_id |
||||||
4244 | $where_access_url |
||||||
4245 | $exlearnerCondition |
||||||
4246 | ORDER BY sc.position ASC"; |
||||||
4247 | |||||||
4248 | $myCourseList = []; |
||||||
4249 | $courses = []; |
||||||
4250 | $result = Database::query($sql); |
||||||
4251 | if (Database::num_rows($result) > 0) { |
||||||
4252 | while ($result_row = Database::fetch_array($result, 'ASSOC')) { |
||||||
4253 | $result_row['status'] = 5; |
||||||
4254 | if (!in_array($result_row['real_id'], $courses)) { |
||||||
4255 | $position = $result_row['position']; |
||||||
4256 | if (!isset($myCourseList[$position])) { |
||||||
4257 | $myCourseList[$position] = $result_row; |
||||||
4258 | } else { |
||||||
4259 | $myCourseList[] = $result_row; |
||||||
4260 | } |
||||||
4261 | $courses[] = $result_row['real_id']; |
||||||
4262 | } |
||||||
4263 | } |
||||||
4264 | } |
||||||
4265 | |||||||
4266 | if (api_is_allowed_to_create_course()) { |
||||||
4267 | $sql = "SELECT DISTINCT |
||||||
4268 | c.title, |
||||||
4269 | c.visibility, |
||||||
4270 | c.id as real_id, |
||||||
4271 | c.code as course_code, |
||||||
4272 | c.course_language, |
||||||
4273 | sc.position, |
||||||
4274 | c.unsubscribe |
||||||
4275 | FROM $tbl_session_course_user as scu |
||||||
4276 | INNER JOIN $tbl_session as s |
||||||
4277 | ON (scu.session_id = s.id) |
||||||
4278 | INNER JOIN $tbl_session_course sc |
||||||
4279 | ON (scu.session_id = sc.session_id AND scu.c_id = sc.c_id) |
||||||
4280 | INNER JOIN $tableCourse as c |
||||||
4281 | ON (scu.c_id = c.id) |
||||||
4282 | $join_access_url |
||||||
4283 | WHERE |
||||||
4284 | s.id = $session_id AND |
||||||
4285 | ( |
||||||
4286 | (scu.user_id = $user_id AND scu.status = 2) OR |
||||||
4287 | s.id_coach = $user_id |
||||||
4288 | ) |
||||||
4289 | $where_access_url |
||||||
4290 | $exlearnerCondition |
||||||
4291 | ORDER BY sc.position ASC"; |
||||||
4292 | $result = Database::query($sql); |
||||||
4293 | |||||||
4294 | if (Database::num_rows($result) > 0) { |
||||||
4295 | while ($result_row = Database::fetch_array($result, 'ASSOC')) { |
||||||
4296 | $result_row['status'] = 2; |
||||||
4297 | if (!in_array($result_row['real_id'], $courses)) { |
||||||
4298 | $position = $result_row['position']; |
||||||
4299 | if (!isset($myCourseList[$position])) { |
||||||
4300 | $myCourseList[$position] = $result_row; |
||||||
4301 | } else { |
||||||
4302 | $myCourseList[] = $result_row; |
||||||
4303 | } |
||||||
4304 | $courses[] = $result_row['real_id']; |
||||||
4305 | } |
||||||
4306 | } |
||||||
4307 | } |
||||||
4308 | } |
||||||
4309 | |||||||
4310 | if (api_is_drh()) { |
||||||
4311 | $sessionList = SessionManager::get_sessions_followed_by_drh($user_id); |
||||||
4312 | $sessionList = array_keys($sessionList); |
||||||
4313 | if (in_array($session_id, $sessionList)) { |
||||||
4314 | $courseList = SessionManager::get_course_list_by_session_id($session_id); |
||||||
4315 | if (!empty($courseList)) { |
||||||
4316 | foreach ($courseList as $course) { |
||||||
4317 | if (!in_array($course['id'], $courses)) { |
||||||
4318 | $position = $course['position']; |
||||||
4319 | if (!isset($myCourseList[$position])) { |
||||||
4320 | $myCourseList[$position] = $course; |
||||||
4321 | } else { |
||||||
4322 | $myCourseList[] = $course; |
||||||
4323 | } |
||||||
4324 | } |
||||||
4325 | } |
||||||
4326 | } |
||||||
4327 | } |
||||||
4328 | } else { |
||||||
4329 | //check if user is general coach for this session |
||||||
4330 | $sessionInfo = api_get_session_info($session_id); |
||||||
4331 | if ($sessionInfo['id_coach'] == $user_id) { |
||||||
4332 | $courseList = SessionManager::get_course_list_by_session_id($session_id); |
||||||
4333 | if (!empty($courseList)) { |
||||||
4334 | foreach ($courseList as $course) { |
||||||
4335 | if (!in_array($course['id'], $courses)) { |
||||||
4336 | $position = $course['position']; |
||||||
4337 | if (!isset($myCourseList[$position])) { |
||||||
4338 | $myCourseList[$position] = $course; |
||||||
4339 | } else { |
||||||
4340 | $myCourseList[] = $course; |
||||||
4341 | } |
||||||
4342 | } |
||||||
4343 | } |
||||||
4344 | } |
||||||
4345 | } |
||||||
4346 | } |
||||||
4347 | |||||||
4348 | if (!empty($myCourseList)) { |
||||||
4349 | ksort($myCourseList); |
||||||
4350 | $checkPosition = array_filter(array_column($myCourseList, 'position')); |
||||||
4351 | if (empty($checkPosition)) { |
||||||
4352 | // The session course list doesn't have any position, |
||||||
4353 | // then order the course list by course code. |
||||||
4354 | $orderByCode = array_column($myCourseList, 'course_code'); |
||||||
4355 | sort($orderByCode, SORT_NATURAL); |
||||||
4356 | $newCourseList = []; |
||||||
4357 | foreach ($orderByCode as $code) { |
||||||
4358 | foreach ($myCourseList as $course) { |
||||||
4359 | if ($code === $course['course_code']) { |
||||||
4360 | $newCourseList[] = $course; |
||||||
4361 | break; |
||||||
4362 | } |
||||||
4363 | } |
||||||
4364 | } |
||||||
4365 | $myCourseList = $newCourseList; |
||||||
4366 | } |
||||||
4367 | } |
||||||
4368 | |||||||
4369 | return $myCourseList; |
||||||
4370 | } |
||||||
4371 | |||||||
4372 | /** |
||||||
4373 | * Get user id from a username. |
||||||
4374 | * |
||||||
4375 | * @param string $username |
||||||
4376 | * |
||||||
4377 | * @return int User ID (or false if not found) |
||||||
4378 | */ |
||||||
4379 | public static function get_user_id_from_username($username) |
||||||
4380 | { |
||||||
4381 | if (empty($username)) { |
||||||
4382 | return false; |
||||||
4383 | } |
||||||
4384 | $username = trim($username); |
||||||
4385 | $username = Database::escape_string($username); |
||||||
4386 | $t_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
4387 | $sql = "SELECT id FROM $t_user WHERE username = '$username'"; |
||||||
4388 | $res = Database::query($sql); |
||||||
4389 | |||||||
4390 | if ($res === false) { |
||||||
4391 | return false; |
||||||
4392 | } |
||||||
4393 | if (Database::num_rows($res) !== 1) { |
||||||
4394 | return false; |
||||||
4395 | } |
||||||
4396 | $row = Database::fetch_array($res); |
||||||
4397 | |||||||
4398 | return $row['id']; |
||||||
4399 | } |
||||||
4400 | |||||||
4401 | /** |
||||||
4402 | * Get the users files upload from his share_folder. |
||||||
4403 | * |
||||||
4404 | * @param string $user_id User ID |
||||||
4405 | * @param string $course course directory |
||||||
4406 | * @param string $resourceType resource type: images, all |
||||||
4407 | * |
||||||
4408 | * @return string |
||||||
4409 | */ |
||||||
4410 | public static function get_user_upload_files_by_course( |
||||||
4411 | $user_id, |
||||||
4412 | $course, |
||||||
4413 | $resourceType = 'all' |
||||||
4414 | ) { |
||||||
4415 | $return = ''; |
||||||
4416 | $user_id = (int) $user_id; |
||||||
4417 | |||||||
4418 | if (!empty($user_id) && !empty($course)) { |
||||||
4419 | $path = api_get_path(SYS_COURSE_PATH).$course.'/document/shared_folder/sf_user_'.$user_id.'/'; |
||||||
4420 | $web_path = api_get_path(WEB_COURSE_PATH).$course.'/document/shared_folder/sf_user_'.$user_id.'/'; |
||||||
4421 | $file_list = []; |
||||||
4422 | |||||||
4423 | if (is_dir($path)) { |
||||||
4424 | $handle = opendir($path); |
||||||
4425 | while ($file = readdir($handle)) { |
||||||
4426 | if ($file == '.' || $file == '..' || $file == '.htaccess' || is_dir($path.$file)) { |
||||||
4427 | continue; // skip current/parent directory and .htaccess |
||||||
4428 | } |
||||||
4429 | $file_list[] = $file; |
||||||
4430 | } |
||||||
4431 | if (count($file_list) > 0) { |
||||||
4432 | $return = "<h4>$course</h4>"; |
||||||
4433 | $return .= '<ul class="thumbnails">'; |
||||||
4434 | } |
||||||
4435 | $extensionList = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tif']; |
||||||
4436 | foreach ($file_list as $file) { |
||||||
4437 | if ($resourceType == 'all') { |
||||||
4438 | $return .= '<li> |
||||||
4439 | <a href="'.$web_path.urlencode($file).'" target="_blank">'.htmlentities($file).'</a></li>'; |
||||||
4440 | } elseif ($resourceType == 'images') { |
||||||
4441 | //get extension |
||||||
4442 | $ext = explode('.', $file); |
||||||
4443 | if (isset($ext[1]) && in_array($ext[1], $extensionList)) { |
||||||
4444 | $return .= '<li class="span2"> |
||||||
4445 | <a class="thumbnail" href="'.$web_path.urlencode($file).'" target="_blank"> |
||||||
4446 | <img src="'.$web_path.urlencode($file).'" > |
||||||
4447 | </a> |
||||||
4448 | </li>'; |
||||||
4449 | } |
||||||
4450 | } |
||||||
4451 | } |
||||||
4452 | if (count($file_list) > 0) { |
||||||
4453 | $return .= '</ul>'; |
||||||
4454 | } |
||||||
4455 | } |
||||||
4456 | } |
||||||
4457 | |||||||
4458 | return $return; |
||||||
4459 | } |
||||||
4460 | |||||||
4461 | /** |
||||||
4462 | * Gets the API key (or keys) and return them into an array. |
||||||
4463 | * |
||||||
4464 | * @param int Optional user id (defaults to the result of api_get_user_id()) |
||||||
4465 | * @param string $api_service |
||||||
4466 | * |
||||||
4467 | * @return mixed Non-indexed array containing the list of API keys for this user, or FALSE on error |
||||||
4468 | */ |
||||||
4469 | public static function get_api_keys($user_id = null, $api_service = 'dokeos') |
||||||
4470 | { |
||||||
4471 | if ($user_id != strval(intval($user_id))) { |
||||||
4472 | return false; |
||||||
4473 | } |
||||||
4474 | if (empty($user_id)) { |
||||||
4475 | $user_id = api_get_user_id(); |
||||||
4476 | } |
||||||
4477 | if ($user_id === false) { |
||||||
4478 | return false; |
||||||
4479 | } |
||||||
4480 | $service_name = Database::escape_string($api_service); |
||||||
4481 | if (is_string($service_name) === false) { |
||||||
4482 | return false; |
||||||
4483 | } |
||||||
4484 | $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY); |
||||||
4485 | $sql = "SELECT * FROM $t_api WHERE user_id = $user_id AND api_service='$api_service';"; |
||||||
4486 | $res = Database::query($sql); |
||||||
4487 | if ($res === false) { |
||||||
4488 | return false; |
||||||
4489 | } //error during query |
||||||
4490 | $num = Database::num_rows($res); |
||||||
4491 | if ($num == 0) { |
||||||
4492 | return false; |
||||||
4493 | } |
||||||
4494 | $list = []; |
||||||
4495 | while ($row = Database::fetch_array($res)) { |
||||||
4496 | $list[$row['id']] = $row['api_key']; |
||||||
4497 | } |
||||||
4498 | |||||||
4499 | return $list; |
||||||
4500 | } |
||||||
4501 | |||||||
4502 | /** |
||||||
4503 | * Adds a new API key to the users' account. |
||||||
4504 | * |
||||||
4505 | * @param int Optional user ID (defaults to the results of api_get_user_id()) |
||||||
4506 | * @param string $api_service |
||||||
4507 | * |
||||||
4508 | * @return bool True on success, false on failure |
||||||
4509 | */ |
||||||
4510 | public static function add_api_key($user_id = null, $api_service = 'dokeos') |
||||||
4511 | { |
||||||
4512 | if ($user_id != strval(intval($user_id))) { |
||||||
4513 | return false; |
||||||
4514 | } |
||||||
4515 | if (empty($user_id)) { |
||||||
4516 | $user_id = api_get_user_id(); |
||||||
4517 | } |
||||||
4518 | if ($user_id === false) { |
||||||
4519 | return false; |
||||||
4520 | } |
||||||
4521 | $service_name = Database::escape_string($api_service); |
||||||
4522 | if (is_string($service_name) === false) { |
||||||
4523 | return false; |
||||||
4524 | } |
||||||
4525 | $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY); |
||||||
4526 | $md5 = md5((time() + ($user_id * 5)) - rand(10000, 10000)); //generate some kind of random key |
||||||
4527 | $sql = "INSERT INTO $t_api (user_id, api_key,api_service) VALUES ($user_id,'$md5','$service_name')"; |
||||||
4528 | $res = Database::query($sql); |
||||||
4529 | if ($res === false) { |
||||||
4530 | return false; |
||||||
4531 | } //error during query |
||||||
4532 | $num = Database::insert_id(); |
||||||
4533 | |||||||
4534 | return $num == 0 ? false : $num; |
||||||
0 ignored issues
–
show
|
|||||||
4535 | } |
||||||
4536 | |||||||
4537 | /** |
||||||
4538 | * Deletes an API key from the user's account. |
||||||
4539 | * |
||||||
4540 | * @param int API key's internal ID |
||||||
4541 | * |
||||||
4542 | * @return bool True on success, false on failure |
||||||
4543 | */ |
||||||
4544 | public static function delete_api_key($key_id) |
||||||
4545 | { |
||||||
4546 | if ($key_id != strval(intval($key_id))) { |
||||||
4547 | return false; |
||||||
4548 | } |
||||||
4549 | if ($key_id === false) { |
||||||
4550 | return false; |
||||||
4551 | } |
||||||
4552 | $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY); |
||||||
4553 | $sql = "SELECT * FROM $t_api WHERE id = ".$key_id; |
||||||
4554 | $res = Database::query($sql); |
||||||
4555 | if ($res === false) { |
||||||
4556 | return false; |
||||||
4557 | } //error during query |
||||||
4558 | $num = Database::num_rows($res); |
||||||
4559 | if ($num !== 1) { |
||||||
4560 | return false; |
||||||
4561 | } |
||||||
4562 | $sql = "DELETE FROM $t_api WHERE id = ".$key_id; |
||||||
4563 | $res = Database::query($sql); |
||||||
4564 | if ($res === false) { |
||||||
4565 | return false; |
||||||
4566 | } //error during query |
||||||
4567 | |||||||
4568 | return true; |
||||||
4569 | } |
||||||
4570 | |||||||
4571 | /** |
||||||
4572 | * Regenerate an API key from the user's account. |
||||||
4573 | * |
||||||
4574 | * @param int user ID (defaults to the results of api_get_user_id()) |
||||||
4575 | * @param string API key's internal ID |
||||||
4576 | * |
||||||
4577 | * @return int num |
||||||
4578 | */ |
||||||
4579 | public static function update_api_key($user_id, $api_service) |
||||||
4580 | { |
||||||
4581 | if ($user_id != strval(intval($user_id))) { |
||||||
4582 | return false; |
||||||
4583 | } |
||||||
4584 | if ($user_id === false) { |
||||||
4585 | return false; |
||||||
4586 | } |
||||||
4587 | $service_name = Database::escape_string($api_service); |
||||||
4588 | if (is_string($service_name) === false) { |
||||||
4589 | return false; |
||||||
4590 | } |
||||||
4591 | $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY); |
||||||
4592 | $sql = "SELECT id FROM $t_api |
||||||
4593 | WHERE user_id=".$user_id." AND api_service='".$api_service."'"; |
||||||
4594 | $res = Database::query($sql); |
||||||
4595 | $num = Database::num_rows($res); |
||||||
4596 | if ($num == 1) { |
||||||
4597 | $id_key = Database::fetch_array($res, 'ASSOC'); |
||||||
4598 | self::delete_api_key($id_key['id']); |
||||||
4599 | $num = self::add_api_key($user_id, $api_service); |
||||||
4600 | } elseif ($num == 0) { |
||||||
4601 | $num = self::add_api_key($user_id, $api_service); |
||||||
4602 | } |
||||||
4603 | |||||||
4604 | return $num; |
||||||
0 ignored issues
–
show
|
|||||||
4605 | } |
||||||
4606 | |||||||
4607 | /** |
||||||
4608 | * @param int user ID (defaults to the results of api_get_user_id()) |
||||||
4609 | * @param string API key's internal ID |
||||||
4610 | * |
||||||
4611 | * @return int row ID, or return false if not found |
||||||
4612 | */ |
||||||
4613 | public static function get_api_key_id($user_id, $api_service) |
||||||
4614 | { |
||||||
4615 | if ($user_id != strval(intval($user_id))) { |
||||||
4616 | return false; |
||||||
4617 | } |
||||||
4618 | if ($user_id === false) { |
||||||
4619 | return false; |
||||||
4620 | } |
||||||
4621 | if (empty($api_service)) { |
||||||
4622 | return false; |
||||||
4623 | } |
||||||
4624 | $t_api = Database::get_main_table(TABLE_MAIN_USER_API_KEY); |
||||||
4625 | $api_service = Database::escape_string($api_service); |
||||||
4626 | $sql = "SELECT id FROM $t_api |
||||||
4627 | WHERE user_id=".$user_id." AND api_service='".$api_service."'"; |
||||||
4628 | $res = Database::query($sql); |
||||||
4629 | if (Database::num_rows($res) < 1) { |
||||||
4630 | return false; |
||||||
4631 | } |
||||||
4632 | $row = Database::fetch_array($res, 'ASSOC'); |
||||||
4633 | |||||||
4634 | return $row['id']; |
||||||
4635 | } |
||||||
4636 | |||||||
4637 | /** |
||||||
4638 | * Checks if a user_id is platform admin. |
||||||
4639 | * |
||||||
4640 | * @param int user ID |
||||||
4641 | * |
||||||
4642 | * @return bool True if is admin, false otherwise |
||||||
4643 | * |
||||||
4644 | * @see main_api.lib.php::api_is_platform_admin() for a context-based check |
||||||
4645 | */ |
||||||
4646 | public static function is_admin($user_id) |
||||||
4647 | { |
||||||
4648 | $user_id = (int) $user_id; |
||||||
4649 | if (empty($user_id)) { |
||||||
4650 | return false; |
||||||
4651 | } |
||||||
4652 | $admin_table = Database::get_main_table(TABLE_MAIN_ADMIN); |
||||||
4653 | $sql = "SELECT * FROM $admin_table WHERE user_id = $user_id"; |
||||||
4654 | $res = Database::query($sql); |
||||||
4655 | |||||||
4656 | return Database::num_rows($res) === 1; |
||||||
4657 | } |
||||||
4658 | |||||||
4659 | /** |
||||||
4660 | * Get the total count of users. |
||||||
4661 | * |
||||||
4662 | * @param int|null $status Status of users to be counted |
||||||
4663 | * @param int|null $access_url_id Access URL ID (optional) |
||||||
4664 | * |
||||||
4665 | * @return mixed Number of users or false on error |
||||||
4666 | */ |
||||||
4667 | public static function get_number_of_users( |
||||||
4668 | int $status = null, |
||||||
4669 | int $access_url_id = null, |
||||||
4670 | int $active = null, |
||||||
4671 | string $dateFrom = null, |
||||||
4672 | string $dateUntil = null |
||||||
4673 | ) { |
||||||
4674 | $tableUser = Database::get_main_table(TABLE_MAIN_USER); |
||||||
4675 | $tableAccessUrlRelUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
||||||
4676 | |||||||
4677 | if (empty($access_url_id)) { |
||||||
4678 | $access_url_id = api_get_current_access_url_id(); |
||||||
4679 | } |
||||||
4680 | |||||||
4681 | if (api_is_multiple_url_enabled()) { |
||||||
4682 | $sql = "SELECT count(u.id) |
||||||
4683 | FROM $tableUser u |
||||||
4684 | INNER JOIN $tableAccessUrlRelUser url_user |
||||||
4685 | ON (u.id = url_user.user_id) |
||||||
4686 | WHERE url_user.access_url_id = $access_url_id |
||||||
4687 | "; |
||||||
4688 | } else { |
||||||
4689 | $sql = "SELECT count(u.id) |
||||||
4690 | FROM $tableUser u |
||||||
4691 | WHERE 1 = 1 "; |
||||||
4692 | } |
||||||
4693 | |||||||
4694 | if (is_int($status) && $status > 0) { |
||||||
4695 | $status = (int) $status; |
||||||
4696 | $sql .= " AND u.status = $status "; |
||||||
4697 | } |
||||||
4698 | |||||||
4699 | if (isset($active)) { |
||||||
4700 | $active = (int) $active; |
||||||
4701 | $sql .= " AND u.active = $active "; |
||||||
4702 | } |
||||||
4703 | |||||||
4704 | if (!empty($dateFrom)) { |
||||||
4705 | $dateFrom = api_get_utc_datetime("$dateFrom 00:00:00"); |
||||||
4706 | $sql .= " AND u.registration_date >= '$dateFrom' "; |
||||||
4707 | } |
||||||
4708 | |||||||
4709 | if (!empty($dateUntil)) { |
||||||
4710 | $dateUntil = api_get_utc_datetime("$dateUntil 23:59:59"); |
||||||
4711 | $sql .= " AND u.registration_date <= '$dateUntil' "; |
||||||
4712 | } |
||||||
4713 | |||||||
4714 | $res = Database::query($sql); |
||||||
4715 | if (Database::num_rows($res) === 1) { |
||||||
4716 | return (int) Database::result($res, 0, 0); |
||||||
4717 | } |
||||||
4718 | |||||||
4719 | return false; |
||||||
4720 | } |
||||||
4721 | |||||||
4722 | /** |
||||||
4723 | * Gets the tags of a specific field_id |
||||||
4724 | * USER TAGS. |
||||||
4725 | * |
||||||
4726 | * Instructions to create a new user tag by Julio Montoya <[email protected]> |
||||||
4727 | * |
||||||
4728 | * 1. Create a new extra field in main/admin/user_fields.php with the "TAG" field type make it available and visible. |
||||||
4729 | * Called it "books" for example. |
||||||
4730 | * 2. Go to profile main/auth/profile.php There you will see a special input (facebook style) that will show suggestions of tags. |
||||||
4731 | * 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 |
||||||
4732 | * 4. Tags are independent this means that tags can't be shared between tags + book + hobbies. |
||||||
4733 | * 5. Test and enjoy. |
||||||
4734 | * |
||||||
4735 | * @param string $tag |
||||||
4736 | * @param int $field_id field_id |
||||||
4737 | * @param string $return_format how we are going to result value in array or in a string (json) |
||||||
4738 | * @param $limit |
||||||
4739 | * |
||||||
4740 | * @return mixed |
||||||
4741 | */ |
||||||
4742 | public static function get_tags($tag, $field_id, $return_format = 'json', $limit = 10) |
||||||
4743 | { |
||||||
4744 | // database table definition |
||||||
4745 | $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
||||||
4746 | $field_id = (int) $field_id; |
||||||
4747 | $limit = (int) $limit; |
||||||
4748 | $tag = trim(Database::escape_string($tag)); |
||||||
4749 | |||||||
4750 | // all the information of the field |
||||||
4751 | $sql = "SELECT DISTINCT id, tag from $table_user_tag |
||||||
4752 | WHERE field_id = $field_id AND tag LIKE '$tag%' |
||||||
4753 | ORDER BY tag |
||||||
4754 | LIMIT $limit"; |
||||||
4755 | $result = Database::query($sql); |
||||||
4756 | $return = []; |
||||||
4757 | if (Database::num_rows($result) > 0) { |
||||||
4758 | while ($row = Database::fetch_array($result, 'ASSOC')) { |
||||||
4759 | $return[] = ['id' => $row['tag'], 'text' => $row['tag']]; |
||||||
4760 | } |
||||||
4761 | } |
||||||
4762 | if ($return_format === 'json') { |
||||||
4763 | $return = json_encode($return); |
||||||
4764 | } |
||||||
4765 | |||||||
4766 | return $return; |
||||||
4767 | } |
||||||
4768 | |||||||
4769 | /** |
||||||
4770 | * @param int $field_id |
||||||
4771 | * @param int $limit |
||||||
4772 | * |
||||||
4773 | * @return array |
||||||
4774 | */ |
||||||
4775 | public static function get_top_tags($field_id, $limit = 100) |
||||||
4776 | { |
||||||
4777 | // database table definition |
||||||
4778 | $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
||||||
4779 | $table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG); |
||||||
4780 | $field_id = (int) $field_id; |
||||||
4781 | $limit = (int) $limit; |
||||||
4782 | // all the information of the field |
||||||
4783 | $sql = "SELECT count(*) count, tag FROM $table_user_tag_values uv |
||||||
4784 | INNER JOIN $table_user_tag ut |
||||||
4785 | ON (ut.id = uv.tag_id) |
||||||
4786 | WHERE field_id = $field_id |
||||||
4787 | GROUP BY tag_id |
||||||
4788 | ORDER BY count DESC |
||||||
4789 | LIMIT $limit"; |
||||||
4790 | $result = Database::query($sql); |
||||||
4791 | $return = []; |
||||||
4792 | if (Database::num_rows($result) > 0) { |
||||||
4793 | while ($row = Database::fetch_array($result, 'ASSOC')) { |
||||||
4794 | $return[] = $row; |
||||||
4795 | } |
||||||
4796 | } |
||||||
4797 | |||||||
4798 | return $return; |
||||||
4799 | } |
||||||
4800 | |||||||
4801 | /** |
||||||
4802 | * Get user's tags. |
||||||
4803 | * |
||||||
4804 | * @param int $user_id |
||||||
4805 | * @param int $field_id |
||||||
4806 | * |
||||||
4807 | * @return array |
||||||
4808 | */ |
||||||
4809 | public static function get_user_tags($user_id, $field_id) |
||||||
4810 | { |
||||||
4811 | // database table definition |
||||||
4812 | $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
||||||
4813 | $table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG); |
||||||
4814 | $field_id = (int) $field_id; |
||||||
4815 | $user_id = (int) $user_id; |
||||||
4816 | |||||||
4817 | // all the information of the field |
||||||
4818 | $sql = "SELECT ut.id, tag, count |
||||||
4819 | FROM $table_user_tag ut |
||||||
4820 | INNER JOIN $table_user_tag_values uv |
||||||
4821 | ON (uv.tag_id=ut.ID) |
||||||
4822 | WHERE field_id = $field_id AND user_id = $user_id |
||||||
4823 | ORDER BY tag"; |
||||||
4824 | $result = Database::query($sql); |
||||||
4825 | $return = []; |
||||||
4826 | if (Database::num_rows($result) > 0) { |
||||||
4827 | while ($row = Database::fetch_array($result, 'ASSOC')) { |
||||||
4828 | $return[$row['id']] = ['tag' => $row['tag'], 'count' => $row['count']]; |
||||||
4829 | } |
||||||
4830 | } |
||||||
4831 | |||||||
4832 | return $return; |
||||||
4833 | } |
||||||
4834 | |||||||
4835 | /** |
||||||
4836 | * Get user's tags. |
||||||
4837 | * |
||||||
4838 | * @param int $user_id |
||||||
4839 | * @param int $field_id |
||||||
4840 | * @param bool $show_links show links or not |
||||||
4841 | * |
||||||
4842 | * @return string |
||||||
4843 | */ |
||||||
4844 | public static function get_user_tags_to_string($user_id, $field_id, $show_links = true) |
||||||
4845 | { |
||||||
4846 | // database table definition |
||||||
4847 | $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
||||||
4848 | $table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG); |
||||||
4849 | $field_id = (int) $field_id; |
||||||
4850 | $user_id = (int) $user_id; |
||||||
4851 | |||||||
4852 | // all the information of the field |
||||||
4853 | $sql = "SELECT ut.id, tag,count FROM $table_user_tag ut |
||||||
4854 | INNER JOIN $table_user_tag_values uv |
||||||
4855 | ON (uv.tag_id = ut.id) |
||||||
4856 | WHERE field_id = $field_id AND user_id = $user_id |
||||||
4857 | ORDER BY tag"; |
||||||
4858 | |||||||
4859 | $result = Database::query($sql); |
||||||
4860 | $return = []; |
||||||
4861 | if (Database::num_rows($result) > 0) { |
||||||
4862 | while ($row = Database::fetch_array($result, 'ASSOC')) { |
||||||
4863 | $return[$row['id']] = ['tag' => $row['tag'], 'count' => $row['count']]; |
||||||
4864 | } |
||||||
4865 | } |
||||||
4866 | $user_tags = $return; |
||||||
4867 | $tag_tmp = []; |
||||||
4868 | foreach ($user_tags as $tag) { |
||||||
4869 | if ($show_links) { |
||||||
4870 | $tag_tmp[] = '<a href="'.api_get_path(WEB_PATH).'main/search/index.php?q='.$tag['tag'].'">'. |
||||||
4871 | $tag['tag']. |
||||||
4872 | '</a>'; |
||||||
4873 | } else { |
||||||
4874 | $tag_tmp[] = $tag['tag']; |
||||||
4875 | } |
||||||
4876 | } |
||||||
4877 | |||||||
4878 | if (is_array($user_tags) && count($user_tags) > 0) { |
||||||
4879 | return implode(', ', $tag_tmp); |
||||||
4880 | } else { |
||||||
4881 | return ''; |
||||||
4882 | } |
||||||
4883 | } |
||||||
4884 | |||||||
4885 | /** |
||||||
4886 | * Get the tag id. |
||||||
4887 | * |
||||||
4888 | * @param int $tag |
||||||
4889 | * @param int $field_id |
||||||
4890 | * |
||||||
4891 | * @return int returns 0 if fails otherwise the tag id |
||||||
4892 | */ |
||||||
4893 | public static function get_tag_id($tag, $field_id) |
||||||
4894 | { |
||||||
4895 | $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
||||||
4896 | $tag = Database::escape_string($tag); |
||||||
4897 | $field_id = (int) $field_id; |
||||||
4898 | //with COLLATE latin1_bin to select query in a case sensitive mode |
||||||
4899 | $sql = "SELECT id FROM $table_user_tag |
||||||
4900 | WHERE tag LIKE '$tag' AND field_id = $field_id"; |
||||||
4901 | $result = Database::query($sql); |
||||||
4902 | if (Database::num_rows($result) > 0) { |
||||||
4903 | $row = Database::fetch_array($result, 'ASSOC'); |
||||||
4904 | |||||||
4905 | return $row['id']; |
||||||
4906 | } else { |
||||||
4907 | return 0; |
||||||
4908 | } |
||||||
4909 | } |
||||||
4910 | |||||||
4911 | /** |
||||||
4912 | * Get the tag id. |
||||||
4913 | * |
||||||
4914 | * @param int $tag_id |
||||||
4915 | * @param int $field_id |
||||||
4916 | * |
||||||
4917 | * @return int 0 if fails otherwise the tag id |
||||||
4918 | */ |
||||||
4919 | public static function get_tag_id_from_id($tag_id, $field_id) |
||||||
4920 | { |
||||||
4921 | $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
||||||
4922 | $tag_id = (int) $tag_id; |
||||||
4923 | $field_id = (int) $field_id; |
||||||
4924 | $sql = "SELECT id FROM $table_user_tag |
||||||
4925 | WHERE id = '$tag_id' AND field_id = $field_id"; |
||||||
4926 | $result = Database::query($sql); |
||||||
4927 | if (Database::num_rows($result) > 0) { |
||||||
4928 | $row = Database::fetch_array($result, 'ASSOC'); |
||||||
4929 | |||||||
4930 | return $row['id']; |
||||||
4931 | } else { |
||||||
4932 | return false; |
||||||
4933 | } |
||||||
4934 | } |
||||||
4935 | |||||||
4936 | /** |
||||||
4937 | * Adds a user-tag value. |
||||||
4938 | * |
||||||
4939 | * @param mixed $tag |
||||||
4940 | * @param int $user_id |
||||||
4941 | * @param int $field_id field id of the tag |
||||||
4942 | * |
||||||
4943 | * @return bool True if the tag was inserted or updated. False otherwise. |
||||||
4944 | * The return value doesn't take into account *values* added to the tag. |
||||||
4945 | * Only the creation/update of the tag field itself. |
||||||
4946 | */ |
||||||
4947 | public static function add_tag($tag, $user_id, $field_id) |
||||||
4948 | { |
||||||
4949 | // database table definition |
||||||
4950 | $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
||||||
4951 | $table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG); |
||||||
4952 | $tag = trim(Database::escape_string($tag)); |
||||||
4953 | $user_id = (int) $user_id; |
||||||
4954 | $field_id = (int) $field_id; |
||||||
4955 | |||||||
4956 | $tag_id = self::get_tag_id($tag, $field_id); |
||||||
4957 | |||||||
4958 | /* IMPORTANT |
||||||
4959 | * @todo we don't create tags with numbers |
||||||
4960 | * |
||||||
4961 | */ |
||||||
4962 | if (is_numeric($tag)) { |
||||||
4963 | //the form is sending an id this means that the user select it from the list so it MUST exists |
||||||
4964 | /* $new_tag_id = self::get_tag_id_from_id($tag,$field_id); |
||||||
4965 | if ($new_tag_id !== false) { |
||||||
4966 | $sql = "UPDATE $table_user_tag SET count = count + 1 WHERE id = $new_tag_id"; |
||||||
4967 | $result = Database::query($sql); |
||||||
4968 | $last_insert_id = $new_tag_id; |
||||||
4969 | } else { |
||||||
4970 | $sql = "INSERT INTO $table_user_tag (tag, field_id,count) VALUES ('$tag','$field_id', count + 1)"; |
||||||
4971 | $result = Database::query($sql); |
||||||
4972 | $last_insert_id = Database::insert_id(); |
||||||
4973 | } */ |
||||||
4974 | } |
||||||
4975 | |||||||
4976 | //this is a new tag |
||||||
4977 | if ($tag_id == 0) { |
||||||
4978 | //the tag doesn't exist |
||||||
4979 | $sql = "INSERT INTO $table_user_tag (tag, field_id,count) VALUES ('$tag','$field_id', count + 1)"; |
||||||
4980 | Database::query($sql); |
||||||
4981 | $last_insert_id = Database::insert_id(); |
||||||
4982 | } else { |
||||||
4983 | //the tag exists we update it |
||||||
4984 | $sql = "UPDATE $table_user_tag SET count = count + 1 WHERE id = $tag_id"; |
||||||
4985 | Database::query($sql); |
||||||
4986 | $last_insert_id = $tag_id; |
||||||
4987 | } |
||||||
4988 | |||||||
4989 | if (!empty($last_insert_id) && ($last_insert_id != 0)) { |
||||||
4990 | //we insert the relationship user-tag |
||||||
4991 | $sql = "SELECT tag_id FROM $table_user_tag_values |
||||||
4992 | WHERE user_id = $user_id AND tag_id = $last_insert_id "; |
||||||
4993 | $result = Database::query($sql); |
||||||
4994 | //if the relationship does not exist we create it |
||||||
4995 | if (Database::num_rows($result) == 0) { |
||||||
4996 | $sql = "INSERT INTO $table_user_tag_values SET user_id = $user_id, tag_id = $last_insert_id"; |
||||||
4997 | Database::query($sql); |
||||||
4998 | } |
||||||
4999 | |||||||
5000 | return true; |
||||||
5001 | } |
||||||
5002 | |||||||
5003 | return false; |
||||||
5004 | } |
||||||
5005 | |||||||
5006 | /** |
||||||
5007 | * Deletes an user tag. |
||||||
5008 | * |
||||||
5009 | * @param int $user_id |
||||||
5010 | * @param int $field_id |
||||||
5011 | */ |
||||||
5012 | public static function delete_user_tags($user_id, $field_id) |
||||||
5013 | { |
||||||
5014 | // database table definition |
||||||
5015 | $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
||||||
5016 | $table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG); |
||||||
5017 | $user_id = (int) $user_id; |
||||||
5018 | |||||||
5019 | $tags = self::get_user_tags($user_id, $field_id); |
||||||
5020 | if (is_array($tags) && count($tags) > 0) { |
||||||
5021 | foreach ($tags as $key => $tag) { |
||||||
5022 | if ($tag['count'] > '0') { |
||||||
5023 | $sql = "UPDATE $table_user_tag SET count = count - 1 WHERE id = $key "; |
||||||
5024 | Database::query($sql); |
||||||
5025 | } |
||||||
5026 | $sql = "DELETE FROM $table_user_tag_values |
||||||
5027 | WHERE user_id = $user_id AND tag_id = $key"; |
||||||
5028 | Database::query($sql); |
||||||
5029 | } |
||||||
5030 | } |
||||||
5031 | } |
||||||
5032 | |||||||
5033 | /** |
||||||
5034 | * Process the tag list comes from the UserManager::update_extra_field_value() function. |
||||||
5035 | * |
||||||
5036 | * @param array $tags the tag list that will be added |
||||||
5037 | * @param int $user_id |
||||||
5038 | * @param int $field_id |
||||||
5039 | * |
||||||
5040 | * @return bool |
||||||
5041 | */ |
||||||
5042 | public static function process_tags($tags, $user_id, $field_id) |
||||||
5043 | { |
||||||
5044 | // We loop the tags and add it to the DB |
||||||
5045 | if (is_array($tags)) { |
||||||
5046 | foreach ($tags as $tag) { |
||||||
5047 | self::add_tag($tag, $user_id, $field_id); |
||||||
5048 | } |
||||||
5049 | } else { |
||||||
5050 | self::add_tag($tags, $user_id, $field_id); |
||||||
5051 | } |
||||||
5052 | |||||||
5053 | return true; |
||||||
5054 | } |
||||||
5055 | |||||||
5056 | /** |
||||||
5057 | * Returns a list of all administrators. |
||||||
5058 | * |
||||||
5059 | * @return array |
||||||
5060 | */ |
||||||
5061 | public static function get_all_administrators() |
||||||
5062 | { |
||||||
5063 | $table_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
5064 | $table_admin = Database::get_main_table(TABLE_MAIN_ADMIN); |
||||||
5065 | $tbl_url_rel_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
||||||
5066 | $access_url_id = api_get_current_access_url_id(); |
||||||
5067 | if (api_get_multiple_access_url()) { |
||||||
5068 | $sql = "SELECT admin.user_id, username, firstname, lastname, email, active |
||||||
5069 | FROM $tbl_url_rel_user as url |
||||||
5070 | INNER JOIN $table_admin as admin |
||||||
5071 | ON (admin.user_id=url.user_id) |
||||||
5072 | INNER JOIN $table_user u |
||||||
5073 | ON (u.id=admin.user_id) |
||||||
5074 | WHERE access_url_id ='".$access_url_id."'"; |
||||||
5075 | } else { |
||||||
5076 | $sql = "SELECT admin.user_id, username, firstname, lastname, email, active |
||||||
5077 | FROM $table_admin as admin |
||||||
5078 | INNER JOIN $table_user u |
||||||
5079 | ON (u.id=admin.user_id)"; |
||||||
5080 | } |
||||||
5081 | $result = Database::query($sql); |
||||||
5082 | $return = []; |
||||||
5083 | if (Database::num_rows($result) > 0) { |
||||||
5084 | while ($row = Database::fetch_array($result, 'ASSOC')) { |
||||||
5085 | $return[$row['user_id']] = $row; |
||||||
5086 | } |
||||||
5087 | } |
||||||
5088 | |||||||
5089 | return $return; |
||||||
5090 | } |
||||||
5091 | |||||||
5092 | /** |
||||||
5093 | * Search an user (tags, first name, last name and email ). |
||||||
5094 | * |
||||||
5095 | * @param string $tag |
||||||
5096 | * @param int $field_id field id of the tag |
||||||
5097 | * @param int $from where to start in the query |
||||||
5098 | * @param int $number_of_items |
||||||
5099 | * @param bool $getCount get count or not |
||||||
5100 | * |
||||||
5101 | * @return array |
||||||
5102 | */ |
||||||
5103 | public static function get_all_user_tags( |
||||||
5104 | $tag, |
||||||
5105 | $field_id = 0, |
||||||
5106 | $from = 0, |
||||||
5107 | $number_of_items = 10, |
||||||
5108 | $getCount = false |
||||||
5109 | ) { |
||||||
5110 | $user_table = Database::get_main_table(TABLE_MAIN_USER); |
||||||
5111 | $table_user_tag = Database::get_main_table(TABLE_MAIN_TAG); |
||||||
5112 | $table_user_tag_values = Database::get_main_table(TABLE_MAIN_USER_REL_TAG); |
||||||
5113 | $access_url_rel_user_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
||||||
5114 | |||||||
5115 | $field_id = intval($field_id); |
||||||
5116 | $from = intval($from); |
||||||
5117 | $number_of_items = intval($number_of_items); |
||||||
5118 | |||||||
5119 | $where_field = ""; |
||||||
5120 | $where_extra_fields = self::get_search_form_where_extra_fields(); |
||||||
5121 | if ($field_id != 0) { |
||||||
5122 | $where_field = " field_id = $field_id AND "; |
||||||
5123 | } |
||||||
5124 | |||||||
5125 | // all the information of the field |
||||||
5126 | if ($getCount) { |
||||||
5127 | $select = "SELECT count(DISTINCT u.id) count"; |
||||||
5128 | } else { |
||||||
5129 | $select = "SELECT DISTINCT u.id, u.username, firstname, lastname, email, picture_uri"; |
||||||
5130 | } |
||||||
5131 | |||||||
5132 | $sql = " $select |
||||||
5133 | FROM $user_table u |
||||||
5134 | INNER JOIN $access_url_rel_user_table url_rel_user |
||||||
5135 | ON (u.id = url_rel_user.user_id) |
||||||
5136 | LEFT JOIN $table_user_tag_values uv |
||||||
5137 | ON (u.id AND uv.user_id AND uv.user_id = url_rel_user.user_id) |
||||||
5138 | LEFT JOIN $table_user_tag ut ON (uv.tag_id = ut.id) |
||||||
5139 | WHERE |
||||||
5140 | ($where_field tag LIKE '".Database::escape_string($tag."%")."') OR |
||||||
5141 | ( |
||||||
5142 | u.firstname LIKE '".Database::escape_string("%".$tag."%")."' OR |
||||||
5143 | u.lastname LIKE '".Database::escape_string("%".$tag."%")."' OR |
||||||
5144 | u.username LIKE '".Database::escape_string("%".$tag."%")."' OR |
||||||
5145 | concat(u.firstname, ' ', u.lastname) LIKE '".Database::escape_string("%".$tag."%")."' OR |
||||||
5146 | concat(u.lastname, ' ', u.firstname) LIKE '".Database::escape_string("%".$tag."%")."' |
||||||
5147 | ) |
||||||
5148 | ".(!empty($where_extra_fields) ? $where_extra_fields : '')." |
||||||
5149 | AND url_rel_user.access_url_id=".api_get_current_access_url_id(); |
||||||
5150 | |||||||
5151 | $keyword_active = true; |
||||||
5152 | // only active users |
||||||
5153 | if ($keyword_active) { |
||||||
5154 | $sql .= " AND u.active='1'"; |
||||||
5155 | } |
||||||
5156 | // avoid anonymous |
||||||
5157 | $sql .= " AND u.status <> 6 "; |
||||||
5158 | $sql .= " ORDER BY username"; |
||||||
5159 | $sql .= " LIMIT $from , $number_of_items"; |
||||||
5160 | |||||||
5161 | $result = Database::query($sql); |
||||||
5162 | $return = []; |
||||||
5163 | |||||||
5164 | if (Database::num_rows($result) > 0) { |
||||||
5165 | if ($getCount) { |
||||||
5166 | $row = Database::fetch_array($result, 'ASSOC'); |
||||||
5167 | |||||||
5168 | return $row['count']; |
||||||
5169 | } |
||||||
5170 | while ($row = Database::fetch_array($result, 'ASSOC')) { |
||||||
5171 | $return[$row['id']] = $row; |
||||||
5172 | } |
||||||
5173 | } |
||||||
5174 | |||||||
5175 | return $return; |
||||||
5176 | } |
||||||
5177 | |||||||
5178 | /** |
||||||
5179 | * Get extra filterable user fields (only type select). |
||||||
5180 | * |
||||||
5181 | * @return array Array of extra fields as [int => ['name' => ..., 'variable' => ..., 'data' => ...]] ( |
||||||
5182 | * or empty array if no extra field) |
||||||
5183 | */ |
||||||
5184 | public static function getExtraFilterableFields() |
||||||
5185 | { |
||||||
5186 | $extraFieldList = self::get_extra_fields(); |
||||||
5187 | $fields = []; |
||||||
5188 | if (is_array($extraFieldList)) { |
||||||
5189 | foreach ($extraFieldList as $extraField) { |
||||||
5190 | // If is enabled to filter and is a "<select>" field type |
||||||
5191 | if ($extraField[8] == 1 && $extraField[2] == 4) { |
||||||
5192 | $fields[] = [ |
||||||
5193 | 'name' => $extraField[3], |
||||||
5194 | 'variable' => $extraField[1], |
||||||
5195 | 'data' => $extraField[9], |
||||||
5196 | ]; |
||||||
5197 | } |
||||||
5198 | } |
||||||
5199 | } |
||||||
5200 | |||||||
5201 | return $fields; |
||||||
5202 | } |
||||||
5203 | |||||||
5204 | /** |
||||||
5205 | * Get extra where clauses for finding users based on extra filterable user fields (type select). |
||||||
5206 | * |
||||||
5207 | * @return string With AND clauses based on user's ID which have the values to search in extra user fields |
||||||
5208 | * (or empty if no extra field exists) |
||||||
5209 | */ |
||||||
5210 | public static function get_search_form_where_extra_fields() |
||||||
5211 | { |
||||||
5212 | $useExtraFields = false; |
||||||
5213 | $extraFields = self::getExtraFilterableFields(); |
||||||
5214 | $extraFieldResult = []; |
||||||
5215 | if (is_array($extraFields) && count($extraFields) > 0) { |
||||||
5216 | foreach ($extraFields as $extraField) { |
||||||
5217 | $varName = 'field_'.$extraField['variable']; |
||||||
5218 | if (self::is_extra_field_available($extraField['variable'])) { |
||||||
5219 | if (isset($_GET[$varName]) && $_GET[$varName] != '0') { |
||||||
5220 | $useExtraFields = true; |
||||||
5221 | $extraFieldResult[] = self::get_extra_user_data_by_value( |
||||||
5222 | $extraField['variable'], |
||||||
5223 | $_GET[$varName] |
||||||
5224 | ); |
||||||
5225 | } |
||||||
5226 | } |
||||||
5227 | } |
||||||
5228 | } |
||||||
5229 | |||||||
5230 | if ($useExtraFields) { |
||||||
5231 | $finalResult = []; |
||||||
5232 | if (count($extraFieldResult) > 1) { |
||||||
5233 | for ($i = 0; $i < count($extraFieldResult) - 1; $i++) { |
||||||
5234 | if (is_array($extraFieldResult[$i]) && is_array($extraFieldResult[$i + 1])) { |
||||||
5235 | $finalResult = array_intersect($extraFieldResult[$i], $extraFieldResult[$i + 1]); |
||||||
5236 | } |
||||||
5237 | } |
||||||
5238 | } else { |
||||||
5239 | $finalResult = $extraFieldResult[0]; |
||||||
5240 | } |
||||||
5241 | |||||||
5242 | if (is_array($finalResult) && count($finalResult) > 0) { |
||||||
5243 | $whereFilter = " AND u.id IN ('".implode("','", $finalResult)."') "; |
||||||
5244 | } else { |
||||||
5245 | //no results |
||||||
5246 | $whereFilter = " AND u.id = -1 "; |
||||||
5247 | } |
||||||
5248 | |||||||
5249 | return $whereFilter; |
||||||
5250 | } |
||||||
5251 | |||||||
5252 | return ''; |
||||||
5253 | } |
||||||
5254 | |||||||
5255 | /** |
||||||
5256 | * Show the search form. |
||||||
5257 | * |
||||||
5258 | * @param string $query the value of the search box |
||||||
5259 | * |
||||||
5260 | * @throws Exception |
||||||
5261 | * |
||||||
5262 | * @return string HTML form |
||||||
5263 | */ |
||||||
5264 | public static function get_search_form($query, $defaultParams = []) |
||||||
5265 | { |
||||||
5266 | $searchType = isset($_GET['search_type']) ? $_GET['search_type'] : null; |
||||||
5267 | $form = new FormValidator( |
||||||
5268 | 'search_user', |
||||||
5269 | 'get', |
||||||
5270 | api_get_path(WEB_PATH).'main/social/search.php', |
||||||
5271 | '', |
||||||
5272 | [], |
||||||
5273 | FormValidator::LAYOUT_HORIZONTAL |
||||||
5274 | ); |
||||||
5275 | |||||||
5276 | $query = Security::remove_XSS($query); |
||||||
5277 | |||||||
5278 | if (!empty($query)) { |
||||||
5279 | $form->addHeader(get_lang('Results').' "'.$query.'"'); |
||||||
5280 | } |
||||||
5281 | |||||||
5282 | $form->addText( |
||||||
5283 | 'q', |
||||||
5284 | get_lang('UsersGroups'), |
||||||
5285 | false, |
||||||
5286 | [ |
||||||
5287 | 'id' => 'q', |
||||||
5288 | ] |
||||||
5289 | ); |
||||||
5290 | $options = [ |
||||||
5291 | 0 => get_lang('Select'), |
||||||
5292 | 1 => get_lang('User'), |
||||||
5293 | 2 => get_lang('Group'), |
||||||
5294 | ]; |
||||||
5295 | $form->addSelect( |
||||||
5296 | 'search_type', |
||||||
5297 | get_lang('Type'), |
||||||
5298 | $options, |
||||||
5299 | ['onchange' => 'javascript: extra_field_toogle();', 'id' => 'search_type'] |
||||||
5300 | ); |
||||||
5301 | |||||||
5302 | // Extra fields |
||||||
5303 | $extraFields = self::getExtraFilterableFields(); |
||||||
5304 | $defaults = []; |
||||||
5305 | if (is_array($extraFields) && count($extraFields) > 0) { |
||||||
5306 | foreach ($extraFields as $extraField) { |
||||||
5307 | $varName = 'field_'.$extraField['variable']; |
||||||
5308 | $options = [ |
||||||
5309 | 0 => get_lang('Select'), |
||||||
5310 | ]; |
||||||
5311 | foreach ($extraField['data'] as $option) { |
||||||
5312 | if (isset($_GET[$varName])) { |
||||||
5313 | if ($_GET[$varName] == $option[1]) { |
||||||
5314 | $defaults[$option[1]] = true; |
||||||
5315 | } |
||||||
5316 | } |
||||||
5317 | |||||||
5318 | $options[$option[1]] = $option[1]; |
||||||
5319 | } |
||||||
5320 | $form->addSelect($varName, $extraField['name'], $options); |
||||||
5321 | } |
||||||
5322 | } |
||||||
5323 | |||||||
5324 | $defaults['search_type'] = (int) $searchType; |
||||||
5325 | $defaults['q'] = $query; |
||||||
5326 | |||||||
5327 | if (!empty($defaultParams)) { |
||||||
5328 | $defaults = array_merge($defaults, $defaultParams); |
||||||
5329 | } |
||||||
5330 | $form->setDefaults($defaults); |
||||||
5331 | $form->addButtonSearch(get_lang('Search')); |
||||||
5332 | |||||||
5333 | $js = '<script> |
||||||
5334 | extra_field_toogle(); |
||||||
5335 | function extra_field_toogle() { |
||||||
5336 | if (jQuery("select[name=search_type]").val() != "1") { |
||||||
5337 | jQuery(".extra_field").hide(); |
||||||
5338 | } else { |
||||||
5339 | jQuery(".extra_field").show(); |
||||||
5340 | } |
||||||
5341 | } |
||||||
5342 | </script>'; |
||||||
5343 | |||||||
5344 | return $js.$form->returnForm(); |
||||||
5345 | } |
||||||
5346 | |||||||
5347 | /** |
||||||
5348 | * Shows the user menu. |
||||||
5349 | */ |
||||||
5350 | public static function show_menu() |
||||||
5351 | { |
||||||
5352 | echo '<div class="actions">'; |
||||||
5353 | echo '<a href="/main/auth/profile.php">'. |
||||||
5354 | Display::return_icon('profile.png').' '.get_lang('PersonalData').'</a>'; |
||||||
5355 | echo '<a href="/main/messages/inbox.php">'. |
||||||
5356 | Display::return_icon('inbox.png').' '.get_lang('Inbox').'</a>'; |
||||||
5357 | echo '<a href="/main/messages/outbox.php">'. |
||||||
5358 | Display::return_icon('outbox.png').' '.get_lang('Outbox').'</a>'; |
||||||
5359 | echo '<span style="float:right; padding-top:7px;">'. |
||||||
5360 | '<a href="/main/auth/profile.php?show=1">'. |
||||||
5361 | Display::return_icon('edit.gif').' '.get_lang('Configuration').'</a>'; |
||||||
5362 | echo '</span>'; |
||||||
5363 | echo '</div>'; |
||||||
5364 | } |
||||||
5365 | |||||||
5366 | /** |
||||||
5367 | * Allow to register contact to social network. |
||||||
5368 | * |
||||||
5369 | * @param int $friend_id user friend id |
||||||
5370 | * @param int $my_user_id user id |
||||||
5371 | * @param int $relation_type relation between users see constants definition |
||||||
5372 | * |
||||||
5373 | * @return bool |
||||||
5374 | */ |
||||||
5375 | public static function relate_users($friend_id, $my_user_id, $relation_type) |
||||||
5376 | { |
||||||
5377 | $tbl_my_friend = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
||||||
5378 | |||||||
5379 | $friend_id = (int) $friend_id; |
||||||
5380 | $my_user_id = (int) $my_user_id; |
||||||
5381 | $relation_type = (int) $relation_type; |
||||||
5382 | |||||||
5383 | $sql = 'SELECT COUNT(*) as count FROM '.$tbl_my_friend.' |
||||||
5384 | WHERE |
||||||
5385 | friend_user_id='.$friend_id.' AND |
||||||
5386 | user_id='.$my_user_id.' AND |
||||||
5387 | relation_type NOT IN('.USER_RELATION_TYPE_RRHH.', '.USER_RELATION_TYPE_BOSS.') '; |
||||||
5388 | $result = Database::query($sql); |
||||||
5389 | $row = Database::fetch_array($result, 'ASSOC'); |
||||||
5390 | $current_date = api_get_utc_datetime(); |
||||||
5391 | |||||||
5392 | if ($row['count'] == 0) { |
||||||
5393 | $sql = 'INSERT INTO '.$tbl_my_friend.'(friend_user_id,user_id,relation_type,last_edit) |
||||||
5394 | VALUES ('.$friend_id.','.$my_user_id.','.$relation_type.',"'.$current_date.'")'; |
||||||
5395 | Database::query($sql); |
||||||
5396 | |||||||
5397 | return true; |
||||||
5398 | } |
||||||
5399 | |||||||
5400 | $sql = 'SELECT COUNT(*) as count, relation_type FROM '.$tbl_my_friend.' |
||||||
5401 | WHERE |
||||||
5402 | friend_user_id='.$friend_id.' AND |
||||||
5403 | user_id='.$my_user_id.' AND |
||||||
5404 | relation_type NOT IN('.USER_RELATION_TYPE_RRHH.', '.USER_RELATION_TYPE_BOSS.') '; |
||||||
5405 | $result = Database::query($sql); |
||||||
5406 | $row = Database::fetch_array($result, 'ASSOC'); |
||||||
5407 | |||||||
5408 | if ($row['count'] == 1) { |
||||||
5409 | //only for the case of a RRHH or a Student BOSS |
||||||
5410 | if ($row['relation_type'] != $relation_type && |
||||||
5411 | ($relation_type == USER_RELATION_TYPE_RRHH || $relation_type == USER_RELATION_TYPE_BOSS) |
||||||
5412 | ) { |
||||||
5413 | $sql = 'INSERT INTO '.$tbl_my_friend.'(friend_user_id,user_id,relation_type,last_edit) |
||||||
5414 | VALUES ('.$friend_id.','.$my_user_id.','.$relation_type.',"'.$current_date.'")'; |
||||||
5415 | } else { |
||||||
5416 | $sql = 'UPDATE '.$tbl_my_friend.' SET relation_type='.$relation_type.' |
||||||
5417 | WHERE friend_user_id='.$friend_id.' AND user_id='.$my_user_id; |
||||||
5418 | } |
||||||
5419 | Database::query($sql); |
||||||
5420 | |||||||
5421 | return true; |
||||||
5422 | } |
||||||
5423 | |||||||
5424 | return false; |
||||||
5425 | } |
||||||
5426 | |||||||
5427 | /** |
||||||
5428 | * Deletes a contact. |
||||||
5429 | * |
||||||
5430 | * @param bool $friend_id |
||||||
5431 | * @param bool $real_removed true will delete ALL friends relationship |
||||||
5432 | * @param string $with_status_condition |
||||||
5433 | * |
||||||
5434 | * @author isaac flores paz <[email protected]> |
||||||
5435 | * @author Julio Montoya <[email protected]> Cleaning code |
||||||
5436 | */ |
||||||
5437 | public static function remove_user_rel_user( |
||||||
5438 | $friend_id, |
||||||
5439 | $real_removed = false, |
||||||
5440 | $with_status_condition = '' |
||||||
5441 | ) { |
||||||
5442 | $tbl_my_friend = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
||||||
5443 | $tbl_my_message = Database::get_main_table(TABLE_MESSAGE); |
||||||
5444 | $friend_id = (int) $friend_id; |
||||||
5445 | $user_id = api_get_user_id(); |
||||||
5446 | |||||||
5447 | if ($real_removed) { |
||||||
5448 | $extra_condition = ''; |
||||||
5449 | if ($with_status_condition != '') { |
||||||
5450 | $extra_condition = ' AND relation_type = '.intval($with_status_condition); |
||||||
5451 | } |
||||||
5452 | $sql = 'DELETE FROM '.$tbl_my_friend.' |
||||||
5453 | WHERE |
||||||
5454 | relation_type <> '.USER_RELATION_TYPE_RRHH.' AND |
||||||
5455 | friend_user_id='.$friend_id.' '.$extra_condition; |
||||||
5456 | Database::query($sql); |
||||||
5457 | $sql = 'DELETE FROM '.$tbl_my_friend.' |
||||||
5458 | WHERE |
||||||
5459 | relation_type <> '.USER_RELATION_TYPE_RRHH.' AND |
||||||
5460 | user_id='.$friend_id.' '.$extra_condition; |
||||||
5461 | Database::query($sql); |
||||||
5462 | } else { |
||||||
5463 | $sql = 'SELECT COUNT(*) as count FROM '.$tbl_my_friend.' |
||||||
5464 | WHERE |
||||||
5465 | user_id='.$user_id.' AND |
||||||
5466 | relation_type NOT IN('.USER_RELATION_TYPE_DELETED.', '.USER_RELATION_TYPE_RRHH.') AND |
||||||
5467 | friend_user_id='.$friend_id; |
||||||
5468 | $result = Database::query($sql); |
||||||
5469 | $row = Database::fetch_array($result, 'ASSOC'); |
||||||
5470 | if ($row['count'] == 1) { |
||||||
5471 | //Delete user rel user |
||||||
5472 | $sql_i = 'UPDATE '.$tbl_my_friend.' SET relation_type='.USER_RELATION_TYPE_DELETED.' |
||||||
5473 | WHERE user_id='.$user_id.' AND friend_user_id='.$friend_id; |
||||||
5474 | |||||||
5475 | $sql_j = 'UPDATE '.$tbl_my_message.' SET msg_status='.MESSAGE_STATUS_INVITATION_DENIED.' |
||||||
5476 | WHERE |
||||||
5477 | user_receiver_id='.$user_id.' AND |
||||||
5478 | user_sender_id='.$friend_id.' AND update_date="0000-00-00 00:00:00" '; |
||||||
5479 | // Delete user |
||||||
5480 | $sql_ij = 'UPDATE '.$tbl_my_friend.' SET relation_type='.USER_RELATION_TYPE_DELETED.' |
||||||
5481 | WHERE user_id='.$friend_id.' AND friend_user_id='.$user_id; |
||||||
5482 | $sql_ji = 'UPDATE '.$tbl_my_message.' SET msg_status='.MESSAGE_STATUS_INVITATION_DENIED.' |
||||||
5483 | WHERE |
||||||
5484 | user_receiver_id='.$friend_id.' AND |
||||||
5485 | user_sender_id='.$user_id.' AND |
||||||
5486 | update_date="0000-00-00 00:00:00" '; |
||||||
5487 | Database::query($sql_i); |
||||||
5488 | Database::query($sql_j); |
||||||
5489 | Database::query($sql_ij); |
||||||
5490 | Database::query($sql_ji); |
||||||
5491 | } |
||||||
5492 | } |
||||||
5493 | |||||||
5494 | // Delete accepted invitations |
||||||
5495 | $sql = "DELETE FROM $tbl_my_message |
||||||
5496 | WHERE |
||||||
5497 | msg_status = ".MESSAGE_STATUS_INVITATION_ACCEPTED." AND |
||||||
5498 | ( |
||||||
5499 | user_receiver_id = $user_id AND |
||||||
5500 | user_sender_id = $friend_id |
||||||
5501 | ) OR |
||||||
5502 | ( |
||||||
5503 | user_sender_id = $user_id AND |
||||||
5504 | user_receiver_id = $friend_id |
||||||
5505 | ) |
||||||
5506 | "; |
||||||
5507 | Database::query($sql); |
||||||
5508 | } |
||||||
5509 | |||||||
5510 | /** |
||||||
5511 | * @param int $userId |
||||||
5512 | * |
||||||
5513 | * @return array |
||||||
5514 | */ |
||||||
5515 | public static function getDrhListFromUser($userId) |
||||||
5516 | { |
||||||
5517 | $tblUser = Database::get_main_table(TABLE_MAIN_USER); |
||||||
5518 | $tblUserRelUser = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
||||||
5519 | $tblUserRelAccessUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
||||||
5520 | $userId = (int) $userId; |
||||||
5521 | |||||||
5522 | $orderBy = null; |
||||||
5523 | if (api_is_western_name_order()) { |
||||||
5524 | $orderBy .= ' ORDER BY firstname, lastname '; |
||||||
5525 | } else { |
||||||
5526 | $orderBy .= ' ORDER BY lastname, firstname '; |
||||||
5527 | } |
||||||
5528 | |||||||
5529 | $sql = "SELECT u.id, username, u.firstname, u.lastname |
||||||
5530 | FROM $tblUser u |
||||||
5531 | INNER JOIN $tblUserRelUser uru ON (uru.friend_user_id = u.id) |
||||||
5532 | INNER JOIN $tblUserRelAccessUrl a ON (a.user_id = u.id) |
||||||
5533 | WHERE |
||||||
5534 | access_url_id = ".api_get_current_access_url_id()." AND |
||||||
5535 | uru.user_id = '$userId' AND |
||||||
5536 | relation_type = '".USER_RELATION_TYPE_RRHH."' |
||||||
5537 | $orderBy |
||||||
5538 | "; |
||||||
5539 | $result = Database::query($sql); |
||||||
5540 | |||||||
5541 | return Database::store_result($result); |
||||||
5542 | } |
||||||
5543 | |||||||
5544 | /** |
||||||
5545 | * get users followed by human resource manager. |
||||||
5546 | * |
||||||
5547 | * @param int $userId |
||||||
5548 | * @param int $userStatus (STUDENT, COURSEMANAGER, etc) |
||||||
5549 | * @param bool $getOnlyUserId |
||||||
5550 | * @param bool $getSql |
||||||
5551 | * @param bool $getCount |
||||||
5552 | * @param int $from |
||||||
5553 | * @param int $numberItems |
||||||
5554 | * @param int $column |
||||||
5555 | * @param string $direction |
||||||
5556 | * @param int $active |
||||||
5557 | * @param string $lastConnectionDate |
||||||
5558 | * |
||||||
5559 | * @return array users |
||||||
5560 | */ |
||||||
5561 | public static function get_users_followed_by_drh( |
||||||
5562 | $userId, |
||||||
5563 | $userStatus = 0, |
||||||
5564 | $getOnlyUserId = false, |
||||||
5565 | $getSql = false, |
||||||
5566 | $getCount = false, |
||||||
5567 | $from = null, |
||||||
5568 | $numberItems = null, |
||||||
5569 | $column = null, |
||||||
5570 | $direction = null, |
||||||
5571 | $active = null, |
||||||
5572 | $lastConnectionDate = null |
||||||
5573 | ) { |
||||||
5574 | return self::getUsersFollowedByUser( |
||||||
0 ignored issues
–
show
|
|||||||
5575 | $userId, |
||||||
5576 | $userStatus, |
||||||
5577 | $getOnlyUserId, |
||||||
5578 | $getSql, |
||||||
5579 | $getCount, |
||||||
5580 | $from, |
||||||
5581 | $numberItems, |
||||||
5582 | $column, |
||||||
5583 | $direction, |
||||||
5584 | $active, |
||||||
5585 | $lastConnectionDate, |
||||||
5586 | DRH |
||||||
5587 | ); |
||||||
5588 | } |
||||||
5589 | |||||||
5590 | /** |
||||||
5591 | * Get users followed by human resource manager. |
||||||
5592 | * |
||||||
5593 | * @param int $userId |
||||||
5594 | * @param int $userStatus Filter users by status (STUDENT, COURSEMANAGER, etc) |
||||||
5595 | * @param bool $getOnlyUserId |
||||||
5596 | * @param bool $getSql |
||||||
5597 | * @param bool $getCount |
||||||
5598 | * @param int $from |
||||||
5599 | * @param int $numberItems |
||||||
5600 | * @param int $column |
||||||
5601 | * @param string $direction |
||||||
5602 | * @param int $active |
||||||
5603 | * @param string $lastConnectionDate |
||||||
5604 | * @param int $status the function is called by who? COURSEMANAGER, DRH? |
||||||
5605 | * @param string $keyword |
||||||
5606 | * @param bool $checkSessionVisibility |
||||||
5607 | * |
||||||
5608 | * @return mixed Users list (array) or the SQL query if $getSQL was set to true |
||||||
5609 | */ |
||||||
5610 | public static function getUsersFollowedByUser( |
||||||
5611 | $userId, |
||||||
5612 | $userStatus = null, |
||||||
5613 | $getOnlyUserId = false, |
||||||
5614 | $getSql = false, |
||||||
5615 | $getCount = false, |
||||||
5616 | $from = null, |
||||||
5617 | $numberItems = null, |
||||||
5618 | $column = null, |
||||||
5619 | $direction = null, |
||||||
5620 | $active = null, |
||||||
5621 | $lastConnectionDate = null, |
||||||
5622 | $status = null, |
||||||
5623 | $keyword = null, |
||||||
5624 | $checkSessionVisibility = false, |
||||||
5625 | $filterUsers = null |
||||||
5626 | ) { |
||||||
5627 | // Database Table Definitions |
||||||
5628 | $tbl_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
5629 | $tbl_user_rel_user = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
||||||
5630 | $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
||||||
5631 | $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION); |
||||||
5632 | $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
||||||
5633 | $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
||||||
5634 | $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION); |
||||||
5635 | $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER); |
||||||
5636 | |||||||
5637 | $userId = (int) $userId; |
||||||
5638 | $limitCondition = ''; |
||||||
5639 | |||||||
5640 | if (isset($from) && isset($numberItems)) { |
||||||
5641 | $from = (int) $from; |
||||||
5642 | $numberItems = (int) $numberItems; |
||||||
5643 | $limitCondition = "LIMIT $from, $numberItems"; |
||||||
5644 | } |
||||||
5645 | |||||||
5646 | $column = Database::escape_string($column); |
||||||
5647 | $direction = in_array(strtolower($direction), ['asc', 'desc']) ? $direction : null; |
||||||
5648 | |||||||
5649 | $userConditions = ''; |
||||||
5650 | if (!empty($userStatus)) { |
||||||
5651 | $userConditions .= ' AND u.status = '.intval($userStatus); |
||||||
5652 | } |
||||||
5653 | |||||||
5654 | $select = " SELECT DISTINCT u.id user_id, u.username, u.lastname, u.firstname, u.email "; |
||||||
5655 | if ($getOnlyUserId) { |
||||||
5656 | $select = " SELECT DISTINCT u.id user_id"; |
||||||
5657 | } |
||||||
5658 | |||||||
5659 | $masterSelect = "SELECT DISTINCT * FROM "; |
||||||
5660 | |||||||
5661 | if ($getCount) { |
||||||
5662 | $masterSelect = "SELECT COUNT(DISTINCT(user_id)) as count FROM "; |
||||||
5663 | $select = " SELECT DISTINCT(u.id) user_id"; |
||||||
5664 | } |
||||||
5665 | |||||||
5666 | if (!is_null($active)) { |
||||||
5667 | $active = intval($active); |
||||||
5668 | $userConditions .= " AND u.active = $active "; |
||||||
5669 | } |
||||||
5670 | |||||||
5671 | if (!empty($keyword)) { |
||||||
5672 | $keyword = trim(Database::escape_string($keyword)); |
||||||
5673 | $keywordParts = array_filter(explode(' ', $keyword)); |
||||||
5674 | $extraKeyword = ''; |
||||||
5675 | if (!empty($keywordParts)) { |
||||||
5676 | $keywordPartsFixed = Database::escape_string(implode('%', $keywordParts)); |
||||||
5677 | if (!empty($keywordPartsFixed)) { |
||||||
5678 | $extraKeyword .= " OR |
||||||
5679 | CONCAT(u.firstname, ' ', u.lastname) LIKE '%$keywordPartsFixed%' OR |
||||||
5680 | CONCAT(u.lastname, ' ', u.firstname) LIKE '%$keywordPartsFixed%' "; |
||||||
5681 | } |
||||||
5682 | } |
||||||
5683 | |||||||
5684 | $userConditions .= " AND ( |
||||||
5685 | u.username LIKE '%$keyword%' OR |
||||||
5686 | u.firstname LIKE '%$keyword%' OR |
||||||
5687 | u.lastname LIKE '%$keyword%' OR |
||||||
5688 | u.official_code LIKE '%$keyword%' OR |
||||||
5689 | u.email LIKE '%$keyword%' OR |
||||||
5690 | CONCAT(u.firstname, ' ', u.lastname) LIKE '%$keyword%' OR |
||||||
5691 | CONCAT(u.lastname, ' ', u.firstname) LIKE '%$keyword%' |
||||||
5692 | $extraKeyword |
||||||
5693 | )"; |
||||||
5694 | } |
||||||
5695 | |||||||
5696 | if (!empty($lastConnectionDate)) { |
||||||
5697 | $lastConnectionDate = Database::escape_string($lastConnectionDate); |
||||||
5698 | $userConditions .= " AND u.last_login <= '$lastConnectionDate' "; |
||||||
5699 | } |
||||||
5700 | |||||||
5701 | if (!empty($filterUsers)) { |
||||||
5702 | $userConditions .= " AND u.id IN(".implode(',', $filterUsers).")"; |
||||||
5703 | } |
||||||
5704 | |||||||
5705 | $sessionConditionsCoach = null; |
||||||
5706 | $dateCondition = ''; |
||||||
5707 | $drhConditions = null; |
||||||
5708 | $teacherSelect = null; |
||||||
5709 | |||||||
5710 | $urlId = api_get_current_access_url_id(); |
||||||
5711 | |||||||
5712 | switch ($status) { |
||||||
5713 | case DRH: |
||||||
5714 | $drhConditions .= " AND |
||||||
5715 | friend_user_id = '$userId' AND |
||||||
5716 | relation_type = '".USER_RELATION_TYPE_RRHH."' |
||||||
5717 | "; |
||||||
5718 | break; |
||||||
5719 | case COURSEMANAGER: |
||||||
5720 | $drhConditions .= " AND |
||||||
5721 | friend_user_id = '$userId' AND |
||||||
5722 | relation_type = '".USER_RELATION_TYPE_RRHH."' |
||||||
5723 | "; |
||||||
5724 | |||||||
5725 | $sessionConditionsCoach .= " AND |
||||||
5726 | (s.id_coach = '$userId') |
||||||
5727 | "; |
||||||
5728 | |||||||
5729 | $sessionConditionsTeacher = " AND |
||||||
5730 | (scu.status = 2 AND scu.user_id = '$userId') |
||||||
5731 | "; |
||||||
5732 | |||||||
5733 | if ($checkSessionVisibility) { |
||||||
5734 | $today = api_strtotime('now', 'UTC'); |
||||||
5735 | $today = date('Y-m-d', $today); |
||||||
5736 | $dateCondition = " |
||||||
5737 | AND |
||||||
5738 | ( |
||||||
5739 | (s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR |
||||||
5740 | (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR |
||||||
5741 | (s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR |
||||||
5742 | ('$today' <= s.access_end_date AND s.access_start_date IS NULL) |
||||||
5743 | ) |
||||||
5744 | "; |
||||||
5745 | } |
||||||
5746 | |||||||
5747 | // Use $tbl_session_rel_course_rel_user instead of $tbl_session_rel_user |
||||||
5748 | /* |
||||||
5749 | INNER JOIN $tbl_session_rel_user sru |
||||||
5750 | ON (sru.user_id = u.id) |
||||||
5751 | INNER JOIN $tbl_session_rel_course_rel_user scu |
||||||
5752 | ON (scu.user_id = u.id AND scu.c_id IS NOT NULL AND visibility = 1)*/ |
||||||
5753 | $teacherSelect = |
||||||
5754 | "UNION ALL ( |
||||||
5755 | $select |
||||||
5756 | FROM $tbl_user u |
||||||
5757 | INNER JOIN $tbl_session_rel_user sru ON (sru.user_id = u.id) |
||||||
5758 | WHERE |
||||||
5759 | ( |
||||||
5760 | sru.session_id IN ( |
||||||
5761 | SELECT DISTINCT(s.id) FROM $tbl_session s INNER JOIN |
||||||
5762 | $tbl_session_rel_access_url session_rel_access_rel_user |
||||||
5763 | ON session_rel_access_rel_user.session_id = s.id |
||||||
5764 | WHERE access_url_id = ".$urlId." |
||||||
5765 | $sessionConditionsCoach |
||||||
5766 | ) OR sru.session_id IN ( |
||||||
5767 | SELECT DISTINCT(s.id) FROM $tbl_session s |
||||||
5768 | INNER JOIN $tbl_session_rel_access_url url |
||||||
5769 | ON (url.session_id = s.id) |
||||||
5770 | INNER JOIN $tbl_session_rel_course_rel_user scu |
||||||
5771 | ON (scu.session_id = s.id) |
||||||
5772 | WHERE access_url_id = ".$urlId." |
||||||
5773 | $sessionConditionsTeacher |
||||||
5774 | $dateCondition |
||||||
5775 | ) |
||||||
5776 | ) |
||||||
5777 | $userConditions |
||||||
5778 | ) |
||||||
5779 | UNION ALL( |
||||||
5780 | $select |
||||||
5781 | FROM $tbl_user u |
||||||
5782 | INNER JOIN $tbl_course_user cu ON (cu.user_id = u.id) |
||||||
5783 | WHERE cu.c_id IN ( |
||||||
5784 | SELECT DISTINCT(c_id) FROM $tbl_course_user |
||||||
5785 | WHERE user_id = $userId AND status = ".COURSEMANAGER." |
||||||
5786 | ) |
||||||
5787 | $userConditions |
||||||
5788 | )" |
||||||
5789 | ; |
||||||
5790 | break; |
||||||
5791 | case STUDENT_BOSS: |
||||||
5792 | $drhConditions = " AND friend_user_id = $userId AND relation_type = ".USER_RELATION_TYPE_BOSS; |
||||||
5793 | break; |
||||||
5794 | case HRM_REQUEST: |
||||||
5795 | $drhConditions .= " AND |
||||||
5796 | friend_user_id = '$userId' AND |
||||||
5797 | relation_type = '".USER_RELATION_TYPE_HRM_REQUEST."' |
||||||
5798 | "; |
||||||
5799 | break; |
||||||
5800 | } |
||||||
5801 | |||||||
5802 | $join = null; |
||||||
5803 | $sql = " $masterSelect |
||||||
5804 | ( |
||||||
5805 | ( |
||||||
5806 | $select |
||||||
5807 | FROM $tbl_user u |
||||||
5808 | INNER JOIN $tbl_user_rel_user uru ON (uru.user_id = u.id) |
||||||
5809 | LEFT JOIN $tbl_user_rel_access_url a ON (a.user_id = u.id) |
||||||
5810 | $join |
||||||
5811 | WHERE |
||||||
5812 | access_url_id = ".$urlId." |
||||||
5813 | $drhConditions |
||||||
5814 | $userConditions |
||||||
5815 | ) |
||||||
5816 | $teacherSelect |
||||||
5817 | ) as t1"; |
||||||
5818 | |||||||
5819 | if ($getSql) { |
||||||
5820 | return $sql; |
||||||
5821 | } |
||||||
5822 | |||||||
5823 | if ($getCount) { |
||||||
5824 | $result = Database::query($sql); |
||||||
5825 | $row = Database::fetch_array($result); |
||||||
5826 | |||||||
5827 | return $row['count']; |
||||||
5828 | } |
||||||
5829 | |||||||
5830 | $orderBy = null; |
||||||
5831 | if ($getOnlyUserId == false) { |
||||||
5832 | if (api_is_western_name_order()) { |
||||||
5833 | $orderBy .= " ORDER BY firstname, lastname "; |
||||||
5834 | } else { |
||||||
5835 | $orderBy .= " ORDER BY lastname, firstname "; |
||||||
5836 | } |
||||||
5837 | |||||||
5838 | if (!empty($column) && !empty($direction)) { |
||||||
5839 | // Fixing order due the UNIONs |
||||||
5840 | $column = str_replace('u.', '', $column); |
||||||
5841 | $column = trim($column); |
||||||
5842 | $orderBy = " ORDER BY `$column` $direction "; |
||||||
5843 | } |
||||||
5844 | } |
||||||
5845 | |||||||
5846 | $sql .= $orderBy; |
||||||
5847 | $sql .= $limitCondition; |
||||||
5848 | |||||||
5849 | $result = Database::query($sql); |
||||||
5850 | $users = []; |
||||||
5851 | if (Database::num_rows($result) > 0) { |
||||||
5852 | while ($row = Database::fetch_array($result)) { |
||||||
5853 | $users[$row['user_id']] = $row; |
||||||
5854 | } |
||||||
5855 | } |
||||||
5856 | |||||||
5857 | return $users; |
||||||
5858 | } |
||||||
5859 | |||||||
5860 | /** |
||||||
5861 | * Subscribes users to human resource manager (Dashboard feature). |
||||||
5862 | * |
||||||
5863 | * @param int $hr_dept_id |
||||||
5864 | * @param array $users_id |
||||||
5865 | * @param bool $deleteOtherAssignedUsers |
||||||
5866 | * |
||||||
5867 | * @return int |
||||||
5868 | */ |
||||||
5869 | public static function subscribeUsersToHRManager( |
||||||
5870 | $hr_dept_id, |
||||||
5871 | $users_id, |
||||||
5872 | $deleteOtherAssignedUsers = true |
||||||
5873 | ) { |
||||||
5874 | return self::subscribeUsersToUser( |
||||||
5875 | $hr_dept_id, |
||||||
5876 | $users_id, |
||||||
5877 | USER_RELATION_TYPE_RRHH, |
||||||
5878 | false, |
||||||
5879 | $deleteOtherAssignedUsers |
||||||
5880 | ); |
||||||
5881 | } |
||||||
5882 | |||||||
5883 | /** |
||||||
5884 | * Register request to assign users to HRM. |
||||||
5885 | * |
||||||
5886 | * @param int $hrmId The HRM ID |
||||||
5887 | * @param array $usersId The users IDs |
||||||
5888 | * |
||||||
5889 | * @return int |
||||||
5890 | */ |
||||||
5891 | public static function requestUsersToHRManager($hrmId, $usersId) |
||||||
5892 | { |
||||||
5893 | return self::subscribeUsersToUser( |
||||||
5894 | $hrmId, |
||||||
5895 | $usersId, |
||||||
5896 | USER_RELATION_TYPE_HRM_REQUEST, |
||||||
5897 | false, |
||||||
5898 | false |
||||||
5899 | ); |
||||||
5900 | } |
||||||
5901 | |||||||
5902 | /** |
||||||
5903 | * Remove the requests for assign a user to a HRM. |
||||||
5904 | * |
||||||
5905 | * @param array $usersId List of user IDs from whom to remove all relations requests with HRM |
||||||
5906 | */ |
||||||
5907 | public static function clearHrmRequestsForUser(User $hrmId, $usersId) |
||||||
5908 | { |
||||||
5909 | $users = implode(', ', $usersId); |
||||||
5910 | Database::getManager() |
||||||
5911 | ->createQuery(' |
||||||
5912 | DELETE FROM ChamiloCoreBundle:UserRelUser uru |
||||||
5913 | WHERE uru.friendUserId = :hrm_id AND uru.relationType = :relation_type AND uru.userId IN (:users_ids) |
||||||
5914 | ') |
||||||
5915 | ->execute(['hrm_id' => $hrmId, 'relation_type' => USER_RELATION_TYPE_HRM_REQUEST, 'users_ids' => $users]); |
||||||
5916 | } |
||||||
5917 | |||||||
5918 | /** |
||||||
5919 | * Add subscribed users to a user by relation type. |
||||||
5920 | * |
||||||
5921 | * @param int $userId The user id |
||||||
5922 | * @param array $subscribedUsersId The id of subscribed users |
||||||
5923 | * @param string $relationType The relation type |
||||||
5924 | * @param bool $deleteUsersBeforeInsert |
||||||
5925 | * @param bool $deleteOtherAssignedUsers |
||||||
5926 | * |
||||||
5927 | * @return int |
||||||
5928 | */ |
||||||
5929 | public static function subscribeUsersToUser( |
||||||
5930 | $userId, |
||||||
5931 | $subscribedUsersId, |
||||||
5932 | $relationType, |
||||||
5933 | $deleteUsersBeforeInsert = false, |
||||||
5934 | $deleteOtherAssignedUsers = true |
||||||
5935 | ) { |
||||||
5936 | $userRelUserTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
||||||
5937 | $userRelAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
||||||
5938 | |||||||
5939 | $userId = (int) $userId; |
||||||
5940 | $relationType = (int) $relationType; |
||||||
5941 | $affectedRows = 0; |
||||||
5942 | |||||||
5943 | if ($deleteOtherAssignedUsers) { |
||||||
5944 | if (api_get_multiple_access_url()) { |
||||||
5945 | // Deleting assigned users to hrm_id |
||||||
5946 | $sql = "SELECT s.user_id |
||||||
5947 | FROM $userRelUserTable s |
||||||
5948 | INNER JOIN $userRelAccessUrlTable a |
||||||
5949 | ON (a.user_id = s.user_id) |
||||||
5950 | WHERE |
||||||
5951 | friend_user_id = $userId AND |
||||||
5952 | relation_type = $relationType AND |
||||||
5953 | access_url_id = ".api_get_current_access_url_id(); |
||||||
5954 | } else { |
||||||
5955 | $sql = "SELECT user_id |
||||||
5956 | FROM $userRelUserTable |
||||||
5957 | WHERE |
||||||
5958 | friend_user_id = $userId AND |
||||||
5959 | relation_type = $relationType"; |
||||||
5960 | } |
||||||
5961 | $result = Database::query($sql); |
||||||
5962 | |||||||
5963 | if (Database::num_rows($result) > 0) { |
||||||
5964 | while ($row = Database::fetch_array($result)) { |
||||||
5965 | $sql = "DELETE FROM $userRelUserTable |
||||||
5966 | WHERE |
||||||
5967 | user_id = {$row['user_id']} AND |
||||||
5968 | friend_user_id = $userId AND |
||||||
5969 | relation_type = $relationType"; |
||||||
5970 | Database::query($sql); |
||||||
5971 | } |
||||||
5972 | } |
||||||
5973 | } |
||||||
5974 | |||||||
5975 | if ($deleteUsersBeforeInsert) { |
||||||
5976 | $sql = "DELETE FROM $userRelUserTable |
||||||
5977 | WHERE |
||||||
5978 | user_id = $userId AND |
||||||
5979 | relation_type = $relationType"; |
||||||
5980 | Database::query($sql); |
||||||
5981 | } |
||||||
5982 | |||||||
5983 | // Inserting new user list |
||||||
5984 | if (is_array($subscribedUsersId)) { |
||||||
5985 | foreach ($subscribedUsersId as $subscribedUserId) { |
||||||
5986 | $subscribedUserId = (int) $subscribedUserId; |
||||||
5987 | $sql = "SELECT id |
||||||
5988 | FROM $userRelUserTable |
||||||
5989 | WHERE |
||||||
5990 | user_id = $subscribedUserId AND |
||||||
5991 | friend_user_id = $userId AND |
||||||
5992 | relation_type = $relationType"; |
||||||
5993 | |||||||
5994 | $result = Database::query($sql); |
||||||
5995 | $num = Database::num_rows($result); |
||||||
5996 | if ($num === 0) { |
||||||
5997 | $date = api_get_utc_datetime(); |
||||||
5998 | $sql = "INSERT INTO $userRelUserTable (user_id, friend_user_id, relation_type, last_edit) |
||||||
5999 | VALUES ($subscribedUserId, $userId, $relationType, '$date')"; |
||||||
6000 | $result = Database::query($sql); |
||||||
6001 | $affectedRows += Database::affected_rows($result); |
||||||
6002 | } |
||||||
6003 | } |
||||||
6004 | } |
||||||
6005 | |||||||
6006 | return $affectedRows; |
||||||
6007 | } |
||||||
6008 | |||||||
6009 | /** |
||||||
6010 | * This function check if an user is followed by human resources manager. |
||||||
6011 | * |
||||||
6012 | * @param int $user_id |
||||||
6013 | * @param int $hr_dept_id Human resources manager |
||||||
6014 | * |
||||||
6015 | * @return bool |
||||||
6016 | */ |
||||||
6017 | public static function is_user_followed_by_drh($user_id, $hr_dept_id) |
||||||
6018 | { |
||||||
6019 | $tbl_user_rel_user = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
||||||
6020 | $user_id = (int) $user_id; |
||||||
6021 | $hr_dept_id = (int) $hr_dept_id; |
||||||
6022 | $result = false; |
||||||
6023 | |||||||
6024 | $sql = "SELECT user_id FROM $tbl_user_rel_user |
||||||
6025 | WHERE |
||||||
6026 | user_id = $user_id AND |
||||||
6027 | friend_user_id = $hr_dept_id AND |
||||||
6028 | relation_type = ".USER_RELATION_TYPE_RRHH; |
||||||
6029 | $rs = Database::query($sql); |
||||||
6030 | if (Database::num_rows($rs) > 0) { |
||||||
6031 | $result = true; |
||||||
6032 | } |
||||||
6033 | |||||||
6034 | return $result; |
||||||
6035 | } |
||||||
6036 | |||||||
6037 | /** |
||||||
6038 | * Return the user id of teacher or session administrator. |
||||||
6039 | * |
||||||
6040 | * @return int|bool The user id, or false if the session ID was negative |
||||||
6041 | */ |
||||||
6042 | public static function get_user_id_of_course_admin_or_session_admin(array $courseInfo) |
||||||
6043 | { |
||||||
6044 | $session = api_get_session_id(); |
||||||
6045 | $table_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
6046 | $table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
||||||
6047 | $table_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
||||||
6048 | |||||||
6049 | if (empty($courseInfo)) { |
||||||
6050 | return false; |
||||||
6051 | } |
||||||
6052 | |||||||
6053 | $courseId = $courseInfo['real_id']; |
||||||
6054 | |||||||
6055 | if (empty($session)) { |
||||||
6056 | $sql = 'SELECT u.id uid FROM '.$table_user.' u |
||||||
6057 | INNER JOIN '.$table_course_user.' ru |
||||||
6058 | ON ru.user_id = u.id |
||||||
6059 | WHERE |
||||||
6060 | ru.status = '.COURSEMANAGER.' AND |
||||||
6061 | ru.c_id = "'.$courseId.'" '; |
||||||
6062 | } else { |
||||||
6063 | $sql = 'SELECT u.id uid FROM '.$table_user.' u |
||||||
6064 | INNER JOIN '.$table_session_course_user.' sru |
||||||
6065 | ON sru.user_id=u.id |
||||||
6066 | WHERE |
||||||
6067 | sru.c_id="'.$courseId.'" AND |
||||||
6068 | sru.session_id="'.$session.'" AND |
||||||
6069 | sru.status = '.SessionEntity::COACH; |
||||||
6070 | } |
||||||
6071 | |||||||
6072 | $rs = Database::query($sql); |
||||||
6073 | $num_rows = Database::num_rows($rs); |
||||||
6074 | |||||||
6075 | if (0 === $num_rows) { |
||||||
6076 | return false; |
||||||
6077 | } |
||||||
6078 | |||||||
6079 | if (1 === $num_rows) { |
||||||
6080 | $row = Database::fetch_array($rs); |
||||||
6081 | |||||||
6082 | return (int) $row['uid']; |
||||||
6083 | } |
||||||
6084 | |||||||
6085 | $my_num_rows = $num_rows; |
||||||
6086 | $my_user_id = Database::result($rs, $my_num_rows - 1, 'uid'); |
||||||
6087 | |||||||
6088 | return (int) $my_user_id; |
||||||
6089 | } |
||||||
6090 | |||||||
6091 | /** |
||||||
6092 | * Determines if a user is a gradebook certified. |
||||||
6093 | * |
||||||
6094 | * @param int $cat_id The category id of gradebook |
||||||
6095 | * @param int $user_id The user id |
||||||
6096 | * |
||||||
6097 | * @return bool |
||||||
6098 | */ |
||||||
6099 | public static function is_user_certified($cat_id, $user_id) |
||||||
6100 | { |
||||||
6101 | $cat_id = (int) $cat_id; |
||||||
6102 | $user_id = (int) $user_id; |
||||||
6103 | |||||||
6104 | $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE); |
||||||
6105 | $sql = 'SELECT path_certificate |
||||||
6106 | FROM '.$table.' |
||||||
6107 | WHERE |
||||||
6108 | cat_id = "'.$cat_id.'" AND |
||||||
6109 | user_id = "'.$user_id.'"'; |
||||||
6110 | $rs = Database::query($sql); |
||||||
6111 | $row = Database::fetch_array($rs); |
||||||
6112 | |||||||
6113 | if ($row['path_certificate'] == '' || is_null($row['path_certificate'])) { |
||||||
6114 | return false; |
||||||
6115 | } |
||||||
6116 | |||||||
6117 | return true; |
||||||
6118 | } |
||||||
6119 | |||||||
6120 | /** |
||||||
6121 | * Gets the info about a gradebook certificate for a user by course. |
||||||
6122 | * |
||||||
6123 | * @param string $course_code The course code |
||||||
6124 | * @param int $session_id |
||||||
6125 | * @param int $user_id The user id |
||||||
6126 | * @param string $startDate date string |
||||||
6127 | * @param string $endDate date string |
||||||
6128 | * |
||||||
6129 | * @return array if there is not information return false |
||||||
6130 | */ |
||||||
6131 | public static function get_info_gradebook_certificate( |
||||||
6132 | $course_code, |
||||||
6133 | $session_id, |
||||||
6134 | $user_id, |
||||||
6135 | $startDate = null, |
||||||
6136 | $endDate = null |
||||||
6137 | ) { |
||||||
6138 | $tbl_grade_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE); |
||||||
6139 | $tbl_grade_category = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY); |
||||||
6140 | $session_id = (int) $session_id; |
||||||
6141 | $user_id = (int) $user_id; |
||||||
6142 | |||||||
6143 | if (empty($session_id)) { |
||||||
6144 | $session_condition = ' AND (session_id = "" OR session_id = 0 OR session_id IS NULL )'; |
||||||
6145 | } else { |
||||||
6146 | $session_condition = " AND session_id = $session_id"; |
||||||
6147 | } |
||||||
6148 | |||||||
6149 | $dateConditions = ""; |
||||||
6150 | if (!empty($startDate)) { |
||||||
6151 | $startDate = api_get_utc_datetime($startDate, false, true); |
||||||
6152 | $dateConditions .= " AND created_at >= '".$startDate->format('Y-m-d 00:00:00')."' "; |
||||||
6153 | } |
||||||
6154 | if (!empty($endDate)) { |
||||||
6155 | $endDate = api_get_utc_datetime($endDate, false, true); |
||||||
6156 | $dateConditions .= " AND created_at <= '".$endDate->format('Y-m-d 23:59:59')."' "; |
||||||
6157 | } |
||||||
6158 | |||||||
6159 | $sql = 'SELECT * FROM '.$tbl_grade_certificate.' |
||||||
6160 | WHERE cat_id = ( |
||||||
6161 | SELECT id FROM '.$tbl_grade_category.' |
||||||
6162 | WHERE |
||||||
6163 | course_code = "'.Database::escape_string($course_code).'" '.$session_condition.' '.$dateConditions.' |
||||||
6164 | LIMIT 1 |
||||||
6165 | ) AND user_id='.$user_id; |
||||||
6166 | |||||||
6167 | $rs = Database::query($sql); |
||||||
6168 | if (Database::num_rows($rs) > 0) { |
||||||
6169 | $row = Database::fetch_array($rs, 'ASSOC'); |
||||||
6170 | $score = $row['score_certificate']; |
||||||
6171 | $category_id = $row['cat_id']; |
||||||
6172 | $cat = Category::load($category_id); |
||||||
6173 | $displayscore = ScoreDisplay::instance(); |
||||||
6174 | if (isset($cat) && $displayscore->is_custom()) { |
||||||
6175 | $grade = $displayscore->display_score( |
||||||
6176 | [$score, $cat[0]->get_weight()], |
||||||
6177 | SCORE_DIV_PERCENT_WITH_CUSTOM |
||||||
6178 | ); |
||||||
6179 | } else { |
||||||
6180 | $grade = $displayscore->display_score( |
||||||
6181 | [$score, $cat[0]->get_weight()] |
||||||
6182 | ); |
||||||
6183 | } |
||||||
6184 | $row['grade'] = $grade; |
||||||
6185 | |||||||
6186 | return $row; |
||||||
6187 | } |
||||||
6188 | |||||||
6189 | return false; |
||||||
6190 | } |
||||||
6191 | |||||||
6192 | /** |
||||||
6193 | * This function check if the user is a coach inside session course. |
||||||
6194 | * |
||||||
6195 | * @param int $user_id User id |
||||||
6196 | * @param int $courseId |
||||||
6197 | * @param int $session_id |
||||||
6198 | * |
||||||
6199 | * @return bool True if the user is a coach |
||||||
6200 | */ |
||||||
6201 | public static function is_session_course_coach($user_id, $courseId, $session_id) |
||||||
6202 | { |
||||||
6203 | $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
||||||
6204 | // Protect data |
||||||
6205 | $user_id = intval($user_id); |
||||||
6206 | $courseId = intval($courseId); |
||||||
6207 | $session_id = intval($session_id); |
||||||
6208 | $result = false; |
||||||
6209 | |||||||
6210 | $sql = "SELECT session_id FROM $table |
||||||
6211 | WHERE |
||||||
6212 | session_id = $session_id AND |
||||||
6213 | c_id = $courseId AND |
||||||
6214 | user_id = $user_id AND |
||||||
6215 | status = 2 "; |
||||||
6216 | $res = Database::query($sql); |
||||||
6217 | |||||||
6218 | if (Database::num_rows($res) > 0) { |
||||||
6219 | $result = true; |
||||||
6220 | } |
||||||
6221 | |||||||
6222 | return $result; |
||||||
6223 | } |
||||||
6224 | |||||||
6225 | /** |
||||||
6226 | * This function returns an icon path that represents the favicon of the website of which the url given. |
||||||
6227 | * Defaults to the current Chamilo favicon. |
||||||
6228 | * |
||||||
6229 | * @param string $url1 URL of website where to look for favicon.ico |
||||||
6230 | * @param string $url2 Optional second URL of website where to look for favicon.ico |
||||||
6231 | * |
||||||
6232 | * @return string Path of icon to load |
||||||
6233 | */ |
||||||
6234 | public static function get_favicon_from_url($url1, $url2 = null) |
||||||
6235 | { |
||||||
6236 | $icon_link = ''; |
||||||
6237 | $url = $url1; |
||||||
6238 | if (empty($url1)) { |
||||||
6239 | $url = $url2; |
||||||
6240 | if (empty($url)) { |
||||||
6241 | $url = api_get_access_url(api_get_current_access_url_id()); |
||||||
6242 | $url = $url[0]; |
||||||
6243 | } |
||||||
6244 | } |
||||||
6245 | if (!empty($url)) { |
||||||
6246 | $pieces = parse_url($url); |
||||||
6247 | $icon_link = $pieces['scheme'].'://'.$pieces['host'].'/favicon.ico'; |
||||||
6248 | } |
||||||
6249 | |||||||
6250 | return $icon_link; |
||||||
6251 | } |
||||||
6252 | |||||||
6253 | public static function addUserAsAdmin(User $user) |
||||||
6254 | { |
||||||
6255 | if ($user) { |
||||||
6256 | $userId = $user->getId(); |
||||||
6257 | if (!self::is_admin($userId)) { |
||||||
6258 | $table = Database::get_main_table(TABLE_MAIN_ADMIN); |
||||||
6259 | $sql = "INSERT INTO $table SET user_id = $userId"; |
||||||
6260 | Database::query($sql); |
||||||
6261 | } |
||||||
6262 | |||||||
6263 | $user->addRole('ROLE_SUPER_ADMIN'); |
||||||
6264 | self::getManager()->updateUser($user, true); |
||||||
6265 | } |
||||||
6266 | } |
||||||
6267 | |||||||
6268 | public static function removeUserAdmin(User $user) |
||||||
6269 | { |
||||||
6270 | $userId = (int) $user->getId(); |
||||||
6271 | if (self::is_admin($userId)) { |
||||||
6272 | $table = Database::get_main_table(TABLE_MAIN_ADMIN); |
||||||
6273 | $sql = "DELETE FROM $table WHERE user_id = $userId"; |
||||||
6274 | Database::query($sql); |
||||||
6275 | $user->removeRole('ROLE_SUPER_ADMIN'); |
||||||
6276 | self::getManager()->updateUser($user, true); |
||||||
6277 | } |
||||||
6278 | } |
||||||
6279 | |||||||
6280 | /** |
||||||
6281 | * @param string $from |
||||||
6282 | * @param string $to |
||||||
6283 | */ |
||||||
6284 | public static function update_all_user_languages($from, $to) |
||||||
6285 | { |
||||||
6286 | $table_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
6287 | $from = Database::escape_string($from); |
||||||
6288 | $to = Database::escape_string($to); |
||||||
6289 | |||||||
6290 | if (!empty($to) && !empty($from)) { |
||||||
6291 | $sql = "UPDATE $table_user SET language = '$to' |
||||||
6292 | WHERE language = '$from'"; |
||||||
6293 | Database::query($sql); |
||||||
6294 | } |
||||||
6295 | } |
||||||
6296 | |||||||
6297 | /** |
||||||
6298 | * Subscribe boss to students. |
||||||
6299 | * |
||||||
6300 | * @param int $bossId The boss id |
||||||
6301 | * @param array $usersId The users array |
||||||
6302 | * @param bool $deleteOtherAssignedUsers |
||||||
6303 | * |
||||||
6304 | * @return int Affected rows |
||||||
6305 | */ |
||||||
6306 | public static function subscribeBossToUsers($bossId, $usersId, $deleteOtherAssignedUsers = true) |
||||||
6307 | { |
||||||
6308 | return self::subscribeUsersToUser( |
||||||
6309 | $bossId, |
||||||
6310 | $usersId, |
||||||
6311 | USER_RELATION_TYPE_BOSS, |
||||||
6312 | false, |
||||||
6313 | $deleteOtherAssignedUsers |
||||||
6314 | ); |
||||||
6315 | } |
||||||
6316 | |||||||
6317 | /** |
||||||
6318 | * @param int $userId |
||||||
6319 | * |
||||||
6320 | * @return bool |
||||||
6321 | */ |
||||||
6322 | public static function removeAllBossFromStudent($userId) |
||||||
6323 | { |
||||||
6324 | $userId = (int) $userId; |
||||||
6325 | |||||||
6326 | if (empty($userId)) { |
||||||
6327 | return false; |
||||||
6328 | } |
||||||
6329 | |||||||
6330 | $userRelUserTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
||||||
6331 | $sql = "DELETE FROM $userRelUserTable |
||||||
6332 | WHERE user_id = $userId AND relation_type = ".USER_RELATION_TYPE_BOSS; |
||||||
6333 | Database::query($sql); |
||||||
6334 | |||||||
6335 | return true; |
||||||
6336 | } |
||||||
6337 | |||||||
6338 | /** |
||||||
6339 | * It updates course relation type as EX-LEARNER if project name (extra field from user_edition_extra_field_to_check) is changed. |
||||||
6340 | * |
||||||
6341 | * @param $userId |
||||||
6342 | * @param $extraValue |
||||||
6343 | * |
||||||
6344 | * @throws \Doctrine\DBAL\Exception |
||||||
6345 | */ |
||||||
6346 | public static function updateCourseRelationTypeExLearner($userId, $extraValue) |
||||||
6347 | { |
||||||
6348 | if (false !== api_get_configuration_value('user_edition_extra_field_to_check')) { |
||||||
6349 | $extraToCheck = api_get_configuration_value('user_edition_extra_field_to_check'); |
||||||
6350 | |||||||
6351 | // Get the old user extra value to check |
||||||
6352 | $userExtra = UserManager::get_extra_user_data_by_field($userId, $extraToCheck); |
||||||
6353 | if (isset($userExtra[$extraToCheck]) && $userExtra[$extraToCheck] != $extraValue) { |
||||||
6354 | // it searchs the courses with the user old extravalue |
||||||
6355 | $extraFieldValues = new ExtraFieldValue('course'); |
||||||
6356 | $extraItems = $extraFieldValues->get_item_id_from_field_variable_and_field_value($extraToCheck, $userExtra[$extraToCheck], false, false, true); |
||||||
6357 | $coursesTocheck = []; |
||||||
6358 | if (!empty($extraItems)) { |
||||||
6359 | foreach ($extraItems as $items) { |
||||||
6360 | $coursesTocheck[] = $items['item_id']; |
||||||
6361 | } |
||||||
6362 | } |
||||||
6363 | |||||||
6364 | $tblUserGroupRelUser = Database::get_main_table(TABLE_USERGROUP_REL_USER); |
||||||
6365 | $tblUserGroupRelCourse = Database::get_main_table(TABLE_USERGROUP_REL_COURSE); |
||||||
6366 | $tblUserGroupRelSession = Database::get_main_table(TABLE_USERGROUP_REL_SESSION); |
||||||
6367 | $tblSessionUser = Database::get_main_table(TABLE_MAIN_SESSION_USER); |
||||||
6368 | $tblCourseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
||||||
6369 | |||||||
6370 | // To check in main course |
||||||
6371 | if (!empty($coursesTocheck)) { |
||||||
6372 | foreach ($coursesTocheck as $courseId) { |
||||||
6373 | $sql = "SELECT id FROM $tblCourseUser |
||||||
6374 | WHERE user_id = $userId AND c_id = $courseId"; |
||||||
6375 | $rs = Database::query($sql); |
||||||
6376 | if (Database::num_rows($rs) > 0) { |
||||||
6377 | $id = Database::result($rs, 0, 0); |
||||||
6378 | $sql = "UPDATE $tblCourseUser SET relation_type = ".COURSE_EXLEARNER." |
||||||
6379 | WHERE id = $id"; |
||||||
6380 | Database::query($sql); |
||||||
6381 | } |
||||||
6382 | } |
||||||
6383 | } |
||||||
6384 | |||||||
6385 | // To check in sessions |
||||||
6386 | if (!empty($coursesTocheck)) { |
||||||
6387 | $tblSessionCourseUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
||||||
6388 | $sessionsToCheck = []; |
||||||
6389 | foreach ($coursesTocheck as $courseId) { |
||||||
6390 | $sql = "SELECT id, session_id FROM $tblSessionCourseUser |
||||||
6391 | WHERE user_id = $userId AND c_id = $courseId"; |
||||||
6392 | $rs = Database::query($sql); |
||||||
6393 | if (Database::num_rows($rs) > 0) { |
||||||
6394 | $row = Database::fetch_array($rs); |
||||||
6395 | $id = $row['id']; |
||||||
6396 | $sessionId = $row['session_id']; |
||||||
6397 | $sql = "UPDATE $tblSessionCourseUser SET status = ".COURSE_EXLEARNER." |
||||||
6398 | WHERE id = $id"; |
||||||
6399 | Database::query($sql); |
||||||
6400 | $sessionsToCheck[] = $sessionId; |
||||||
6401 | } |
||||||
6402 | } |
||||||
6403 | // It checks if user is ex-learner in all courses in the session to update the session relation type |
||||||
6404 | if (!empty($sessionsToCheck)) { |
||||||
6405 | $sessionsToCheck = array_unique($sessionsToCheck); |
||||||
6406 | foreach ($sessionsToCheck as $sessionId) { |
||||||
6407 | $checkAll = Database::query("SELECT count(id) FROM $tblSessionCourseUser WHERE user_id = $userId AND session_id = $sessionId"); |
||||||
6408 | $countAll = Database::result($checkAll, 0, 0); |
||||||
6409 | $checkExLearner = Database::query("SELECT count(id) FROM $tblSessionCourseUser WHERE status = ".COURSE_EXLEARNER." AND user_id = $userId AND session_id = $sessionId"); |
||||||
6410 | $countExLearner = Database::result($checkExLearner, 0, 0); |
||||||
6411 | if ($countAll > 0 && $countAll == $countExLearner) { |
||||||
6412 | $sql = "UPDATE $tblSessionUser SET relation_type = ".COURSE_EXLEARNER." |
||||||
6413 | WHERE user_id = $userId AND session_id = $sessionId"; |
||||||
6414 | Database::query($sql); |
||||||
6415 | } |
||||||
6416 | } |
||||||
6417 | } |
||||||
6418 | } |
||||||
6419 | // To check users inside a class |
||||||
6420 | $rsUser = Database::query("SELECT usergroup_id FROM $tblUserGroupRelUser WHERE user_id = $userId"); |
||||||
6421 | if (Database::num_rows($rsUser) > 0) { |
||||||
6422 | while ($rowUser = Database::fetch_array($rsUser)) { |
||||||
6423 | $usergroupId = $rowUser['usergroup_id']; |
||||||
6424 | |||||||
6425 | // Count courses with exlearners |
||||||
6426 | $sqlC1 = "SELECT count(id) FROM $tblUserGroupRelCourse WHERE usergroup_id = $usergroupId"; |
||||||
6427 | $rsCourses = Database::query($sqlC1); |
||||||
6428 | $countGroupCourses = Database::result($rsCourses, 0, 0); |
||||||
6429 | |||||||
6430 | $sqlC2 = "SELECT count(cu.id) |
||||||
6431 | FROM $tblCourseUser cu |
||||||
6432 | INNER JOIN $tblUserGroupRelCourse gc |
||||||
6433 | ON gc.course_id = cu.c_id |
||||||
6434 | WHERE |
||||||
6435 | cu.user_id = $userId AND |
||||||
6436 | usergroup_id = $usergroupId AND |
||||||
6437 | relation_type = ".COURSE_EXLEARNER; |
||||||
6438 | $rsExCourses = Database::query($sqlC2); |
||||||
6439 | $countExCourses = Database::result($rsExCourses, 0, 0); |
||||||
6440 | $checkedExCourses = $countGroupCourses > 0 && ($countExCourses == $countGroupCourses); |
||||||
6441 | |||||||
6442 | // Count sessions with exlearners |
||||||
6443 | $sqlS1 = "SELECT count(id) FROM $tblUserGroupRelSession WHERE usergroup_id = $usergroupId"; |
||||||
6444 | $rsSessions = Database::query($sqlS1); |
||||||
6445 | $countGroupSessions = Database::result($rsSessions, 0, 0); |
||||||
6446 | |||||||
6447 | $sqlS2 = "SELECT count(su.id) |
||||||
6448 | FROM $tblSessionUser su |
||||||
6449 | INNER JOIN $tblUserGroupRelSession gs |
||||||
6450 | ON gs.session_id = su.session_id |
||||||
6451 | WHERE |
||||||
6452 | su.user_id = $userId AND |
||||||
6453 | usergroup_id = $usergroupId AND |
||||||
6454 | relation_type = ".COURSE_EXLEARNER; |
||||||
6455 | $rsExSessions = Database::query($sqlS2); |
||||||
6456 | $countExSessions = Database::result($rsExSessions, 0, 0); |
||||||
6457 | $checkedExSessions = $countGroupSessions > 0 && ($countExSessions == $countGroupSessions); |
||||||
6458 | |||||||
6459 | // it checks if usergroup user should be set to EXLEARNER |
||||||
6460 | $checkedExClassLearner = false; |
||||||
6461 | if ($countGroupCourses > 0 && $countGroupSessions == 0) { |
||||||
6462 | $checkedExClassLearner = $checkedExCourses; |
||||||
6463 | } elseif ($countGroupCourses == 0 && $countGroupSessions > 0) { |
||||||
6464 | $checkedExClassLearner = $checkedExSessions; |
||||||
6465 | } elseif ($countGroupCourses > 0 && $countGroupSessions > 0) { |
||||||
6466 | $checkedExClassLearner = ($checkedExCourses && $checkedExSessions); |
||||||
6467 | } |
||||||
6468 | |||||||
6469 | if ($checkedExClassLearner) { |
||||||
6470 | Database::query("UPDATE $tblUserGroupRelUser SET relation_type = ".COURSE_EXLEARNER." WHERE user_id = $userId AND usergroup_id = $usergroupId"); |
||||||
6471 | } |
||||||
6472 | } |
||||||
6473 | } |
||||||
6474 | } |
||||||
6475 | } |
||||||
6476 | } |
||||||
6477 | |||||||
6478 | /** |
||||||
6479 | * Subscribe boss to students, if $bossList is empty then the boss list will be empty too. |
||||||
6480 | * |
||||||
6481 | * @param int $studentId |
||||||
6482 | * @param array $bossList |
||||||
6483 | * @param bool $sendNotification |
||||||
6484 | * |
||||||
6485 | * @return mixed Affected rows or false on failure |
||||||
6486 | */ |
||||||
6487 | public static function subscribeUserToBossList( |
||||||
6488 | $studentId, |
||||||
6489 | $bossList, |
||||||
6490 | $sendNotification = false |
||||||
6491 | ) { |
||||||
6492 | $inserted = 0; |
||||||
6493 | if (!empty($bossList)) { |
||||||
6494 | sort($bossList); |
||||||
6495 | $studentId = (int) $studentId; |
||||||
6496 | $studentInfo = api_get_user_info($studentId); |
||||||
6497 | |||||||
6498 | if (empty($studentInfo)) { |
||||||
6499 | return false; |
||||||
6500 | } |
||||||
6501 | |||||||
6502 | $previousBossList = self::getStudentBossList($studentId); |
||||||
6503 | $previousBossList = !empty($previousBossList) ? array_column($previousBossList, 'boss_id') : []; |
||||||
6504 | sort($previousBossList); |
||||||
6505 | |||||||
6506 | // Boss list is the same, nothing changed. |
||||||
6507 | if ($bossList == $previousBossList) { |
||||||
6508 | return false; |
||||||
6509 | } |
||||||
6510 | |||||||
6511 | $userRelUserTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
||||||
6512 | self::removeAllBossFromStudent($studentId); |
||||||
6513 | |||||||
6514 | foreach ($bossList as $bossId) { |
||||||
6515 | $bossId = (int) $bossId; |
||||||
6516 | $bossInfo = api_get_user_info($bossId); |
||||||
6517 | |||||||
6518 | if (empty($bossInfo)) { |
||||||
6519 | continue; |
||||||
6520 | } |
||||||
6521 | |||||||
6522 | $bossLanguage = $bossInfo['language']; |
||||||
6523 | |||||||
6524 | $sql = "INSERT IGNORE INTO $userRelUserTable (user_id, friend_user_id, relation_type) |
||||||
6525 | VALUES ($studentId, $bossId, ".USER_RELATION_TYPE_BOSS.")"; |
||||||
6526 | $insertId = Database::query($sql); |
||||||
6527 | |||||||
6528 | if ($insertId) { |
||||||
6529 | if ($sendNotification) { |
||||||
6530 | $name = $studentInfo['complete_name']; |
||||||
6531 | $url = api_get_path(WEB_CODE_PATH).'mySpace/myStudents.php?student='.$studentId; |
||||||
6532 | $url = Display::url($url, $url); |
||||||
6533 | $subject = sprintf( |
||||||
6534 | get_lang('UserXHasBeenAssignedToBoss', false, $bossLanguage), |
||||||
6535 | $name |
||||||
6536 | ); |
||||||
6537 | $message = sprintf( |
||||||
6538 | get_lang('UserXHasBeenAssignedToBossWithUrlX', false, $bossLanguage), |
||||||
6539 | $name, |
||||||
6540 | $url |
||||||
6541 | ); |
||||||
6542 | MessageManager::send_message_simple( |
||||||
6543 | $bossId, |
||||||
6544 | $subject, |
||||||
6545 | $message |
||||||
6546 | ); |
||||||
6547 | } |
||||||
6548 | $inserted++; |
||||||
6549 | } |
||||||
6550 | } |
||||||
6551 | } else { |
||||||
6552 | self::removeAllBossFromStudent($studentId); |
||||||
6553 | } |
||||||
6554 | |||||||
6555 | return $inserted; |
||||||
6556 | } |
||||||
6557 | |||||||
6558 | /** |
||||||
6559 | * Get users followed by student boss. |
||||||
6560 | * |
||||||
6561 | * @param int $userId |
||||||
6562 | * @param int $userStatus (STUDENT, COURSEMANAGER, etc) |
||||||
6563 | * @param bool $getOnlyUserId |
||||||
6564 | * @param bool $getSql |
||||||
6565 | * @param bool $getCount |
||||||
6566 | * @param int $from |
||||||
6567 | * @param int $numberItems |
||||||
6568 | * @param int $column |
||||||
6569 | * @param string $direction |
||||||
6570 | * @param int $active |
||||||
6571 | * @param string $lastConnectionDate |
||||||
6572 | * |
||||||
6573 | * @return array users |
||||||
6574 | */ |
||||||
6575 | public static function getUsersFollowedByStudentBoss( |
||||||
6576 | $userId, |
||||||
6577 | $userStatus = 0, |
||||||
6578 | $getOnlyUserId = false, |
||||||
6579 | $getSql = false, |
||||||
6580 | $getCount = false, |
||||||
6581 | $from = null, |
||||||
6582 | $numberItems = null, |
||||||
6583 | $column = null, |
||||||
6584 | $direction = null, |
||||||
6585 | $active = null, |
||||||
6586 | $lastConnectionDate = null |
||||||
6587 | ) { |
||||||
6588 | return self::getUsersFollowedByUser( |
||||||
0 ignored issues
–
show
|
|||||||
6589 | $userId, |
||||||
6590 | $userStatus, |
||||||
6591 | $getOnlyUserId, |
||||||
6592 | $getSql, |
||||||
6593 | $getCount, |
||||||
6594 | $from, |
||||||
6595 | $numberItems, |
||||||
6596 | $column, |
||||||
6597 | $direction, |
||||||
6598 | $active, |
||||||
6599 | $lastConnectionDate, |
||||||
6600 | STUDENT_BOSS |
||||||
6601 | ); |
||||||
6602 | } |
||||||
6603 | |||||||
6604 | /** |
||||||
6605 | * @return array |
||||||
6606 | */ |
||||||
6607 | public static function getOfficialCodeGrouped() |
||||||
6608 | { |
||||||
6609 | $user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
6610 | $sql = "SELECT DISTINCT official_code |
||||||
6611 | FROM $user |
||||||
6612 | GROUP BY official_code"; |
||||||
6613 | $result = Database::query($sql); |
||||||
6614 | $values = Database::store_result($result, 'ASSOC'); |
||||||
6615 | $result = []; |
||||||
6616 | foreach ($values as $value) { |
||||||
6617 | $result[$value['official_code']] = $value['official_code']; |
||||||
6618 | } |
||||||
6619 | |||||||
6620 | return $result; |
||||||
6621 | } |
||||||
6622 | |||||||
6623 | /** |
||||||
6624 | * @param string $officialCode |
||||||
6625 | * |
||||||
6626 | * @return array |
||||||
6627 | */ |
||||||
6628 | public static function getUsersByOfficialCode($officialCode) |
||||||
6629 | { |
||||||
6630 | $user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
6631 | $officialCode = Database::escape_string($officialCode); |
||||||
6632 | |||||||
6633 | $sql = "SELECT DISTINCT id |
||||||
6634 | FROM $user |
||||||
6635 | WHERE official_code = '$officialCode' |
||||||
6636 | "; |
||||||
6637 | $result = Database::query($sql); |
||||||
6638 | |||||||
6639 | $users = []; |
||||||
6640 | while ($row = Database::fetch_array($result)) { |
||||||
6641 | $users[] = $row['id']; |
||||||
6642 | } |
||||||
6643 | |||||||
6644 | return $users; |
||||||
6645 | } |
||||||
6646 | |||||||
6647 | /** |
||||||
6648 | * Calc the expended time (in seconds) by a user in a course. |
||||||
6649 | * |
||||||
6650 | * @param int $userId The user id |
||||||
6651 | * @param int $courseId The course id |
||||||
6652 | * @param int $sessionId Optional. The session id |
||||||
6653 | * @param string $from Optional. From date |
||||||
6654 | * @param string $until Optional. Until date |
||||||
6655 | * |
||||||
6656 | * @return int The time |
||||||
6657 | */ |
||||||
6658 | public static function getTimeSpentInCourses( |
||||||
6659 | $userId, |
||||||
6660 | $courseId, |
||||||
6661 | $sessionId = 0, |
||||||
6662 | $from = '', |
||||||
6663 | $until = '' |
||||||
6664 | ) { |
||||||
6665 | $userId = (int) $userId; |
||||||
6666 | $sessionId = (int) $sessionId; |
||||||
6667 | |||||||
6668 | $trackCourseAccessTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
||||||
6669 | $whereConditions = [ |
||||||
6670 | 'user_id = ? ' => $userId, |
||||||
6671 | 'AND c_id = ? ' => $courseId, |
||||||
6672 | 'AND session_id = ? ' => $sessionId, |
||||||
6673 | ]; |
||||||
6674 | |||||||
6675 | if (!empty($from) && !empty($until)) { |
||||||
6676 | $whereConditions["AND (login_course_date >= '?' "] = $from; |
||||||
6677 | $whereConditions["AND logout_course_date <= DATE_ADD('?', INTERVAL 1 DAY)) "] = $until; |
||||||
6678 | } |
||||||
6679 | |||||||
6680 | $trackResult = Database::select( |
||||||
6681 | 'SUM(UNIX_TIMESTAMP(logout_course_date) - UNIX_TIMESTAMP(login_course_date)) as total_time', |
||||||
6682 | $trackCourseAccessTable, |
||||||
6683 | [ |
||||||
6684 | 'where' => $whereConditions, |
||||||
6685 | ], |
||||||
6686 | 'first' |
||||||
6687 | ); |
||||||
6688 | |||||||
6689 | if ($trackResult != false) { |
||||||
6690 | return $trackResult['total_time'] ? $trackResult['total_time'] : 0; |
||||||
6691 | } |
||||||
6692 | |||||||
6693 | return 0; |
||||||
6694 | } |
||||||
6695 | |||||||
6696 | /** |
||||||
6697 | * Get the boss user ID from a followed user id. |
||||||
6698 | * |
||||||
6699 | * @param $userId |
||||||
6700 | * |
||||||
6701 | * @return bool |
||||||
6702 | */ |
||||||
6703 | public static function getFirstStudentBoss($userId) |
||||||
6704 | { |
||||||
6705 | $userId = (int) $userId; |
||||||
6706 | if ($userId > 0) { |
||||||
6707 | $userRelTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
||||||
6708 | $row = Database::select( |
||||||
6709 | 'DISTINCT friend_user_id AS boss_id', |
||||||
6710 | $userRelTable, |
||||||
6711 | [ |
||||||
6712 | 'where' => [ |
||||||
6713 | 'user_id = ? AND relation_type = ? LIMIT 1' => [ |
||||||
6714 | $userId, |
||||||
6715 | USER_RELATION_TYPE_BOSS, |
||||||
6716 | ], |
||||||
6717 | ], |
||||||
6718 | ] |
||||||
6719 | ); |
||||||
6720 | if (!empty($row)) { |
||||||
6721 | return $row[0]['boss_id']; |
||||||
6722 | } |
||||||
6723 | } |
||||||
6724 | |||||||
6725 | return false; |
||||||
6726 | } |
||||||
6727 | |||||||
6728 | /** |
||||||
6729 | * Get the boss user ID from a followed user id. |
||||||
6730 | * |
||||||
6731 | * @param int $userId student id |
||||||
6732 | * |
||||||
6733 | * @return array |
||||||
6734 | */ |
||||||
6735 | public static function getStudentBossList($userId) |
||||||
6736 | { |
||||||
6737 | $userId = (int) $userId; |
||||||
6738 | |||||||
6739 | if ($userId > 0) { |
||||||
6740 | $userRelTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER); |
||||||
6741 | |||||||
6742 | return Database::select( |
||||||
6743 | 'DISTINCT friend_user_id AS boss_id', |
||||||
6744 | $userRelTable, |
||||||
6745 | [ |
||||||
6746 | 'where' => [ |
||||||
6747 | 'user_id = ? AND relation_type = ? ' => [ |
||||||
6748 | $userId, |
||||||
6749 | USER_RELATION_TYPE_BOSS, |
||||||
6750 | ], |
||||||
6751 | ], |
||||||
6752 | ] |
||||||
6753 | ); |
||||||
6754 | } |
||||||
6755 | |||||||
6756 | return []; |
||||||
6757 | } |
||||||
6758 | |||||||
6759 | /** |
||||||
6760 | * @param int $bossId |
||||||
6761 | * @param int $studentId |
||||||
6762 | * |
||||||
6763 | * @return bool |
||||||
6764 | */ |
||||||
6765 | public static function userIsBossOfStudent($bossId, $studentId) |
||||||
6766 | { |
||||||
6767 | $result = false; |
||||||
6768 | $bossList = self::getStudentBossList($studentId); |
||||||
6769 | if (!empty($bossList)) { |
||||||
6770 | $bossList = array_column($bossList, 'boss_id'); |
||||||
6771 | if (in_array($bossId, $bossList)) { |
||||||
6772 | $result = true; |
||||||
6773 | } |
||||||
6774 | } |
||||||
6775 | |||||||
6776 | return $result; |
||||||
6777 | } |
||||||
6778 | |||||||
6779 | /** |
||||||
6780 | * Displays the name of the user and makes the link to the user profile. |
||||||
6781 | * |
||||||
6782 | * @param array $userInfo |
||||||
6783 | * |
||||||
6784 | * @return string |
||||||
6785 | */ |
||||||
6786 | public static function getUserProfileLink($userInfo) |
||||||
6787 | { |
||||||
6788 | if (isset($userInfo) && isset($userInfo['user_id'])) { |
||||||
6789 | return Display::url( |
||||||
6790 | $userInfo['complete_name_with_username'], |
||||||
6791 | $userInfo['profile_url'] |
||||||
6792 | ); |
||||||
6793 | } |
||||||
6794 | |||||||
6795 | return get_lang('Anonymous'); |
||||||
6796 | } |
||||||
6797 | |||||||
6798 | /** |
||||||
6799 | * Get users whose name matches $firstname and $lastname. |
||||||
6800 | * |
||||||
6801 | * @param string $firstname Firstname to search |
||||||
6802 | * @param string $lastname Lastname to search |
||||||
6803 | * |
||||||
6804 | * @return array The user list |
||||||
6805 | */ |
||||||
6806 | public static function getUsersByName($firstname, $lastname) |
||||||
6807 | { |
||||||
6808 | $firstname = Database::escape_string($firstname); |
||||||
6809 | $lastname = Database::escape_string($lastname); |
||||||
6810 | $userTable = Database::get_main_table(TABLE_MAIN_USER); |
||||||
6811 | |||||||
6812 | $sql = <<<SQL |
||||||
6813 | SELECT id, username, lastname, firstname |
||||||
6814 | FROM $userTable |
||||||
6815 | WHERE |
||||||
6816 | firstname LIKE '$firstname%' AND |
||||||
6817 | lastname LIKE '$lastname%' |
||||||
6818 | SQL; |
||||||
6819 | $result = Database::query($sql); |
||||||
6820 | $users = []; |
||||||
6821 | while ($resultData = Database::fetch_object($result)) { |
||||||
6822 | $users[] = $resultData; |
||||||
6823 | } |
||||||
6824 | |||||||
6825 | return $users; |
||||||
6826 | } |
||||||
6827 | |||||||
6828 | /** |
||||||
6829 | * @param int $optionSelected |
||||||
6830 | * |
||||||
6831 | * @return string |
||||||
6832 | */ |
||||||
6833 | public static function getUserSubscriptionTab($optionSelected = 1) |
||||||
6834 | { |
||||||
6835 | $allowAdmin = api_get_setting('allow_user_course_subscription_by_course_admin'); |
||||||
6836 | if (($allowAdmin === 'true' && api_is_allowed_to_edit()) || |
||||||
6837 | api_is_platform_admin() |
||||||
6838 | ) { |
||||||
6839 | $userPath = api_get_path(WEB_CODE_PATH).'user/'; |
||||||
6840 | |||||||
6841 | $headers = [ |
||||||
6842 | [ |
||||||
6843 | 'url' => $userPath.'user.php?'.api_get_cidreq().'&type='.STUDENT, |
||||||
6844 | 'content' => get_lang('Students'), |
||||||
6845 | ], |
||||||
6846 | [ |
||||||
6847 | 'url' => $userPath.'user.php?'.api_get_cidreq().'&type='.COURSEMANAGER, |
||||||
6848 | 'content' => get_lang('Teachers'), |
||||||
6849 | ], |
||||||
6850 | /*[ |
||||||
6851 | 'url' => $userPath.'subscribe_user.php?'.api_get_cidreq(), |
||||||
6852 | 'content' => get_lang('Students'), |
||||||
6853 | ], |
||||||
6854 | [ |
||||||
6855 | 'url' => $userPath.'subscribe_user.php?type=teacher&'.api_get_cidreq(), |
||||||
6856 | 'content' => get_lang('Teachers'), |
||||||
6857 | ],*/ |
||||||
6858 | [ |
||||||
6859 | 'url' => api_get_path(WEB_CODE_PATH).'group/group.php?'.api_get_cidreq(), |
||||||
6860 | 'content' => get_lang('Groups'), |
||||||
6861 | ], |
||||||
6862 | 'classes' => [ |
||||||
6863 | 'url' => $userPath.'class.php?'.api_get_cidreq(), |
||||||
6864 | 'content' => get_lang('Classes'), |
||||||
6865 | ], |
||||||
6866 | ]; |
||||||
6867 | |||||||
6868 | if (api_get_configuration_value('session_classes_tab_disable') |
||||||
6869 | && !api_is_platform_admin() |
||||||
6870 | && api_get_session_id() |
||||||
6871 | ) { |
||||||
6872 | unset($headers['classes']); |
||||||
6873 | } |
||||||
6874 | |||||||
6875 | return Display::tabsOnlyLink($headers, $optionSelected); |
||||||
6876 | } |
||||||
6877 | |||||||
6878 | return ''; |
||||||
6879 | } |
||||||
6880 | |||||||
6881 | /** |
||||||
6882 | * Make sure this function is protected because it does NOT check password! |
||||||
6883 | * |
||||||
6884 | * This function defines globals. |
||||||
6885 | * |
||||||
6886 | * @param int $userId |
||||||
6887 | * @param bool $checkIfUserCanLoginAs |
||||||
6888 | * |
||||||
6889 | * @return bool |
||||||
6890 | * |
||||||
6891 | * @author Evie Embrechts |
||||||
6892 | * @author Yannick Warnier <[email protected]> |
||||||
6893 | */ |
||||||
6894 | public static function loginAsUser($userId, $checkIfUserCanLoginAs = true) |
||||||
6895 | { |
||||||
6896 | $userId = (int) $userId; |
||||||
6897 | $userInfo = api_get_user_info($userId); |
||||||
6898 | |||||||
6899 | // Check if the user is allowed to 'login_as' |
||||||
6900 | $canLoginAs = true; |
||||||
6901 | if ($checkIfUserCanLoginAs) { |
||||||
6902 | $canLoginAs = api_can_login_as($userId); |
||||||
6903 | } |
||||||
6904 | |||||||
6905 | if (!$canLoginAs || empty($userInfo)) { |
||||||
6906 | return false; |
||||||
6907 | } |
||||||
6908 | |||||||
6909 | if ($userId) { |
||||||
6910 | $logInfo = [ |
||||||
6911 | 'tool' => 'logout', |
||||||
6912 | 'tool_id' => 0, |
||||||
6913 | 'tool_id_detail' => 0, |
||||||
6914 | 'action' => '', |
||||||
6915 | 'info' => 'Change user (login as)', |
||||||
6916 | ]; |
||||||
6917 | Event::registerLog($logInfo); |
||||||
0 ignored issues
–
show
The method
registerLog() does not exist on Event .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
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.
Loading history...
|
|||||||
6918 | |||||||
6919 | // Logout the current user |
||||||
6920 | self::loginDelete(api_get_user_id()); |
||||||
6921 | |||||||
6922 | Session::erase('_user'); |
||||||
6923 | Session::erase('is_platformAdmin'); |
||||||
6924 | Session::erase('is_allowedCreateCourse'); |
||||||
6925 | Session::erase('_uid'); |
||||||
6926 | |||||||
6927 | // Cleaning session variables |
||||||
6928 | $_user['firstName'] = $userInfo['firstname']; |
||||||
6929 | $_user['lastName'] = $userInfo['lastname']; |
||||||
6930 | $_user['mail'] = $userInfo['email']; |
||||||
6931 | $_user['official_code'] = $userInfo['official_code']; |
||||||
6932 | $_user['picture_uri'] = $userInfo['picture_uri']; |
||||||
6933 | $_user['user_id'] = $userId; |
||||||
6934 | $_user['id'] = $userId; |
||||||
6935 | $_user['status'] = $userInfo['status']; |
||||||
6936 | |||||||
6937 | // Filling session variables with new data |
||||||
6938 | Session::write('_uid', $userId); |
||||||
6939 | Session::write('_user', $userInfo); |
||||||
6940 | Session::write('is_platformAdmin', (bool) self::is_admin($userId)); |
||||||
6941 | Session::write('is_allowedCreateCourse', $userInfo['status'] == 1); |
||||||
6942 | // will be useful later to know if the user is actually an admin or not (example reporting) |
||||||
6943 | Session::write('login_as', true); |
||||||
6944 | $logInfo = [ |
||||||
6945 | 'tool' => 'login', |
||||||
6946 | 'tool_id' => 0, |
||||||
6947 | 'tool_id_detail' => 0, |
||||||
6948 | 'info' => $userId, |
||||||
6949 | ]; |
||||||
6950 | Event::registerLog($logInfo); |
||||||
6951 | |||||||
6952 | return true; |
||||||
6953 | } |
||||||
6954 | |||||||
6955 | return false; |
||||||
6956 | } |
||||||
6957 | |||||||
6958 | /** |
||||||
6959 | * Remove all login records from the track_e_online stats table, |
||||||
6960 | * for the given user ID. |
||||||
6961 | * |
||||||
6962 | * @param int $userId User ID |
||||||
6963 | */ |
||||||
6964 | public static function loginDelete($userId) |
||||||
6965 | { |
||||||
6966 | $online_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE); |
||||||
6967 | $userId = (int) $userId; |
||||||
6968 | $query = "DELETE FROM $online_table WHERE login_user_id = $userId"; |
||||||
6969 | Database::query($query); |
||||||
6970 | } |
||||||
6971 | |||||||
6972 | /** |
||||||
6973 | * Login as first admin user registered in the platform. |
||||||
6974 | * |
||||||
6975 | * @return array |
||||||
6976 | */ |
||||||
6977 | public static function logInAsFirstAdmin() |
||||||
6978 | { |
||||||
6979 | $adminList = self::get_all_administrators(); |
||||||
6980 | |||||||
6981 | if (!empty($adminList)) { |
||||||
6982 | $userInfo = current($adminList); |
||||||
6983 | if (!empty($userInfo)) { |
||||||
6984 | $result = self::loginAsUser($userInfo['user_id'], false); |
||||||
6985 | if ($result && api_is_platform_admin()) { |
||||||
6986 | return api_get_user_info(); |
||||||
0 ignored issues
–
show
The expression
return api_get_user_info() could also return false which is incompatible with the documented return type array . Did you maybe forget to handle an error condition?
If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.
Loading history...
|
|||||||
6987 | } |
||||||
6988 | } |
||||||
6989 | } |
||||||
6990 | |||||||
6991 | return []; |
||||||
6992 | } |
||||||
6993 | |||||||
6994 | public static function blockIfMaxLoginAttempts(array $userInfo) |
||||||
6995 | { |
||||||
6996 | if (false === (bool) $userInfo['active'] || null === $userInfo['last_login']) { |
||||||
6997 | return; |
||||||
6998 | } |
||||||
6999 | |||||||
7000 | $maxAllowed = (int) api_get_configuration_value('login_max_attempt_before_blocking_account'); |
||||||
7001 | |||||||
7002 | if ($maxAllowed <= 0) { |
||||||
7003 | return; |
||||||
7004 | } |
||||||
7005 | |||||||
7006 | $em = Database::getManager(); |
||||||
7007 | |||||||
7008 | $countFailedAttempts = $em |
||||||
7009 | ->getRepository(TrackELoginAttempt::class) |
||||||
7010 | ->createQueryBuilder('la') |
||||||
7011 | ->select('COUNT(la)') |
||||||
7012 | ->where('la.username = :username') |
||||||
7013 | ->andWhere('la.loginDate >= :last_login') |
||||||
7014 | ->andWhere('la.success <> TRUE') |
||||||
7015 | ->setParameters( |
||||||
7016 | [ |
||||||
7017 | 'username' => $userInfo['username'], |
||||||
7018 | 'last_login' => $userInfo['last_login'], |
||||||
7019 | ] |
||||||
7020 | ) |
||||||
7021 | ->getQuery() |
||||||
7022 | ->getSingleScalarResult() |
||||||
7023 | ; |
||||||
7024 | |||||||
7025 | if ($countFailedAttempts >= $maxAllowed) { |
||||||
7026 | Database::update( |
||||||
7027 | Database::get_main_table(TABLE_MAIN_USER), |
||||||
7028 | ['active' => false], |
||||||
7029 | ['username = ?' => $userInfo['username']] |
||||||
7030 | ); |
||||||
7031 | |||||||
7032 | Display::addFlash( |
||||||
7033 | Display::return_message( |
||||||
7034 | sprintf( |
||||||
7035 | get_lang('XAccountDisabledByYAttempts'), |
||||||
7036 | $userInfo['username'], |
||||||
7037 | $countFailedAttempts |
||||||
7038 | ), |
||||||
7039 | 'error', |
||||||
7040 | false |
||||||
7041 | ) |
||||||
7042 | ); |
||||||
7043 | } |
||||||
7044 | } |
||||||
7045 | |||||||
7046 | /** |
||||||
7047 | * Check if user is teacher of a student based in their courses. |
||||||
7048 | * |
||||||
7049 | * @param $teacherId |
||||||
7050 | * @param $studentId |
||||||
7051 | * |
||||||
7052 | * @return array |
||||||
7053 | */ |
||||||
7054 | public static function getCommonCoursesBetweenTeacherAndStudent($teacherId, $studentId) |
||||||
7055 | { |
||||||
7056 | $courses = CourseManager::getCoursesFollowedByUser( |
||||||
7057 | $teacherId, |
||||||
7058 | COURSEMANAGER |
||||||
7059 | ); |
||||||
7060 | if (empty($courses)) { |
||||||
7061 | return false; |
||||||
7062 | } |
||||||
7063 | |||||||
7064 | $coursesFromUser = CourseManager::get_courses_list_by_user_id($studentId); |
||||||
7065 | if (empty($coursesFromUser)) { |
||||||
7066 | return false; |
||||||
7067 | } |
||||||
7068 | |||||||
7069 | $coursesCodeList = array_column($courses, 'code'); |
||||||
7070 | $coursesCodeFromUserList = array_column($coursesFromUser, 'code'); |
||||||
7071 | $commonCourses = array_intersect($coursesCodeList, $coursesCodeFromUserList); |
||||||
7072 | $commonCourses = array_filter($commonCourses); |
||||||
7073 | |||||||
7074 | if (!empty($commonCourses)) { |
||||||
7075 | return $commonCourses; |
||||||
7076 | } |
||||||
7077 | |||||||
7078 | return []; |
||||||
7079 | } |
||||||
7080 | |||||||
7081 | /** |
||||||
7082 | * @param int $teacherId |
||||||
7083 | * @param int $studentId |
||||||
7084 | * |
||||||
7085 | * @return bool |
||||||
7086 | */ |
||||||
7087 | public static function isTeacherOfStudent($teacherId, $studentId) |
||||||
7088 | { |
||||||
7089 | $courses = self::getCommonCoursesBetweenTeacherAndStudent( |
||||||
7090 | $teacherId, |
||||||
7091 | $studentId |
||||||
7092 | ); |
||||||
7093 | |||||||
7094 | if (!empty($courses)) { |
||||||
7095 | return true; |
||||||
7096 | } |
||||||
7097 | |||||||
7098 | return false; |
||||||
7099 | } |
||||||
7100 | |||||||
7101 | /** |
||||||
7102 | * Send user confirmation mail. |
||||||
7103 | * |
||||||
7104 | * @throws Exception |
||||||
7105 | */ |
||||||
7106 | public static function sendUserConfirmationMail(User $user) |
||||||
7107 | { |
||||||
7108 | $uniqueId = api_get_unique_id(); |
||||||
7109 | $user->setConfirmationToken($uniqueId); |
||||||
7110 | |||||||
7111 | Database::getManager()->persist($user); |
||||||
7112 | Database::getManager()->flush(); |
||||||
7113 | |||||||
7114 | $url = api_get_path(WEB_CODE_PATH).'auth/user_mail_confirmation.php?token='.$uniqueId; |
||||||
7115 | |||||||
7116 | // Check if the user was originally set for an automated subscription to a course or session |
||||||
7117 | $courseCodeToRedirect = Session::read('course_redirect'); |
||||||
7118 | $sessionToRedirect = Session::read('session_redirect'); |
||||||
7119 | if (!empty($courseCodeToRedirect)) { |
||||||
7120 | $url .= '&c='.$courseCodeToRedirect; |
||||||
7121 | } |
||||||
7122 | if (!empty($sessionToRedirect)) { |
||||||
7123 | $url .= '&s='.$sessionToRedirect; |
||||||
7124 | } |
||||||
7125 | $mailSubject = get_lang('RegistrationConfirmation'); |
||||||
7126 | $mailBody = get_lang('RegistrationConfirmationEmailMessage') |
||||||
7127 | .PHP_EOL |
||||||
7128 | .Display::url($url, $url); |
||||||
7129 | |||||||
7130 | api_mail_html( |
||||||
7131 | self::formatUserFullName($user), |
||||||
7132 | $user->getEmail(), |
||||||
7133 | $mailSubject, |
||||||
7134 | $mailBody |
||||||
7135 | ); |
||||||
7136 | Display::addFlash(Display::return_message(get_lang('CheckYourEmailAndFollowInstructions'))); |
||||||
7137 | } |
||||||
7138 | |||||||
7139 | /** |
||||||
7140 | * Anonymize a user. Replace personal info by anonymous info. |
||||||
7141 | * |
||||||
7142 | * @param int $userId User id |
||||||
7143 | * @param bool $deleteIP Whether to replace the IP address in logs tables by 127.0.0.1 or to leave as is |
||||||
7144 | * |
||||||
7145 | * @throws \Exception |
||||||
7146 | * |
||||||
7147 | * @return bool |
||||||
7148 | * @assert (0) === false |
||||||
7149 | */ |
||||||
7150 | public static function anonymize($userId, $deleteIP = true) |
||||||
7151 | { |
||||||
7152 | global $debug; |
||||||
7153 | |||||||
7154 | $userId = (int) $userId; |
||||||
7155 | |||||||
7156 | if (empty($userId)) { |
||||||
7157 | return false; |
||||||
7158 | } |
||||||
7159 | |||||||
7160 | $em = Database::getManager(); |
||||||
7161 | $user = api_get_user_entity($userId); |
||||||
7162 | $uniqueId = uniqid('anon', true); |
||||||
7163 | $user |
||||||
7164 | ->setFirstname($uniqueId) |
||||||
7165 | ->setLastname($uniqueId) |
||||||
7166 | ->setBiography('') |
||||||
7167 | ->setAddress('') |
||||||
7168 | ->setCurriculumItems(null) |
||||||
7169 | ->setDateOfBirth(null) |
||||||
7170 | ->setCompetences('') |
||||||
7171 | ->setDiplomas('') |
||||||
7172 | ->setOpenarea('') |
||||||
7173 | ->setTeach('') |
||||||
7174 | ->setProductions(null) |
||||||
7175 | ->setOpenid('') |
||||||
7176 | ->setEmailCanonical($uniqueId.'@example.com') |
||||||
7177 | ->setEmail($uniqueId.'@example.com') |
||||||
7178 | ->setUsername($uniqueId) |
||||||
7179 | ->setUsernameCanonical($uniqueId) |
||||||
7180 | ->setPhone('') |
||||||
7181 | ->setOfficialCode('') |
||||||
7182 | ; |
||||||
7183 | |||||||
7184 | self::deleteUserPicture($userId); |
||||||
7185 | self::cleanUserRequestsOfRemoval($userId); |
||||||
7186 | |||||||
7187 | // The IP address is a border-case personal data, as it does |
||||||
7188 | // not directly allow for personal identification (it is not |
||||||
7189 | // a completely safe value in most countries - the IP could |
||||||
7190 | // be used by neighbours and crackers) |
||||||
7191 | if ($deleteIP) { |
||||||
7192 | $substitute = '127.0.0.1'; |
||||||
7193 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS); |
||||||
7194 | $sql = "UPDATE $table set user_ip = '$substitute' WHERE access_user_id = $userId"; |
||||||
7195 | $res = Database::query($sql); |
||||||
7196 | if ($res === false && $debug > 0) { |
||||||
7197 | error_log("Could not anonymize IP address for user $userId ($sql)"); |
||||||
7198 | } |
||||||
7199 | |||||||
7200 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
||||||
7201 | $sql = "UPDATE $table set user_ip = '$substitute' WHERE user_id = $userId"; |
||||||
7202 | $res = Database::query($sql); |
||||||
7203 | if ($res === false && $debug > 0) { |
||||||
7204 | error_log("Could not anonymize IP address for user $userId ($sql)"); |
||||||
7205 | } |
||||||
7206 | |||||||
7207 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||||||
7208 | $sql = "UPDATE $table set user_ip = '$substitute' WHERE exe_user_id = $userId"; |
||||||
7209 | $res = Database::query($sql); |
||||||
7210 | if ($res === false && $debug > 0) { |
||||||
7211 | error_log("Could not anonymize IP address for user $userId ($sql)"); |
||||||
7212 | } |
||||||
7213 | |||||||
7214 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN); |
||||||
7215 | $sql = "UPDATE $table set user_ip = '$substitute' WHERE login_user_id = $userId"; |
||||||
7216 | $res = Database::query($sql); |
||||||
7217 | if ($res === false && $debug > 0) { |
||||||
7218 | error_log("Could not anonymize IP address for user $userId ($sql)"); |
||||||
7219 | } |
||||||
7220 | |||||||
7221 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE); |
||||||
7222 | $sql = "UPDATE $table set user_ip = '$substitute' WHERE login_user_id = $userId"; |
||||||
7223 | $res = Database::query($sql); |
||||||
7224 | if ($res === false && $debug > 0) { |
||||||
7225 | error_log("Could not anonymize IP address for user $userId ($sql)"); |
||||||
7226 | } |
||||||
7227 | |||||||
7228 | $table = Database::get_course_table(TABLE_WIKI); |
||||||
7229 | $sql = "UPDATE $table set user_ip = '$substitute' WHERE user_id = $userId"; |
||||||
7230 | $res = Database::query($sql); |
||||||
7231 | if ($res === false && $debug > 0) { |
||||||
7232 | error_log("Could not anonymize IP address for user $userId ($sql)"); |
||||||
7233 | } |
||||||
7234 | |||||||
7235 | $table = Database::get_main_table(TABLE_TICKET_MESSAGE); |
||||||
7236 | $sql = "UPDATE $table set ip_address = '$substitute' WHERE sys_insert_user_id = $userId"; |
||||||
7237 | $res = Database::query($sql); |
||||||
7238 | if ($res === false && $debug > 0) { |
||||||
7239 | error_log("Could not anonymize IP address for user $userId ($sql)"); |
||||||
7240 | } |
||||||
7241 | |||||||
7242 | $table = Database::get_course_table(TABLE_WIKI); |
||||||
7243 | $sql = "UPDATE $table set user_ip = '$substitute' WHERE user_id = $userId"; |
||||||
7244 | $res = Database::query($sql); |
||||||
7245 | if ($res === false && $debug > 0) { |
||||||
7246 | error_log("Could not anonymize IP address for user $userId ($sql)"); |
||||||
7247 | } |
||||||
7248 | } |
||||||
7249 | $em->persist($user); |
||||||
7250 | $em->flush($user); |
||||||
7251 | Event::addEvent(LOG_USER_ANONYMIZE, LOG_USER_ID, $userId); |
||||||
7252 | |||||||
7253 | return true; |
||||||
7254 | } |
||||||
7255 | |||||||
7256 | /** |
||||||
7257 | * @param int $userId |
||||||
7258 | * |
||||||
7259 | * @throws Exception |
||||||
7260 | * |
||||||
7261 | * @return string |
||||||
7262 | */ |
||||||
7263 | public static function anonymizeUserWithVerification($userId) |
||||||
7264 | { |
||||||
7265 | $allowDelete = api_get_configuration_value('allow_delete_user_for_session_admin'); |
||||||
7266 | |||||||
7267 | $message = ''; |
||||||
7268 | if (api_is_platform_admin() || |
||||||
7269 | ($allowDelete && api_is_session_admin()) |
||||||
7270 | ) { |
||||||
7271 | $userToUpdateInfo = api_get_user_info($userId); |
||||||
7272 | $currentUserId = api_get_user_id(); |
||||||
7273 | |||||||
7274 | if ($userToUpdateInfo && |
||||||
7275 | api_global_admin_can_edit_admin($userId, null, $allowDelete) |
||||||
7276 | ) { |
||||||
7277 | if ($userId != $currentUserId && |
||||||
7278 | self::anonymize($userId) |
||||||
7279 | ) { |
||||||
7280 | $message = Display::return_message( |
||||||
7281 | sprintf(get_lang('UserXAnonymized'), $userToUpdateInfo['complete_name_with_username']), |
||||||
7282 | 'confirmation' |
||||||
7283 | ); |
||||||
7284 | } else { |
||||||
7285 | $message = Display::return_message( |
||||||
7286 | sprintf(get_lang('CannotAnonymizeUserX'), $userToUpdateInfo['complete_name_with_username']), |
||||||
7287 | 'error' |
||||||
7288 | ); |
||||||
7289 | } |
||||||
7290 | } else { |
||||||
7291 | $message = Display::return_message( |
||||||
7292 | sprintf(get_lang('NoPermissionToAnonymizeUserX'), $userToUpdateInfo['complete_name_with_username']), |
||||||
7293 | 'error' |
||||||
7294 | ); |
||||||
7295 | } |
||||||
7296 | } |
||||||
7297 | |||||||
7298 | return $message; |
||||||
7299 | } |
||||||
7300 | |||||||
7301 | /** |
||||||
7302 | * @param int $userId |
||||||
7303 | * |
||||||
7304 | * @throws Exception |
||||||
7305 | * |
||||||
7306 | * @return string |
||||||
7307 | */ |
||||||
7308 | public static function deleteUserWithVerification($userId) |
||||||
7309 | { |
||||||
7310 | $allowDelete = api_get_configuration_value('allow_delete_user_for_session_admin'); |
||||||
7311 | $message = Display::return_message(get_lang('CannotDeleteUser'), 'error'); |
||||||
7312 | $userToUpdateInfo = api_get_user_info($userId); |
||||||
7313 | |||||||
7314 | // User must exist. |
||||||
7315 | if (empty($userToUpdateInfo)) { |
||||||
7316 | return $message; |
||||||
7317 | } |
||||||
7318 | |||||||
7319 | $currentUserId = api_get_user_id(); |
||||||
7320 | |||||||
7321 | // Cannot delete myself. |
||||||
7322 | if ($userId == $currentUserId) { |
||||||
7323 | return $message; |
||||||
7324 | } |
||||||
7325 | |||||||
7326 | if (api_is_platform_admin() || |
||||||
7327 | ($allowDelete && api_is_session_admin()) |
||||||
7328 | ) { |
||||||
7329 | if (api_global_admin_can_edit_admin($userId, null, $allowDelete)) { |
||||||
7330 | if (self::delete_user($userId)) { |
||||||
7331 | $message = Display::return_message( |
||||||
7332 | get_lang('UserDeleted').': '.$userToUpdateInfo['complete_name_with_username'], |
||||||
7333 | 'confirmation' |
||||||
7334 | ); |
||||||
7335 | } else { |
||||||
7336 | $message = Display::return_message(get_lang('CannotDeleteUserBecauseOwnsCourse'), 'error'); |
||||||
7337 | } |
||||||
7338 | } |
||||||
7339 | } |
||||||
7340 | |||||||
7341 | return $message; |
||||||
7342 | } |
||||||
7343 | |||||||
7344 | /** |
||||||
7345 | * @return array |
||||||
7346 | */ |
||||||
7347 | public static function createDataPrivacyExtraFields() |
||||||
7348 | { |
||||||
7349 | self::create_extra_field( |
||||||
7350 | 'request_for_legal_agreement_consent_removal_justification', |
||||||
7351 | 1, //text |
||||||
7352 | 'Request for legal agreement consent removal justification ', |
||||||
7353 | '' |
||||||
7354 | ); |
||||||
7355 | |||||||
7356 | self::create_extra_field( |
||||||
7357 | 'request_for_delete_account_justification', |
||||||
7358 | 1, //text |
||||||
7359 | 'Request for delete account justification', |
||||||
7360 | '' |
||||||
7361 | ); |
||||||
7362 | |||||||
7363 | $extraFieldId = self::create_extra_field( |
||||||
7364 | 'request_for_legal_agreement_consent_removal', |
||||||
7365 | 1, //text |
||||||
7366 | 'Request for legal agreement consent removal', |
||||||
7367 | '' |
||||||
7368 | ); |
||||||
7369 | |||||||
7370 | $extraFieldIdDeleteAccount = self::create_extra_field( |
||||||
7371 | 'request_for_delete_account', |
||||||
7372 | 1, //text |
||||||
7373 | 'Request for delete user account', |
||||||
7374 | '' |
||||||
7375 | ); |
||||||
7376 | |||||||
7377 | return [ |
||||||
7378 | 'delete_account_extra_field' => $extraFieldIdDeleteAccount, |
||||||
7379 | 'delete_legal' => $extraFieldId, |
||||||
7380 | ]; |
||||||
7381 | } |
||||||
7382 | |||||||
7383 | /** |
||||||
7384 | * @param int $userId |
||||||
7385 | */ |
||||||
7386 | public static function cleanUserRequestsOfRemoval($userId) |
||||||
7387 | { |
||||||
7388 | $userId = (int) $userId; |
||||||
7389 | |||||||
7390 | $extraFieldValue = new ExtraFieldValue('user'); |
||||||
7391 | $extraFieldsToDelete = [ |
||||||
7392 | 'legal_accept', |
||||||
7393 | 'request_for_legal_agreement_consent_removal', |
||||||
7394 | 'request_for_legal_agreement_consent_removal_justification', |
||||||
7395 | 'request_for_delete_account_justification', // just in case delete also this |
||||||
7396 | 'request_for_delete_account', |
||||||
7397 | ]; |
||||||
7398 | |||||||
7399 | foreach ($extraFieldsToDelete as $variable) { |
||||||
7400 | $value = $extraFieldValue->get_values_by_handler_and_field_variable( |
||||||
7401 | $userId, |
||||||
7402 | $variable |
||||||
7403 | ); |
||||||
7404 | if ($value && isset($value['id'])) { |
||||||
7405 | $extraFieldValue->delete($value['id']); |
||||||
7406 | } |
||||||
7407 | } |
||||||
7408 | } |
||||||
7409 | |||||||
7410 | /** |
||||||
7411 | * @param int $searchYear |
||||||
7412 | * |
||||||
7413 | * @throws Exception |
||||||
7414 | * |
||||||
7415 | * @return array |
||||||
7416 | */ |
||||||
7417 | public static function getSubscribedSessionsByYear(array $userInfo, $searchYear) |
||||||
7418 | { |
||||||
7419 | $timezone = new DateTimeZone(api_get_timezone()); |
||||||
7420 | |||||||
7421 | $sessions = []; |
||||||
7422 | if (DRH == $userInfo['status']) { |
||||||
7423 | $sessions = SessionManager::get_sessions_followed_by_drh($userInfo['id']); |
||||||
7424 | } elseif (api_is_platform_admin(true)) { |
||||||
7425 | $sessions = SessionManager::getSessionsForAdmin($userInfo['id']); |
||||||
7426 | } else { |
||||||
7427 | $sessionsByCategory = self::get_sessions_by_category($userInfo['id'], false, true, true); |
||||||
7428 | $sessionsByCategory = array_column($sessionsByCategory, 'sessions'); |
||||||
7429 | |||||||
7430 | foreach ($sessionsByCategory as $sessionsInCategory) { |
||||||
7431 | $sessions = array_merge($sessions, $sessionsInCategory); |
||||||
7432 | } |
||||||
7433 | } |
||||||
7434 | |||||||
7435 | $sessions = array_map( |
||||||
7436 | function ($sessionInfo) { |
||||||
7437 | if (!isset($sessionInfo['session_id'])) { |
||||||
7438 | $sessionInfo['session_id'] = $sessionInfo['id']; |
||||||
7439 | } |
||||||
7440 | if (!isset($sessionInfo['session_name'])) { |
||||||
7441 | $sessionInfo['session_name'] = $sessionInfo['name']; |
||||||
7442 | } |
||||||
7443 | |||||||
7444 | return $sessionInfo; |
||||||
7445 | }, |
||||||
7446 | $sessions |
||||||
7447 | ); |
||||||
7448 | |||||||
7449 | $calendarSessions = []; |
||||||
7450 | |||||||
7451 | foreach ($sessions as $sessionInfo) { |
||||||
7452 | if (!empty($sessionInfo['duration'])) { |
||||||
7453 | $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser( |
||||||
7454 | $sessionInfo['session_id'], |
||||||
7455 | $userInfo['id'] |
||||||
7456 | ); |
||||||
7457 | |||||||
7458 | if (empty($courseAccess)) { |
||||||
7459 | continue; |
||||||
7460 | } |
||||||
7461 | |||||||
7462 | $firstAcessDate = new DateTime(api_get_local_time($courseAccess['login_course_date']), $timezone); |
||||||
7463 | $lastAccessDate = clone $firstAcessDate; |
||||||
7464 | $lastAccessDate->modify("+{$sessionInfo['duration']} days"); |
||||||
7465 | |||||||
7466 | $firstAccessYear = (int) $firstAcessDate->format('Y'); |
||||||
7467 | $lastAccessYear = (int) $lastAccessDate->format('Y'); |
||||||
7468 | |||||||
7469 | if ($firstAccessYear <= $searchYear && $lastAccessYear >= $searchYear) { |
||||||
7470 | $calendarSessions[$sessionInfo['session_id']] = [ |
||||||
7471 | 'name' => $sessionInfo['session_name'], |
||||||
7472 | 'access_start_date' => $firstAcessDate->format('Y-m-d h:i:s'), |
||||||
7473 | 'access_end_date' => $lastAccessDate->format('Y-m-d h:i:s'), |
||||||
7474 | ]; |
||||||
7475 | } |
||||||
7476 | |||||||
7477 | continue; |
||||||
7478 | } |
||||||
7479 | |||||||
7480 | $accessStartDate = !empty($sessionInfo['access_start_date']) |
||||||
7481 | ? new DateTime(api_get_local_time($sessionInfo['access_start_date']), $timezone) |
||||||
7482 | : null; |
||||||
7483 | $accessEndDate = !empty($sessionInfo['access_end_date']) |
||||||
7484 | ? new DateTime(api_get_local_time($sessionInfo['access_end_date']), $timezone) |
||||||
7485 | : null; |
||||||
7486 | $accessStartYear = $accessStartDate ? (int) $accessStartDate->format('Y') : 0; |
||||||
7487 | $accessEndYear = $accessEndDate ? (int) $accessEndDate->format('Y') : 0; |
||||||
7488 | |||||||
7489 | $isValid = false; |
||||||
7490 | |||||||
7491 | if ($accessStartYear && $accessEndYear) { |
||||||
7492 | if ($accessStartYear <= $searchYear && $accessEndYear >= $searchYear) { |
||||||
7493 | $isValid = true; |
||||||
7494 | } |
||||||
7495 | } |
||||||
7496 | |||||||
7497 | if ($accessStartYear && !$accessEndYear) { |
||||||
7498 | if ($accessStartYear == $searchYear) { |
||||||
7499 | $isValid = true; |
||||||
7500 | } |
||||||
7501 | } |
||||||
7502 | |||||||
7503 | if (!$accessStartYear && $accessEndYear) { |
||||||
7504 | if ($accessEndYear == $searchYear) { |
||||||
7505 | $isValid = true; |
||||||
7506 | } |
||||||
7507 | } |
||||||
7508 | |||||||
7509 | if ($isValid) { |
||||||
7510 | $calendarSessions[$sessionInfo['session_id']] = [ |
||||||
7511 | 'name' => $sessionInfo['session_name'], |
||||||
7512 | 'access_start_date' => $accessStartDate ? $accessStartDate->format('Y-m-d h:i:s') : null, |
||||||
7513 | 'access_end_date' => $accessEndDate ? $accessEndDate->format('Y-m-d h:i:s') : null, |
||||||
7514 | ]; |
||||||
7515 | } |
||||||
7516 | } |
||||||
7517 | |||||||
7518 | return $calendarSessions; |
||||||
7519 | } |
||||||
7520 | |||||||
7521 | /** |
||||||
7522 | * Get sessions info for planification calendar. |
||||||
7523 | * |
||||||
7524 | * @param array $sessionsList Session list from UserManager::getSubscribedSessionsByYear |
||||||
7525 | * @param int $searchYear |
||||||
7526 | * |
||||||
7527 | * @throws Exception |
||||||
7528 | * |
||||||
7529 | * @return array |
||||||
7530 | */ |
||||||
7531 | public static function getSessionsCalendarByYear(array $sessionsList, $searchYear) |
||||||
7532 | { |
||||||
7533 | $timezone = new DateTimeZone(api_get_timezone()); |
||||||
7534 | $calendar = []; |
||||||
7535 | |||||||
7536 | foreach ($sessionsList as $sessionId => $sessionInfo) { |
||||||
7537 | $startDate = $sessionInfo['access_start_date'] |
||||||
7538 | ? new DateTime(api_get_local_time($sessionInfo['access_start_date']), $timezone) |
||||||
7539 | : null; |
||||||
7540 | $endDate = $sessionInfo['access_end_date'] |
||||||
7541 | ? new DateTime(api_get_local_time($sessionInfo['access_end_date']), $timezone) |
||||||
7542 | : null; |
||||||
7543 | |||||||
7544 | $startYear = $startDate ? (int) $startDate->format('Y') : 0; |
||||||
7545 | $startWeekYear = $startDate ? (int) $startDate->format('o') : 0; |
||||||
7546 | $startWeek = $startDate ? (int) $startDate->format('W') : 0; |
||||||
7547 | $endYear = $endDate ? (int) $endDate->format('Y') : 0; |
||||||
7548 | $endWeekYear = $endDate ? (int) $endDate->format('o') : 0; |
||||||
7549 | $endWeek = $endDate ? (int) $endDate->format('W') : 0; |
||||||
7550 | |||||||
7551 | $start = $startWeekYear < $searchYear ? 0 : $startWeek - 1; |
||||||
7552 | $duration = $endWeekYear > $searchYear ? 52 - $start : $endWeek - $start; |
||||||
7553 | |||||||
7554 | $calendar[] = [ |
||||||
7555 | 'id' => $sessionId, |
||||||
7556 | 'name' => $sessionInfo['name'], |
||||||
7557 | 'human_date' => SessionManager::convertSessionDateToString($startDate, $endDate, false, true), |
||||||
7558 | 'start_in_last_year' => $startYear < $searchYear, |
||||||
7559 | 'end_in_next_year' => $endYear > $searchYear, |
||||||
7560 | 'no_start' => !$startWeek, |
||||||
7561 | 'no_end' => !$endWeek, |
||||||
7562 | 'start' => $start, |
||||||
7563 | 'duration' => $duration > 0 ? $duration : 1, |
||||||
7564 | ]; |
||||||
7565 | } |
||||||
7566 | |||||||
7567 | usort( |
||||||
7568 | $calendar, |
||||||
7569 | function ($sA, $sB) { |
||||||
7570 | if ($sA['start'] == $sB['start']) { |
||||||
7571 | return 0; |
||||||
7572 | } |
||||||
7573 | |||||||
7574 | if ($sA['start'] < $sB['start']) { |
||||||
7575 | return -1; |
||||||
7576 | } |
||||||
7577 | |||||||
7578 | return 1; |
||||||
7579 | } |
||||||
7580 | ); |
||||||
7581 | |||||||
7582 | return $calendar; |
||||||
7583 | } |
||||||
7584 | |||||||
7585 | /** |
||||||
7586 | * Return the user's full name. Optionally with the username. |
||||||
7587 | * |
||||||
7588 | * @param bool $includeUsername Optional. By default username is not included. |
||||||
7589 | * |
||||||
7590 | * @return string |
||||||
7591 | */ |
||||||
7592 | public static function formatUserFullName(User $user, $includeUsername = false) |
||||||
7593 | { |
||||||
7594 | $fullName = api_get_person_name($user->getFirstname(), $user->getLastname()); |
||||||
7595 | |||||||
7596 | if ($includeUsername && api_get_configuration_value('hide_username_with_complete_name') !== true) { |
||||||
7597 | $username = $user->getUsername(); |
||||||
7598 | |||||||
7599 | return "$fullName ($username)"; |
||||||
7600 | } |
||||||
7601 | |||||||
7602 | return $fullName; |
||||||
7603 | } |
||||||
7604 | |||||||
7605 | /** |
||||||
7606 | * @param int $userId |
||||||
7607 | * |
||||||
7608 | * @return array |
||||||
7609 | */ |
||||||
7610 | public static function getUserCareers($userId) |
||||||
7611 | { |
||||||
7612 | $table = Database::get_main_table(TABLE_MAIN_USER_CAREER); |
||||||
7613 | $tableCareer = Database::get_main_table(TABLE_CAREER); |
||||||
7614 | $userId = (int) $userId; |
||||||
7615 | |||||||
7616 | $sql = "SELECT c.id, c.name |
||||||
7617 | FROM $table uc |
||||||
7618 | INNER JOIN $tableCareer c |
||||||
7619 | ON uc.career_id = c.id |
||||||
7620 | WHERE user_id = $userId |
||||||
7621 | ORDER BY uc.created_at |
||||||
7622 | "; |
||||||
7623 | $result = Database::query($sql); |
||||||
7624 | |||||||
7625 | return Database::store_result($result, 'ASSOC'); |
||||||
7626 | } |
||||||
7627 | |||||||
7628 | /** |
||||||
7629 | * @param int $userId |
||||||
7630 | * @param int $careerId |
||||||
7631 | */ |
||||||
7632 | public static function addUserCareer($userId, $careerId) |
||||||
7633 | { |
||||||
7634 | if (!api_get_configuration_value('allow_career_users')) { |
||||||
7635 | return false; |
||||||
7636 | } |
||||||
7637 | |||||||
7638 | if (self::userHasCareer($userId, $careerId) === false) { |
||||||
7639 | $params = [ |
||||||
7640 | 'user_id' => $userId, |
||||||
7641 | 'career_id' => $careerId, |
||||||
7642 | 'created_at' => api_get_utc_datetime(), |
||||||
7643 | 'updated_at' => api_get_utc_datetime(), |
||||||
7644 | ]; |
||||||
7645 | $table = Database::get_main_table(TABLE_MAIN_USER_CAREER); |
||||||
7646 | Database::insert($table, $params); |
||||||
7647 | } |
||||||
7648 | |||||||
7649 | return true; |
||||||
7650 | } |
||||||
7651 | |||||||
7652 | /** |
||||||
7653 | * @param int $userCareerId |
||||||
7654 | * @param array $data |
||||||
7655 | * |
||||||
7656 | * @return bool |
||||||
7657 | */ |
||||||
7658 | public static function updateUserCareer($userCareerId, $data) |
||||||
7659 | { |
||||||
7660 | if (!api_get_configuration_value('allow_career_users')) { |
||||||
7661 | return false; |
||||||
7662 | } |
||||||
7663 | |||||||
7664 | $params = ['extra_data' => $data, 'updated_at' => api_get_utc_datetime()]; |
||||||
7665 | $table = Database::get_main_table(TABLE_MAIN_USER_CAREER); |
||||||
7666 | Database::update( |
||||||
7667 | $table, |
||||||
7668 | $params, |
||||||
7669 | ['id = ?' => (int) $userCareerId] |
||||||
7670 | ); |
||||||
7671 | |||||||
7672 | return true; |
||||||
7673 | } |
||||||
7674 | |||||||
7675 | /** |
||||||
7676 | * @param int $userId |
||||||
7677 | * @param int $careerId |
||||||
7678 | * |
||||||
7679 | * @return array |
||||||
7680 | */ |
||||||
7681 | public static function getUserCareer($userId, $careerId) |
||||||
7682 | { |
||||||
7683 | $userId = (int) $userId; |
||||||
7684 | $careerId = (int) $careerId; |
||||||
7685 | $table = Database::get_main_table(TABLE_MAIN_USER_CAREER); |
||||||
7686 | |||||||
7687 | $sql = "SELECT * FROM $table WHERE user_id = $userId AND career_id = $careerId"; |
||||||
7688 | $result = Database::query($sql); |
||||||
7689 | |||||||
7690 | return Database::fetch_array($result, 'ASSOC'); |
||||||
7691 | } |
||||||
7692 | |||||||
7693 | /** |
||||||
7694 | * @param int $userId |
||||||
7695 | * @param int $careerId |
||||||
7696 | * |
||||||
7697 | * @return bool |
||||||
7698 | */ |
||||||
7699 | public static function userHasCareer($userId, $careerId) |
||||||
7700 | { |
||||||
7701 | $userId = (int) $userId; |
||||||
7702 | $careerId = (int) $careerId; |
||||||
7703 | $table = Database::get_main_table(TABLE_MAIN_USER_CAREER); |
||||||
7704 | |||||||
7705 | $sql = "SELECT id FROM $table WHERE user_id = $userId AND career_id = $careerId"; |
||||||
7706 | $result = Database::query($sql); |
||||||
7707 | |||||||
7708 | return Database::num_rows($result) > 0; |
||||||
7709 | } |
||||||
7710 | |||||||
7711 | /** |
||||||
7712 | * @param int $userId |
||||||
7713 | * |
||||||
7714 | * @throws Exception |
||||||
7715 | */ |
||||||
7716 | public static function deleteUserFiles($userId) |
||||||
7717 | { |
||||||
7718 | $path = self::getUserPathById($userId, 'system'); |
||||||
7719 | |||||||
7720 | $fs = new Filesystem(); |
||||||
7721 | $fs->remove($path); |
||||||
7722 | } |
||||||
7723 | |||||||
7724 | public static function redirectToResetPassword($userId) |
||||||
7725 | { |
||||||
7726 | $forceRenew = api_get_configuration_value('force_renew_password_at_first_login'); |
||||||
7727 | |||||||
7728 | if ($forceRenew) { |
||||||
7729 | $askPassword = self::get_extra_user_data_by_field( |
||||||
7730 | $userId, |
||||||
7731 | 'ask_new_password' |
||||||
7732 | ); |
||||||
7733 | |||||||
7734 | if (!empty($askPassword) && isset($askPassword['ask_new_password']) && |
||||||
7735 | 1 === (int) $askPassword['ask_new_password'] |
||||||
7736 | ) { |
||||||
7737 | $uniqueId = api_get_unique_id(); |
||||||
7738 | $userObj = api_get_user_entity($userId); |
||||||
7739 | |||||||
7740 | $userObj->setConfirmationToken($uniqueId); |
||||||
7741 | $userObj->setPasswordRequestedAt(new \DateTime()); |
||||||
7742 | |||||||
7743 | Database::getManager()->persist($userObj); |
||||||
7744 | Database::getManager()->flush(); |
||||||
7745 | |||||||
7746 | $url = api_get_path(WEB_CODE_PATH).'auth/reset.php?token='.$uniqueId; |
||||||
7747 | api_location($url); |
||||||
7748 | } |
||||||
7749 | } |
||||||
7750 | |||||||
7751 | $forceRotateDays = api_get_configuration_value('security_password_rotate_days'); |
||||||
7752 | $forceRotate = false; |
||||||
7753 | |||||||
7754 | if ($forceRotateDays > 0) { |
||||||
7755 | // get the date of the last password update recorded |
||||||
7756 | $lastUpdate = self::get_extra_user_data_by_field( |
||||||
7757 | $userId, |
||||||
7758 | 'password_updated_at' |
||||||
7759 | ); |
||||||
7760 | |||||||
7761 | if (empty($lastUpdate) or empty($lastUpdate['password_updated_at'])) { |
||||||
7762 | $userObj = api_get_user_entity($userId); |
||||||
7763 | $registrationDate = $userObj->getRegistrationDate(); |
||||||
7764 | $now = new \DateTime(null, new DateTimeZone('UTC')); |
||||||
7765 | $interval = $now->diff($registrationDate); |
||||||
7766 | $daysSince = $interval->format('%a'); |
||||||
7767 | if ($daysSince > $forceRotateDays) { |
||||||
7768 | $forceRotate = true; |
||||||
7769 | } |
||||||
7770 | } else { |
||||||
7771 | $now = new \DateTime(null, new DateTimeZone('UTC')); |
||||||
7772 | // In some cases, old records might contain an incomplete Y-m-d H:i:s format |
||||||
7773 | if (strlen($lastUpdate['password_updated_at']) == 10) { |
||||||
7774 | $lastUpdate['password_updated_at'] .= ' 00:00:00'; |
||||||
7775 | } |
||||||
7776 | if (strlen($lastUpdate['password_updated_at']) == 16) { |
||||||
7777 | $lastUpdate['password_updated_at'] .= ':00'; |
||||||
7778 | } |
||||||
7779 | $date = \DateTime::createFromFormat('Y-m-d H:i:s', $lastUpdate['password_updated_at'], new DateTimeZone('UTC')); |
||||||
7780 | $interval = $now->diff($date); |
||||||
7781 | $daysSince = $interval->format('%a'); |
||||||
7782 | if ($daysSince > $forceRotateDays) { |
||||||
7783 | $forceRotate = true; |
||||||
7784 | } |
||||||
7785 | } |
||||||
7786 | if ($forceRotate) { |
||||||
7787 | $uniqueId = api_get_unique_id(); |
||||||
7788 | $userObj = api_get_user_entity($userId); |
||||||
7789 | |||||||
7790 | $userObj->setConfirmationToken($uniqueId); |
||||||
7791 | $userObj->setPasswordRequestedAt(new \DateTime()); |
||||||
7792 | |||||||
7793 | Database::getManager()->persist($userObj); |
||||||
7794 | Database::getManager()->flush(); |
||||||
7795 | |||||||
7796 | $url = api_get_path(WEB_CODE_PATH).'auth/reset.php?token='.$uniqueId.'&rotate=1'; |
||||||
7797 | api_location($url); |
||||||
7798 | } |
||||||
7799 | } |
||||||
7800 | } |
||||||
7801 | |||||||
7802 | /** |
||||||
7803 | * It returns the list of user status available. |
||||||
7804 | * |
||||||
7805 | * @return array |
||||||
7806 | */ |
||||||
7807 | public static function getUserStatusList() |
||||||
7808 | { |
||||||
7809 | $userStatusConfig = []; |
||||||
7810 | // it gets the roles to show in creation/edition user |
||||||
7811 | if (true === api_get_configuration_value('user_status_show_options_enabled')) { |
||||||
7812 | $userStatusConfig = api_get_configuration_value('user_status_show_option'); |
||||||
7813 | } |
||||||
7814 | // it gets the roles to show in creation/edition user (only for admins) |
||||||
7815 | if (true === api_get_configuration_value('user_status_option_only_for_admin_enabled') && api_is_platform_admin()) { |
||||||
7816 | $userStatusConfig = api_get_configuration_value('user_status_option_show_only_for_admin'); |
||||||
7817 | } |
||||||
7818 | |||||||
7819 | $status = []; |
||||||
7820 | if (!empty($userStatusConfig)) { |
||||||
7821 | $statusLang = api_get_status_langvars(); |
||||||
7822 | foreach ($userStatusConfig as $role => $enabled) { |
||||||
7823 | if ($enabled) { |
||||||
7824 | $constStatus = constant($role); |
||||||
7825 | $status[$constStatus] = $statusLang[$constStatus]; |
||||||
7826 | } |
||||||
7827 | } |
||||||
7828 | } else { |
||||||
7829 | $status[COURSEMANAGER] = get_lang('Teacher'); |
||||||
7830 | $status[STUDENT] = get_lang('Learner'); |
||||||
7831 | $status[DRH] = get_lang('Drh'); |
||||||
7832 | $status[SESSIONADMIN] = get_lang('SessionsAdmin'); |
||||||
7833 | $status[STUDENT_BOSS] = get_lang('RoleStudentBoss'); |
||||||
7834 | $status[INVITEE] = get_lang('Invitee'); |
||||||
7835 | } |
||||||
7836 | |||||||
7837 | return $status; |
||||||
7838 | } |
||||||
7839 | |||||||
7840 | /** |
||||||
7841 | * Get the expiration date by user status from configuration value. |
||||||
7842 | * |
||||||
7843 | * @param $status |
||||||
7844 | * |
||||||
7845 | * @throws Exception |
||||||
7846 | * |
||||||
7847 | * @return array |
||||||
7848 | */ |
||||||
7849 | public static function getExpirationDateByRole($status) |
||||||
7850 | { |
||||||
7851 | $status = (int) $status; |
||||||
7852 | $nbDaysByRole = api_get_configuration_value('user_number_of_days_for_default_expiration_date_per_role'); |
||||||
7853 | $dates = []; |
||||||
7854 | if (!empty($nbDaysByRole)) { |
||||||
7855 | $date = new DateTime(); |
||||||
7856 | foreach ($nbDaysByRole as $strVariable => $nDays) { |
||||||
7857 | $constStatus = constant($strVariable); |
||||||
7858 | if ($status == $constStatus) { |
||||||
7859 | $duration = "P{$nDays}D"; |
||||||
7860 | $date->add(new DateInterval($duration)); |
||||||
7861 | $newExpirationDate = $date->format('Y-m-d H:i'); |
||||||
7862 | $formatted = api_format_date($newExpirationDate, DATE_TIME_FORMAT_LONG_24H); |
||||||
7863 | $dates = ['formatted' => $formatted, 'date' => $newExpirationDate]; |
||||||
7864 | } |
||||||
7865 | } |
||||||
7866 | } |
||||||
7867 | |||||||
7868 | return $dates; |
||||||
7869 | } |
||||||
7870 | |||||||
7871 | public static function getAllowedRolesAsTeacher(): array |
||||||
7872 | { |
||||||
7873 | if (api_get_configuration_value('course_allow_student_role_to_be_teacher')) { |
||||||
7874 | return [ |
||||||
7875 | STUDENT, |
||||||
7876 | COURSEMANAGER, |
||||||
7877 | SESSIONADMIN, |
||||||
7878 | ]; |
||||||
7879 | } else { |
||||||
7880 | return [ |
||||||
7881 | COURSEMANAGER, |
||||||
7882 | SESSIONADMIN, |
||||||
7883 | ]; |
||||||
7884 | } |
||||||
7885 | } |
||||||
7886 | |||||||
7887 | /** |
||||||
7888 | * Count users in courses and if they have certificate. |
||||||
7889 | * This function is resource intensive. |
||||||
7890 | * |
||||||
7891 | * @return array |
||||||
7892 | */ |
||||||
7893 | public static function countUsersWhoFinishedCourses() |
||||||
7894 | { |
||||||
7895 | $courses = []; |
||||||
7896 | $currentAccessUrlId = api_get_current_access_url_id(); |
||||||
7897 | $sql = "SELECT course.code, cru.user_id |
||||||
7898 | FROM course_rel_user cru |
||||||
7899 | JOIN course ON cru.c_id = course.id |
||||||
7900 | JOIN access_url_rel_user auru on cru.user_id = auru.user_id |
||||||
7901 | JOIN access_url_rel_course ON course.id = access_url_rel_course.c_id |
||||||
7902 | WHERE access_url_rel_course.access_url_id = $currentAccessUrlId |
||||||
7903 | ORDER BY course.code |
||||||
7904 | "; |
||||||
7905 | |||||||
7906 | $res = Database::query($sql); |
||||||
7907 | if (Database::num_rows($res) > 0) { |
||||||
7908 | while ($row = Database::fetch_array($res)) { |
||||||
7909 | if (!isset($courses[$row['code']])) { |
||||||
7910 | $courses[$row['code']] = [ |
||||||
7911 | 'subscribed' => 0, |
||||||
7912 | 'finished' => 0, |
||||||
7913 | ]; |
||||||
7914 | } |
||||||
7915 | |||||||
7916 | $courses[$row['code']]['subscribed']++; |
||||||
7917 | $entityManager = Database::getManager(); |
||||||
7918 | $repository = $entityManager->getRepository('ChamiloCoreBundle:GradebookCategory'); |
||||||
7919 | //todo check when have more than 1 gradebook |
||||||
7920 | /** @var \Chamilo\CoreBundle\Entity\GradebookCategory $gradebook */ |
||||||
7921 | $gradebook = $repository->findOneBy(['courseCode' => $row['code']]); |
||||||
7922 | |||||||
7923 | if (!empty($gradebook)) { |
||||||
7924 | $finished = 0; |
||||||
7925 | $gb = Category::createCategoryObjectFromEntity($gradebook); |
||||||
7926 | $finished = $gb->is_certificate_available($row['user_id']); |
||||||
7927 | if (!empty($finished)) { |
||||||
7928 | $courses[$row['code']]['finished']++; |
||||||
7929 | } |
||||||
7930 | } |
||||||
7931 | } |
||||||
7932 | } |
||||||
7933 | |||||||
7934 | return $courses; |
||||||
7935 | } |
||||||
7936 | |||||||
7937 | /** |
||||||
7938 | * Count users in sessions and if they have certificate. |
||||||
7939 | * This function is resource intensive. |
||||||
7940 | * |
||||||
7941 | * @return array |
||||||
7942 | */ |
||||||
7943 | public static function countUsersWhoFinishedCoursesInSessions() |
||||||
7944 | { |
||||||
7945 | $coursesInSessions = []; |
||||||
7946 | $currentAccessUrlId = api_get_current_access_url_id(); |
||||||
7947 | $sql = "SELECT course.code, srcru.session_id, srcru.user_id, session.name |
||||||
7948 | FROM session_rel_course_rel_user srcru |
||||||
7949 | JOIN course ON srcru.c_id = course.id |
||||||
7950 | JOIN access_url_rel_session aurs on srcru.session_id = aurs.session_id |
||||||
7951 | JOIN session ON srcru.session_id = session.id |
||||||
7952 | WHERE aurs.access_url_id = $currentAccessUrlId |
||||||
7953 | ORDER BY course.code, session.name |
||||||
7954 | "; |
||||||
7955 | |||||||
7956 | $res = Database::query($sql); |
||||||
7957 | if (Database::num_rows($res) > 0) { |
||||||
7958 | while ($row = Database::fetch_array($res)) { |
||||||
7959 | $index = $row['code'].' ('.$row['name'].')'; |
||||||
7960 | if (!isset($coursesInSessions[$index])) { |
||||||
7961 | $coursesInSessions[$index] = [ |
||||||
7962 | 'subscribed' => 0, |
||||||
7963 | 'finished' => 0, |
||||||
7964 | ]; |
||||||
7965 | } |
||||||
7966 | |||||||
7967 | $coursesInSessions[$index]['subscribed']++; |
||||||
7968 | $entityManager = Database::getManager(); |
||||||
7969 | $repository = $entityManager->getRepository('ChamiloCoreBundle:GradebookCategory'); |
||||||
7970 | /** @var \Chamilo\CoreBundle\Entity\GradebookCategory $gradebook */ |
||||||
7971 | $gradebook = $repository->findOneBy( |
||||||
7972 | [ |
||||||
7973 | 'courseCode' => $row['code'], |
||||||
7974 | 'sessionId' => $row['session_id'], |
||||||
7975 | ] |
||||||
7976 | ); |
||||||
7977 | |||||||
7978 | if (!empty($gradebook)) { |
||||||
7979 | $finished = 0; |
||||||
7980 | $gb = Category::createCategoryObjectFromEntity($gradebook); |
||||||
7981 | $finished = $gb->is_certificate_available($row['user_id']); |
||||||
7982 | if (!empty($finished)) { |
||||||
7983 | $coursesInSessions[$index]['finished']++; |
||||||
7984 | } |
||||||
7985 | } |
||||||
7986 | } |
||||||
7987 | } |
||||||
7988 | |||||||
7989 | return $coursesInSessions; |
||||||
7990 | } |
||||||
7991 | |||||||
7992 | /** |
||||||
7993 | * Build the active-column of the table to lock or unlock a certain user |
||||||
7994 | * lock = the user can no longer use this account. |
||||||
7995 | * |
||||||
7996 | * @author Patrick Cool <[email protected]>, Ghent University |
||||||
7997 | * |
||||||
7998 | * @return string Some HTML-code with the lock/unlock button |
||||||
7999 | */ |
||||||
8000 | public static function getActiveFilterForTable(string $active, string $params, array $row): string |
||||||
8001 | { |
||||||
8002 | if ('1' == $active) { |
||||||
8003 | $action = 'Lock'; |
||||||
8004 | $image = 'accept'; |
||||||
8005 | } elseif ('-1' == $active) { |
||||||
8006 | $action = 'edit'; |
||||||
8007 | $image = 'warning'; |
||||||
8008 | } elseif ('0' == $active) { |
||||||
8009 | $action = 'Unlock'; |
||||||
8010 | $image = 'error'; |
||||||
8011 | } |
||||||
8012 | |||||||
8013 | if ('edit' === $action) { |
||||||
8014 | $langAccountExpired = get_lang('AccountExpired'); |
||||||
8015 | |||||||
8016 | return Display::return_icon( |
||||||
8017 | $image.'.png', |
||||||
8018 | $langAccountExpired, |
||||||
8019 | [], |
||||||
8020 | ICON_SIZE_TINY |
||||||
8021 | ).'<span class="sr-only" aria-hidden="true">'.$langAccountExpired.'</span>'; |
||||||
8022 | } |
||||||
8023 | |||||||
8024 | if ($row['0'] != api_get_user_id()) { |
||||||
8025 | $langAction = get_lang(ucfirst($action)); |
||||||
8026 | // you cannot lock yourself out otherwise you could disable all the |
||||||
8027 | // accounts including your own => everybody is locked out and nobody |
||||||
8028 | // can change it anymore. |
||||||
8029 | return Display::return_icon( |
||||||
8030 | $image.'.png', |
||||||
8031 | $langAction, |
||||||
8032 | ['onclick' => 'active_user(this);', 'id' => 'img_'.$row['0'], 'style' => 'cursor: pointer;'], |
||||||
8033 | ICON_SIZE_TINY |
||||||
8034 | ).'<span class="sr-only" aria-hidden="true">'.$langAction.'</span>'; |
||||||
8035 | } |
||||||
8036 | |||||||
8037 | return ''; |
||||||
8038 | } |
||||||
8039 | |||||||
8040 | public static function getScriptFunctionForActiveFilter(): string |
||||||
8041 | { |
||||||
8042 | return 'function active_user(element_div) { |
||||||
8043 | id_image = $(element_div).attr("id"); |
||||||
8044 | image_clicked = $(element_div).attr("src"); |
||||||
8045 | image_clicked_info = image_clicked.split("/"); |
||||||
8046 | image_real_clicked = image_clicked_info[image_clicked_info.length-1]; |
||||||
8047 | var status = 1; |
||||||
8048 | if (image_real_clicked == "accept.png") { |
||||||
8049 | status = 0; |
||||||
8050 | } |
||||||
8051 | user_id = id_image.split("_"); |
||||||
8052 | ident = "#img_"+user_id[1]; |
||||||
8053 | if (confirm("'.get_lang('AreYouSureToEditTheUserStatus', '').'")) { |
||||||
8054 | $.ajax({ |
||||||
8055 | contentType: "application/x-www-form-urlencoded", |
||||||
8056 | beforeSend: function(myObject) { |
||||||
8057 | $(ident).attr("src","'.Display::returnIconPath('loading1.gif').'"); //candy eye stuff |
||||||
8058 | }, |
||||||
8059 | type: "GET", |
||||||
8060 | url: _p.web_ajax + "user_manager.ajax.php?a=active_user", |
||||||
8061 | data: "user_id=" + user_id[1] + "&status=" + status, |
||||||
8062 | success: function(data) { |
||||||
8063 | if (data == 1) { |
||||||
8064 | $(ident).attr("src", "'.Display::returnIconPath('accept.png', ICON_SIZE_TINY).'"); |
||||||
8065 | $(ident).attr("title","'.get_lang('Lock').'"); |
||||||
8066 | } |
||||||
8067 | if (data == 0) { |
||||||
8068 | $(ident).attr("src","'.Display::returnIconPath('error.png').'"); |
||||||
8069 | $(ident).attr("title","'.get_lang('Unlock').'"); |
||||||
8070 | } |
||||||
8071 | if (data == -1) { |
||||||
8072 | $(ident).attr("src", "'.Display::returnIconPath('warning.png').'"); |
||||||
8073 | $(ident).attr("title","'.get_lang('ActionNotAllowed').'"); |
||||||
8074 | } |
||||||
8075 | } |
||||||
8076 | }); |
||||||
8077 | } |
||||||
8078 | }'; |
||||||
8079 | } |
||||||
8080 | |||||||
8081 | /** |
||||||
8082 | * Get a list of users with the given e-mail address + their "active" field value (0 or 1). |
||||||
8083 | * |
||||||
8084 | * @param string $mail User id |
||||||
8085 | * |
||||||
8086 | * @return array List of users e-mails + active field |
||||||
8087 | */ |
||||||
8088 | public static function getUsersByMail(string $mail): array |
||||||
8089 | { |
||||||
8090 | $resultData = Database::select( |
||||||
8091 | 'id, active', |
||||||
8092 | Database::get_main_table(TABLE_MAIN_USER), |
||||||
8093 | [ |
||||||
8094 | 'where' => ['email = ?' => $mail], |
||||||
8095 | ], |
||||||
8096 | 'all', |
||||||
8097 | null |
||||||
8098 | ); |
||||||
8099 | |||||||
8100 | if ($resultData === false) { |
||||||
8101 | return []; |
||||||
8102 | } |
||||||
8103 | |||||||
8104 | return $resultData; |
||||||
8105 | } |
||||||
8106 | |||||||
8107 | /** |
||||||
8108 | * Get whether we can send an e-mail or not. |
||||||
8109 | * If the e-mail is not in the database, send the mail. |
||||||
8110 | * If the e-mail is in the database but none of its occurences is active, don't send. |
||||||
8111 | * |
||||||
8112 | * @param string $mail The e-mail address to check |
||||||
8113 | * |
||||||
8114 | * @return bool Whether we can send an e-mail or not |
||||||
8115 | */ |
||||||
8116 | public function isEmailingAllowed(string $mail): bool |
||||||
8117 | { |
||||||
8118 | $list = self::getUsersByMail($mail); |
||||||
8119 | if (empty($list)) { |
||||||
8120 | // No e-mail matches, send the mail |
||||||
8121 | return true; |
||||||
8122 | } |
||||||
8123 | $send = false; |
||||||
8124 | foreach ($list as $id => $user) { |
||||||
8125 | if ($user['active'] == 1) { |
||||||
8126 | // as soon as we find at least one active user, send the mail |
||||||
8127 | return true; |
||||||
8128 | } |
||||||
8129 | } |
||||||
8130 | |||||||
8131 | return false; |
||||||
8132 | } |
||||||
8133 | |||||||
8134 | /** |
||||||
8135 | * @return EncoderFactory |
||||||
8136 | */ |
||||||
8137 | private static function getEncoderFactory() |
||||||
8138 | { |
||||||
8139 | $encryption = self::getPasswordEncryption(); |
||||||
8140 | $encoders = [ |
||||||
8141 | 'Chamilo\\UserBundle\\Entity\\User' => new \Chamilo\UserBundle\Security\Encoder($encryption), |
||||||
8142 | ]; |
||||||
8143 | |||||||
8144 | return new EncoderFactory($encoders); |
||||||
8145 | } |
||||||
8146 | |||||||
8147 | /** |
||||||
8148 | * @return \Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface |
||||||
8149 | */ |
||||||
8150 | private static function getEncoder(User $user) |
||||||
8151 | { |
||||||
8152 | $encoderFactory = self::getEncoderFactory(); |
||||||
8153 | |||||||
8154 | return $encoderFactory->getEncoder($user); |
||||||
8155 | } |
||||||
8156 | |||||||
8157 | /** |
||||||
8158 | * Disables or enables a user. |
||||||
8159 | * |
||||||
8160 | * @param int $user_id |
||||||
8161 | * @param int $active Enable or disable |
||||||
8162 | * |
||||||
8163 | * @return bool True on success, false on failure |
||||||
8164 | * @assert (-1,0) === false |
||||||
8165 | * @assert (1,1) === true |
||||||
8166 | */ |
||||||
8167 | private static function change_active_state($user_id, $active) |
||||||
8168 | { |
||||||
8169 | $user_id = (int) $user_id; |
||||||
8170 | $active = (int) $active; |
||||||
8171 | |||||||
8172 | if (empty($user_id)) { |
||||||
8173 | return false; |
||||||
8174 | } |
||||||
8175 | |||||||
8176 | $table_user = Database::get_main_table(TABLE_MAIN_USER); |
||||||
8177 | $sql = "UPDATE $table_user SET active = '$active' WHERE id = $user_id"; |
||||||
8178 | $r = Database::query($sql); |
||||||
8179 | $ev = LOG_USER_DISABLE; |
||||||
8180 | if ($active == 1) { |
||||||
8181 | $ev = LOG_USER_ENABLE; |
||||||
8182 | } |
||||||
8183 | if ($r !== false) { |
||||||
8184 | Event::addEvent($ev, LOG_USER_ID, $user_id); |
||||||
8185 | } |
||||||
8186 | |||||||
8187 | return $r; |
||||||
8188 | } |
||||||
8189 | |||||||
8190 | /** |
||||||
8191 | * Get either a Gravatar URL or complete image tag for a specified email address. |
||||||
8192 | * |
||||||
8193 | * @param string $email The email address |
||||||
8194 | * @param int $s Size in pixels, defaults to 80px [ 1 - 2048 ] |
||||||
8195 | * @param string $d Default imageset to use [ 404 | mm | identicon | monsterid | wavatar ] |
||||||
8196 | * @param string $r Maximum rating (inclusive) [ g | pg | r | x ] |
||||||
8197 | * @param bool $img True to return a complete IMG tag False for just the URL |
||||||
8198 | * @param array $atts Optional, additional key/value attributes to include in the IMG tag |
||||||
8199 | * |
||||||
8200 | * @return string containing either just a URL or a complete image tag |
||||||
8201 | * @source http://gravatar.com/site/implement/images/php/ |
||||||
8202 | */ |
||||||
8203 | private static function getGravatar( |
||||||
8204 | $email, |
||||||
8205 | $s = 80, |
||||||
8206 | $d = 'mm', |
||||||
8207 | $r = 'g', |
||||||
8208 | $img = false, |
||||||
8209 | $atts = [] |
||||||
8210 | ) { |
||||||
8211 | $url = 'http://www.gravatar.com/avatar/'; |
||||||
8212 | if (!empty($_SERVER['HTTPS'])) { |
||||||
8213 | $url = 'https://secure.gravatar.com/avatar/'; |
||||||
8214 | } |
||||||
8215 | $url .= md5(strtolower(trim($email))); |
||||||
8216 | $url .= "?s=$s&d=$d&r=$r"; |
||||||
8217 | if ($img) { |
||||||
8218 | $url = '<img src="'.$url.'"'; |
||||||
8219 | foreach ($atts as $key => $val) { |
||||||
8220 | $url .= ' '.$key.'="'.$val.'"'; |
||||||
8221 | } |
||||||
8222 | $url .= ' />'; |
||||||
8223 | } |
||||||
8224 | |||||||
8225 | return $url; |
||||||
8226 | } |
||||||
8227 | |||||||
8228 | /** |
||||||
8229 | * return user hash based on user_id and loggedin user's salt |
||||||
8230 | * |
||||||
8231 | * @param int user_id id of the user for whom we need the hash |
||||||
8232 | * |
||||||
8233 | * @return string containing the hash |
||||||
8234 | */ |
||||||
8235 | public static function generateUserHash(int $user_id): string |
||||||
8236 | { |
||||||
8237 | $currentUserId = api_get_user_id(); |
||||||
8238 | $userManager = self::getManager(); |
||||||
8239 | /** @var User $user */ |
||||||
8240 | $user = self::getRepository()->find($currentUserId); |
||||||
8241 | if (empty($user)) { |
||||||
8242 | return false; |
||||||
0 ignored issues
–
show
|
|||||||
8243 | } |
||||||
8244 | return rawurlencode(api_encrypt_hash($user_id, $user->getSalt())); |
||||||
8245 | } |
||||||
8246 | |||||||
8247 | /** |
||||||
8248 | * return decrypted hash or false |
||||||
8249 | * |
||||||
8250 | * @param string hash hash that is to be decrypted |
||||||
8251 | * |
||||||
8252 | * @return string |
||||||
8253 | */ |
||||||
8254 | public static function decryptUserHash(string $hash): string |
||||||
8255 | { |
||||||
8256 | $currentUserId = api_get_user_id(); |
||||||
8257 | $userManager = self::getManager(); |
||||||
8258 | /** @var User $user */ |
||||||
8259 | $user = self::getRepository()->find($currentUserId); |
||||||
8260 | if (empty($user)) { |
||||||
8261 | return false; |
||||||
0 ignored issues
–
show
|
|||||||
8262 | } |
||||||
8263 | return api_decrypt_hash(rawurldecode($hash), $user->getSalt()); |
||||||
8264 | } |
||||||
8265 | } |
||||||
8266 |
Let?s assume that you have a directory layout like this:
and let?s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as
OtherDir/Foo.php
does not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php
, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: