From 9e3b21b73c9c0b670c2059a53b3980a131790d0b Mon Sep 17 00:00:00 2001 From: Julio Montoya Date: Wed, 15 Jul 2020 16:02:14 +0200 Subject: [PATCH] Update from 1.11.x --- public/main/admin/user_anonymize_import.php | 159 +++ public/main/auth/pausetraining.php | 88 ++ public/main/inc/ajax/course_chat.ajax.php | 82 ++ public/main/inc/ajax/group.ajax.php | 27 + public/main/inc/lib/webservices/Rest.php | 950 ++++++++++++++---- .../main/inc/lib/webservices/RestResponse.php | 2 +- 6 files changed, 1109 insertions(+), 199 deletions(-) create mode 100644 public/main/admin/user_anonymize_import.php create mode 100644 public/main/auth/pausetraining.php create mode 100644 public/main/inc/ajax/course_chat.ajax.php create mode 100644 public/main/inc/ajax/group.ajax.php diff --git a/public/main/admin/user_anonymize_import.php b/public/main/admin/user_anonymize_import.php new file mode 100644 index 0000000000..ef42459a4b --- /dev/null +++ b/public/main/admin/user_anonymize_import.php @@ -0,0 +1,159 @@ + 'index.php', "name" => get_lang('PlatformAdmin')]; + +set_time_limit(0); +ini_set('memory_limit', -1); + +Display::display_header($tool_name); + +$step1Form = new FormValidator('step1Form'); + +$usernameListFile = $step1Form->addFile('usernameList', get_lang('UsernameList')); +$step1Form->addButtonUpload(get_lang('Upload')); + +$step2Form = new FormValidator('step2Form'); +$usernameTextarea = $step2Form->addTextarea( + 'usersToBeAnonymized', + get_lang('UsersAboutToBeAnonymized'), + [ + 'readonly' => 1, + ] +); +$step2Form->addButtonUpdate(get_lang('Anonymize')); + +if ($step1Form->validate() && $usernameListFile->isUploadedFile()) { + $filePath = $usernameListFile->getValue()['tmp_name']; + if (!file_exists($filePath)) { + throw new Exception(get_lang('CouldNotReadFile').' '.$filePath); + } + $submittedUsernames = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (false === $submittedUsernames) { + throw new Exception(get_lang('CouldNotReadFileLines').' '.$filePath); + } + if (empty($submittedUsernames)) { + printf( + '

'.get_lang('FileXHasNoData').'

', + ''.$usernameListFile->getValue()['name'].'' + ); + } else { + printf( + '

'.get_lang('FileXHasYNonEmptyLines').'

', + ''.$usernameListFile->getValue()['name'].'', + count($submittedUsernames) + ); + $uniqueSubmittedUsernames = array_values(array_unique($submittedUsernames)); + if (count($uniqueSubmittedUsernames) !== count($submittedUsernames)) { + printf( + '

'.get_lang('DuplicatesOnlyXUniqueUserNames').'

', + count($uniqueSubmittedUsernames) + ); + } + $matching = UserManager::getRepository()->matching( + Criteria::create()->where( + Criteria::expr()->in('username', $uniqueSubmittedUsernames) + ) + ); + foreach ($matching as $element) { + if (!is_null($element)) { + $users[] = $element; + } + } + if (empty($users)) { + echo '

'.get_lang('NoLineMatchedAnyActualUserName').'

'; + } else { + $foundUsernames = []; + foreach ($users as $user) { + $foundUsernames[] = $user->getUsername(); + } + if (count($users) !== count($uniqueSubmittedUsernames)) { + printf('

'.get_lang('OnlyXLinesMatchedActualUsers').'

', count($users)); + $usernamesNotFound = array_diff($uniqueSubmittedUsernames, $foundUsernames); + printf( + '

'.get_lang('TheFollowingXLinesDoNotMatchAnyActualUser').'

%s

', + count($usernamesNotFound), + join("\n", $usernamesNotFound) + ); + } + printf('

'.get_lang('XUsersAreAboutToBeAnonymized').'

', count($foundUsernames)); + $usernameTextarea->setValue(join("\n", $foundUsernames)); + $step2Form->display(); + } + } +} elseif ($step2Form->validate()) { + $usernames = preg_split("/\s+/", $usernameTextarea->getValue()); + if (false === $usernames) { + throw new Exception('preg_split failed'); + } + printf('

'.get_lang('LoadingXUsers')."

\n", count($usernames)); + $users = UserManager::getRepository()->matching( + Criteria::create()->where( + Criteria::expr()->in('username', $usernames) + ) + ); + if (count($users) === count($usernames)) { + printf('

'.get_lang('AnonymizingXUsers')."

\n", count($users)); + $anonymized = []; + $errors = []; + foreach ($users as $user) { + $username = $user->getUsername(); + $userId = $user->getId(); + $name = api_get_person_name($user->getFirstname(), $user->getLastname()); + echo "

$username ($name, id=$userId):\n"; + try { + if (UserManager::anonymize($userId)) { + echo get_lang('Done'); + $anonymized[] = $username; + } else { + echo 'error: UserManager::anonymize failed.'; + $errors[] = $username; + } + } catch (Exception $exception) { + echo 'error: '.$exception->getMessage(); + $errors[] = $username; + } + echo "

\n"; + } + if (empty($error)) { + printf('

'.get_lang('AllXUsersWereAnonymized').'

', count($users)); + } else { + printf( + '

' + .get_lang('OnlyXUsersWereAnonymized') + .' ' + .get_lang('AttemptedAnonymizationOfTheseXUsersFailed') + .'

%s

', + count($users), + count($errors), + join("\n", $errors) + ); + } + } else { + printf( + '

'.get_lang('InternalInconsistencyXUsersFoundForYUserNames').'

', + count($users), + count($usernames) + ); + } +} else { + echo '

'.get_lang('PleaseUploadListOfUsers').'

'; + $step1Form->display(); +} + +Display::display_footer(); diff --git a/public/main/auth/pausetraining.php b/public/main/auth/pausetraining.php new file mode 100644 index 0000000000..d1fd8a0739 --- /dev/null +++ b/public/main/auth/pausetraining.php @@ -0,0 +1,88 @@ +addHeader($plugin->get_lang('PauseTraining')); + +$extraField = new ExtraField('user'); + +$return = $extraField->addElements( + $form, + $userId, + [], + false, + false, + ['pause_formation', 'start_pause_date', 'end_pause_date', 'allow_notifications'], + [], + [], + false, + true +); + +$form->addRule( + ['extra_start_pause_date', 'extra_end_pause_date'], + get_lang('StartDateShouldBeBeforeEndDate'), + 'date_compare', + 'lte' +); + +$form->addButtonSend(get_lang('Update')); +if ($form->validate()) { + $values = $form->getSubmitValues(1); + $values['item_id'] = $userId; + + if (!isset($values['extra_pause_formation'])) { + $values['extra_pause_formation'] = 0; + } + + if (!isset($values['extra_allow_notifications'])) { + $values['extra_allow_notifications'] = 0; + } + + $extraField = new ExtraFieldValue('user'); + $extraField->saveFieldValues($values, true, false, [], [], true); + + Display::addFlash(Display::return_message(get_lang('Update'))); + header('Location: '.api_get_self()); + exit; +} + +$tabs = SocialManager::getHomeProfileTabs('pausetraining'); +$content = $tabs.$form->returnForm(); + +$tpl = new Template(get_lang('ModifyProfile')); + +SocialManager::setSocialUserBlock($tpl, api_get_user_id(), 'home'); +$menu = SocialManager::show_social_menu( + 'home', + null, + api_get_user_id(), + false, + false +); + +$tpl->assign('social_menu_block', $menu); +$tpl->assign('social_right_content', $content); +$social_layout = $tpl->get_template('social/edit_profile.tpl'); + +$tpl->display($social_layout); diff --git a/public/main/inc/ajax/course_chat.ajax.php b/public/main/inc/ajax/course_chat.ajax.php new file mode 100644 index 0000000000..561053c152 --- /dev/null +++ b/public/main/inc/ajax/course_chat.ajax.php @@ -0,0 +1,82 @@ + false]; + +$courseChatUtils = new CourseChatUtils($courseId, $userId, $sessionId, $groupId); + +switch ($_REQUEST['action']) { + case 'chat_logout': + $logInfo = [ + 'tool' => TOOL_CHAT, + 'action' => 'exit', + 'action_details' => 'exit-chat', + ]; + Event::registerLog($logInfo); + break; + case 'track': + $courseChatUtils->keepUserAsConnected(); + $courseChatUtils->disconnectInactiveUsers(); + + $friend = isset($_REQUEST['friend']) ? (int) $_REQUEST['friend'] : 0; + $filePath = $courseChatUtils->getFileName(true, $friend); + $newFileSize = file_exists($filePath) ? filesize($filePath) : 0; + $oldFileSize = isset($_GET['size']) ? (int) $_GET['size'] : -1; + $newUsersOnline = $courseChatUtils->countUsersOnline(); + $oldUsersOnline = isset($_GET['users_online']) ? (int) $_GET['users_online'] : 0; + + $json = [ + 'status' => true, + 'data' => [ + 'oldFileSize' => file_exists($filePath) ? filesize($filePath) : 0, + 'history' => $newFileSize !== $oldFileSize ? $courseChatUtils->readMessages(false, $friend) : null, + 'usersOnline' => $newUsersOnline, + 'userList' => $newUsersOnline != $oldUsersOnline ? $courseChatUtils->listUsersOnline() : null, + 'currentFriend' => $friend, + ], + ]; + + break; + case 'preview': + $json = [ + 'status' => true, + 'data' => [ + 'message' => CourseChatUtils::prepareMessage($_REQUEST['message']), + ], + ]; + break; + case 'reset': + $friend = isset($_REQUEST['friend']) ? (int) $_REQUEST['friend'] : 0; + + $json = [ + 'status' => true, + 'data' => $courseChatUtils->readMessages(true, $friend), + ]; + break; + case 'write': + $friend = isset($_REQUEST['friend']) ? (int) $_REQUEST['friend'] : 0; + $writed = $courseChatUtils->saveMessage($_POST['message'], $friend); + + $json = [ + 'status' => $writed, + 'data' => [ + 'writed' => $writed, + ], + ]; + break; +} + +header('Content-Type: application/json'); +echo json_encode($json); diff --git a/public/main/inc/ajax/group.ajax.php b/public/main/inc/ajax/group.ajax.php new file mode 100644 index 0000000000..6630638cbb --- /dev/null +++ b/public/main/inc/ajax/group.ajax.php @@ -0,0 +1,27 @@ + $group['iid'], + 'text' => $group['name'], + ]; + } + echo json_encode(['items' => $list]); + } + break; + default: + break; +} +exit; diff --git a/public/main/inc/lib/webservices/Rest.php b/public/main/inc/lib/webservices/Rest.php index cb82483b03..e95b050931 100644 --- a/public/main/inc/lib/webservices/Rest.php +++ b/public/main/inc/lib/webservices/Rest.php @@ -1,14 +1,14 @@ get_handler_field_info_by_field_variable(self::EXTRA_FIELD_GCM_REGISTRATION); + + if (empty($fieldInfo)) { + $extraField->save( + [ + 'variable' => self::EXTRA_FIELD_GCM_REGISTRATION, + 'field_type' => ExtraField::FIELD_TYPE_TEXT, + 'display_text' => self::EXTRA_FIELD_GCM_REGISTRATION, + ] + ); + } + } + + /** + * @param string $encoded + * + * @return array + */ + public static function decodeParams($encoded) + { + return json_decode($encoded); + } + /** * Set the current course. * @@ -109,13 +158,15 @@ class Rest extends WebService $course = $em->find('ChamiloCoreBundle:Course', $id); if (!$course) { - throw new Exception(get_lang('This course could not be found')); + throw new Exception(get_lang('NoCourse')); } $this->course = $course; } - /** Set the current session. + /** + * Set the current session. + * * @param int $id * * @throws Exception @@ -133,73 +184,106 @@ class Rest extends WebService $session = $em->find('ChamiloCoreBundle:Session', $id); if (!$session) { - throw new Exception(get_lang('The session could not be found')); + throw new Exception(get_lang('NoSession')); } $this->session = $session; } /** - * @param string $username - * @param string $apiKeyToValidate - * - * @throws Exception + * @param string $registrationId * - * @return Rest + * @return bool */ - public static function validate($username, $apiKeyToValidate) + public function setGcmId($registrationId) { - $apiKey = self::findUserApiKey($username, self::SERVICE_NAME); - - if ($apiKey != $apiKeyToValidate) { - throw new Exception(get_lang('Invalid API key')); - } + $registrationId = Security::remove_XSS($registrationId); + $extraFieldValue = new ExtraFieldValue('user'); - return new self($username, $apiKey); + return $extraFieldValue->save( + [ + 'variable' => self::EXTRA_FIELD_GCM_REGISTRATION, + 'value' => $registrationId, + 'item_id' => $this->user->getId(), + ] + ); } /** - * Create the gcm_registration_id extra field for users. + * @param int $lastMessageId + * + * @return array */ - public static function init() + public function getUserMessages($lastMessageId = 0) { - $extraField = new ExtraField('user'); - $fieldInfo = $extraField->get_handler_field_info_by_field_variable(self::EXTRA_FIELD_GCM_REGISTRATION); + $lastMessages = MessageManager::getMessagesFromLastReceivedMessage($this->user->getId(), $lastMessageId); + $messages = []; - if (empty($fieldInfo)) { - $extraField->save([ - 'variable' => self::EXTRA_FIELD_GCM_REGISTRATION, - 'field_type' => ExtraField::FIELD_TYPE_TEXT, - 'display_text' => self::EXTRA_FIELD_GCM_REGISTRATION, - ]); + foreach ($lastMessages as $message) { + $hasAttachments = MessageManager::hasAttachments($message['id']); + + $messages[] = [ + 'id' => $message['id'], + 'title' => $message['title'], + 'sender' => [ + 'id' => $message['user_id'], + 'lastname' => $message['lastname'], + 'firstname' => $message['firstname'], + 'completeName' => api_get_person_name($message['firstname'], $message['lastname']), + ], + 'sendDate' => $message['send_date'], + 'content' => $message['content'], + 'hasAttachments' => $hasAttachments, + 'url' => api_get_path(WEB_CODE_PATH).'messages/view_message.php?' + .http_build_query(['type' => 1, 'id' => $message['id']]), + ]; } + + return $messages; } /** - * @param string $registrationId - * - * @return bool + * @return array */ - public function setGcmId($registrationId) + public function getUserReceivedMessages() { - $registrationId = Security::remove_XSS($registrationId); - $extraFieldValue = new ExtraFieldValue('user'); + $lastMessages = MessageManager::getReceivedMessages($this->user->getId(), 0); + $messages = []; + + foreach ($lastMessages as $message) { + $hasAttachments = MessageManager::hasAttachments($message['id']); + $attachmentList = []; + if ($hasAttachments) { + $attachmentList = MessageManager::getAttachmentList($message['id']); + } + $messages[] = [ + 'id' => $message['id'], + 'title' => $message['title'], + 'msgStatus' => $message['msg_status'], + 'sender' => [ + 'id' => $message['user_id'], + 'lastname' => $message['lastname'], + 'firstname' => $message['firstname'], + 'completeName' => api_get_person_name($message['firstname'], $message['lastname']), + 'pictureUri' => $message['pictureUri'], + ], + 'sendDate' => $message['send_date'], + 'content' => $message['content'], + 'hasAttachments' => $hasAttachments, + 'attachmentList' => $attachmentList, + 'url' => '', + ]; + } - return $extraFieldValue->save([ - 'variable' => self::EXTRA_FIELD_GCM_REGISTRATION, - 'value' => $registrationId, - 'item_id' => $this->user->getId(), - ]); + return $messages; } /** - * @param int $lastMessageId - * * @return array */ - public function getUserMessages($lastMessageId = 0) + public function getUserSentMessages() { - $lastMessages = MessageManager::getMessagesFromLastReceivedMessage($this->user->getId(), $lastMessageId); + $lastMessages = MessageManager::getSentMessages($this->user->getId(), 0); $messages = []; foreach ($lastMessages as $message) { @@ -208,17 +292,18 @@ class Rest extends WebService $messages[] = [ 'id' => $message['id'], 'title' => $message['title'], - 'sender' => [ + 'msgStatus' => $message['msg_status'], + 'receiver' => [ 'id' => $message['user_id'], 'lastname' => $message['lastname'], 'firstname' => $message['firstname'], 'completeName' => api_get_person_name($message['firstname'], $message['lastname']), + 'pictureUri' => $message['pictureUri'], ], 'sendDate' => $message['send_date'], 'content' => $message['content'], 'hasAttachments' => $hasAttachments, - 'url' => api_get_path(WEB_CODE_PATH).'messages/view_message.php?' - .http_build_query(['type' => 1, 'id' => $message['id']]), + 'url' => '', ]; } @@ -228,9 +313,9 @@ class Rest extends WebService /** * Get the user courses. * - * @throws \Doctrine\ORM\OptimisticLockException * @throws \Doctrine\ORM\TransactionRequiredException * @throws \Doctrine\ORM\ORMException + * @throws \Doctrine\ORM\OptimisticLockException * * @return array */ @@ -243,7 +328,8 @@ class Rest extends WebService /** @var Course $course */ $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseInfo['real_id']); $teachers = CourseManager::getTeacherListFromCourseCodeToString($course->getCode()); - $picturePath = Container::getIllustrationRepository()->getIllustrationUrl($course); + $picturePath = CourseManager::getPicturePath($course, true) + ?: Display::return_icon('session_default.png', null, null, null, null, true); $data[] = [ 'id' => $course->getId(), @@ -278,7 +364,7 @@ class Rest extends WebService 'title' => $this->course->getTitle(), 'code' => $this->course->getCode(), 'directory' => $this->course->getDirectory(), - 'urlPicture' => Container::getIllustrationRepository()->getIllustrationUrl($this->course), + 'urlPicture' => CourseManager::getPicturePath($this->course, true), 'teachers' => $teachers, 'tools' => array_map( function ($tool) { @@ -358,11 +444,11 @@ class Rest extends WebService /** @var array $document */ foreach ($documents as $document) { - if ('1' != $document['visibility']) { + if ($document['visibility'] != '1') { continue; } - $icon = 'file' == $document['filetype'] + $icon = $document['filetype'] == 'file' ? choose_image($document['path']) : chooseFolderIcon($document['path']); @@ -371,17 +457,19 @@ class Rest extends WebService 'type' => $document['filetype'], 'title' => $document['title'], 'path' => $document['path'], - 'url' => $webPath.http_build_query([ - 'username' => $this->user->getUsername(), - 'api_key' => $this->apiKey, - 'cidReq' => $this->course->getCode(), - 'id_session' => $sessionId, - 'gidReq' => 0, - 'gradebook' => 0, - 'origin' => '', - 'action' => 'download', - 'id' => $document['id'], - ]), + 'url' => $webPath.http_build_query( + [ + 'username' => $this->user->getUsername(), + 'api_key' => $this->apiKey, + 'cidReq' => $this->course->getCode(), + 'id_session' => $sessionId, + 'gidReq' => 0, + 'gradebook' => 0, + 'origin' => '', + 'action' => 'download', + 'id' => $document['id'], + ] + ), 'icon' => $icon, 'size' => format_file_size($document['size']), ]; @@ -447,7 +535,7 @@ class Rest extends WebService ); if (!$announcement) { - throw new Exception(get_lang('No announcement')); + throw new Exception(get_lang('NoAnnouncement')); } return [ @@ -568,18 +656,20 @@ class Rest extends WebService $categoriesFullData = get_forum_categories('', $this->course->getId(), $sessionId); $categories = []; - $includeGroupsForums = 'true' === api_get_setting('display_groups_forum_in_general_tool'); + $includeGroupsForums = api_get_setting('display_groups_forum_in_general_tool') === 'true'; $forumsFullData = get_forums('', $this->course->getCode(), $includeGroupsForums, $sessionId); $forums = []; foreach ($forumsFullData as $forumId => $forumInfo) { $forum = [ - 'id' => intval($forumInfo['iid']), - 'catId' => intval($forumInfo['forum_category']), + 'id' => (int) $forumInfo['iid'], + 'catId' => (int) $forumInfo['forum_category'], 'title' => $forumInfo['forum_title'], 'description' => $forumInfo['forum_comment'], 'image' => $forumInfo['forum_image'] ? ($webCoursePath.$forumInfo['forum_image']) : '', - 'numberOfThreads' => isset($forumInfo['number_of_threads']) ? intval($forumInfo['number_of_threads']) : 0, + 'numberOfThreads' => isset($forumInfo['number_of_threads']) ? intval( + $forumInfo['number_of_threads'] + ) : 0, 'lastPost' => null, ]; @@ -611,9 +701,9 @@ class Rest extends WebService ); $categories[] = [ - 'id' => intval($category['iid']), + 'id' => (int) $category['iid'], 'title' => $category['cat_title'], - 'catId' => intval($category['cat_id']), + 'catId' => (int) $category['cat_id'], 'description' => $category['cat_comment'], 'forums' => $categoryForums, 'courseId' => $this->course->getId(), @@ -638,7 +728,7 @@ class Rest extends WebService $forumInfo = get_forums($forumId, $this->course->getCode(), true, $sessionId); if (!isset($forumInfo['iid'])) { - throw new Exception(get_lang('No forum')); + throw new Exception(get_lang('NoForum')); } $webCoursePath = api_get_path(WEB_COURSE_PATH).$this->course->getDirectory().'/upload/forum/images/'; @@ -728,7 +818,6 @@ class Rest extends WebService foreach ($extraInfo as $extra) { /** @var ExtraFieldValues $extraValue */ $extraValue = $extra['value']; - $result['extra'][] = [ 'title' => $extraValue->getField()->getDisplayText(true), 'value' => $extraValue->getValue(), @@ -738,6 +827,19 @@ class Rest extends WebService return $result; } + public function getCourseLpProgress() + { + $sessionId = $this->session ? $this->session->getId() : 0; + $userId = $this->user->getId(); + + /*$sessionId = $this->session ? $this->session->getId() : 0; + $courseId = $this->course->getId();*/ + + $result = Tracking::getCourseLpProgress($userId, $sessionId); + + return [$result]; + } + /** * @throws Exception * @@ -750,7 +852,7 @@ class Rest extends WebService $categoryNone = new CLpCategory(); $categoryNone->setId(0); - $categoryNone->setName(get_lang('Without category')); + $categoryNone->setName(get_lang('WithOutCategory')); $categoryNone->setPosition(0); $categories = array_merge([$categoryNone], $categoriesTempList); @@ -776,7 +878,7 @@ class Rest extends WebService $listData = []; foreach ($flatLpList as $lpId => $lpDetails) { - if (0 == $lpDetails['lp_visibility']) { + if ($lpDetails['lp_visibility'] == 0) { continue; } @@ -806,13 +908,13 @@ class Rest extends WebService $startTime = api_strtotime($lpDetails['publicated_on'], 'UTC'); $endTime = api_strtotime($lpDetails['expired_on'], 'UTC'); $now = time(); - $isActivedTime = false; + $isActiveTime = false; if ($now > $startTime && $endTime > $now) { - $isActivedTime = true; + $isActiveTime = true; } - if (!$isActivedTime) { + if (!$isActiveTime) { continue; } } @@ -823,15 +925,19 @@ class Rest extends WebService $listData[] = [ 'id' => $lpId, 'title' => Security::remove_XSS($lpDetails['lp_name']), - 'progress' => intval($progress), - 'url' => api_get_path(WEB_CODE_PATH).'webservices/api/v2.php?'.http_build_query([ - 'hash' => $this->encodeParams([ - 'action' => 'course_learnpath', - 'lp_id' => $lpId, - 'course' => $this->course->getId(), - 'session' => $sessionId, - ]), - ]), + 'progress' => $progress, + 'url' => api_get_path(WEB_CODE_PATH).'webservices/api/v2.php?'.http_build_query( + [ + 'hash' => $this->encodeParams( + [ + 'action' => 'course_learnpath', + 'lp_id' => $lpId, + 'course' => $this->course->getId(), + 'session' => $sessionId, + ] + ), + ] + ), ]; } @@ -849,18 +955,6 @@ class Rest extends WebService return $categoryData; } - /** - * @param string $encoded - * - * @return array - */ - public static function decodeParams($encoded) - { - $decoded = json_decode($encoded); - - return $decoded; - } - /** * Start login for a user. Then make a redirect to show the learnpath. * @@ -876,16 +970,18 @@ class Rest extends WebService ChamiloSession::write('_user', $loggedUser); Login::init_user($this->user->getId(), true); - $url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.http_build_query([ - 'cidReq' => $this->course->getCode(), - 'id_session' => $sessionId, - 'gidReq' => 0, - 'gradebook' => 0, - 'origin' => '', - 'action' => 'view', - 'lp_id' => intval($lpId), - 'isStudentView' => 'true', - ]); + $url = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?'.http_build_query( + [ + 'cidReq' => $this->course->getCode(), + 'id_session' => $sessionId, + 'gidReq' => 0, + 'gradebook' => 0, + 'origin' => '', + 'action' => 'view', + 'lp_id' => (int) $lpId, + 'isStudentView' => 'true', + ] + ); header("Location: $url"); exit; @@ -990,7 +1086,7 @@ class Rest extends WebService $repo = UserManager::getRepository(); $users = $repo->findUsersToSendMessage($this->user->getId(), $search); - $showEmail = 'true' === api_get_setting('show_email_addresses'); + $showEmail = api_get_setting('show_email_addresses') === 'true'; $data = []; /** @var User $user */ @@ -1103,13 +1199,14 @@ class Rest extends WebService public function addSession(array $params) { $name = $params['name']; - $coach_username = intval($params['coach_username']); + $coach_username = (int) $params['coach_username']; $startDate = $params['access_start_date']; $endDate = $params['access_end_date']; $displayStartDate = $startDate; $displayEndDate = $endDate; $description = $params['description']; $idUrlCampus = $params['id_campus']; + $extraFields = isset($params['extra']) ? $params['extra'] : []; $return = SessionManager::create_session( $name, @@ -1126,7 +1223,7 @@ class Rest extends WebService null, $description, 1, - [], + $extraFields, null, false, $idUrlCampus @@ -1135,13 +1232,13 @@ class Rest extends WebService if ($return) { $out = [ 'status' => true, - 'message' => 'Sesión creada correctamente', + 'message' => get_lang('ANewSessionWasCreated'), 'id_session' => $return, ]; } else { $out = [ 'status' => false, - 'message' => 'Error al crear la sesión', + 'message' => get_lang('ErrorOccurred'), ]; } @@ -1182,30 +1279,31 @@ class Rest extends WebService $results['status'] = true; $results['code_course'] = $courseInfo['code']; $results['title_course'] = $courseInfo['title']; - $results['message'] = 'Curso registrado con exito'; + $results['message'] = sprintf(get_lang('CourseXAdded'), $courseInfo['code']); } else { $results['status'] = false; - $results['message'] = 'Error al registrar el curso'; + $results['message'] = get_lang('CourseCreationFailed'); } return $results; } /** - * @param $user_param + * @param $userParam + * + * @throws Exception * * @return array */ - public function addUser($user_param) + public function addUser($userParam) { - $results = []; - $orig_user_id_value = []; - $firstName = $user_param['firstname']; - $lastName = $user_param['lastname']; - $status = $user_param['status']; - $email = $user_param['email']; - $loginName = $user_param['loginname']; - $password = $user_param['password']; + $firstName = $userParam['firstname']; + $lastName = $userParam['lastname']; + $status = $userParam['status']; + $email = $userParam['email']; + $loginName = $userParam['loginname']; + $password = $userParam['password']; + $official_code = ''; $language = ''; $phone = ''; @@ -1215,18 +1313,19 @@ class Rest extends WebService $active = 1; $hr_dept_id = 0; $extra = null; - $original_user_id_name = $user_param['original_user_id_name']; - $original_user_id_value = $user_param['original_user_id_value']; - $orig_user_id_value[] = $user_param['original_user_id_value']; - $extra_list = $user_param['extra']; - if (!empty($user_param['language'])) { - $language = $user_param['language']; + + $original_user_id_name = $userParam['original_user_id_name']; + $original_user_id_value = $userParam['original_user_id_value']; + + $extra_list = isset($userParam['extra']) ? $userParam['extra'] : []; + if (isset($userParam['language'])) { + $language = $userParam['language']; } - if (!empty($user_param['phone'])) { - $phone = $user_param['phone']; + if (isset($userParam['phone'])) { + $phone = $userParam['phone']; } - if (!empty($user_param['expiration_date'])) { - $expiration_date = $user_param['expiration_date']; + if (isset($userParam['expiration_date'])) { + $expiration_date = $userParam['expiration_date']; } // Default language. @@ -1236,7 +1335,7 @@ class Rest extends WebService // First check wether the login already exists. if (!UserManager::is_username_available($loginName)) { - $results[] = 0; + throw new Exception(get_lang('UserNameNotAvailable')); } $userId = UserManager::create_user( @@ -1256,60 +1355,59 @@ class Rest extends WebService $hr_dept_id ); - if ($userId) { - if (api_is_multiple_url_enabled()) { - if (-1 != api_get_current_access_url_id()) { - UrlManager::add_user_to_url( - $userId, - api_get_current_access_url_id() - ); - } else { - UrlManager::add_user_to_url($userId, 1); - } + if (empty($userId)) { + throw new Exception(get_lang('UserNotRegistered')); + } + + if (api_is_multiple_url_enabled()) { + if (api_get_current_access_url_id() != -1) { + UrlManager::add_user_to_url( + $userId, + api_get_current_access_url_id() + ); } else { - // We add by default the access_url_user table with access_url_id = 1 UrlManager::add_user_to_url($userId, 1); } + } else { + // We add by default the access_url_user table with access_url_id = 1 + UrlManager::add_user_to_url($userId, 1); + } - // Save new field label into user_field table. - UserManager::create_extra_field( - $original_user_id_name, - 1, - $original_user_id_name, - '' - ); - // Save the external system's id into user_field_value table. - UserManager::update_extra_field_value( - $userId, - $original_user_id_name, - $original_user_id_value - ); + // Save new field label into user_field table. + UserManager::create_extra_field( + $original_user_id_name, + 1, + $original_user_id_name, + '' + ); + // Save the external system's id into user_field_value table. + UserManager::update_extra_field_value( + $userId, + $original_user_id_name, + $original_user_id_value + ); - if (is_array($extra_list) && count($extra_list) > 0) { - foreach ($extra_list as $extra) { - $extra_field_name = $extra['field_name']; - $extra_field_value = $extra['field_value']; - // Save new field label into user_field table. - UserManager::create_extra_field( - $extra_field_name, - 1, - $extra_field_name, - '' - ); - // Save the external system's id into user_field_value table. - UserManager::update_extra_field_value( - $userId, - $extra_field_name, - $extra_field_value - ); - } + if (is_array($extra_list) && count($extra_list) > 0) { + foreach ($extra_list as $extra) { + $extra_field_name = $extra['field_name']; + $extra_field_value = $extra['field_value']; + // Save new field label into user_field table. + UserManager::create_extra_field( + $extra_field_name, + 1, + $extra_field_name, + '' + ); + // Save the external system's id into user_field_value table. + UserManager::update_extra_field_value( + $userId, + $extra_field_name, + $extra_field_value + ); } - $results[] = $userId; - } else { - $results[] = 0; } - return $results; + return [$userId]; } /** @@ -1339,10 +1437,24 @@ class Rest extends WebService return [true]; } + public function deleteUserMessage($messageId, $messageType) + { + if ($messageType === "sent") { + return MessageManager::delete_message_by_user_sender($this->user->getId(), $messageId); + } else { + return MessageManager::delete_message_by_user_receiver($this->user->getId(), $messageId); + } + } + + public function setMessageRead($messageId) + { + MessageManager::update_message($this->user->getId(), $messageId); + } + /** * Add Campus Virtual. * - * @param array Params Campus + * @param array Params Campus * * @return array */ @@ -1353,9 +1465,9 @@ class Rest extends WebService $active = isset($params['active']) ? intval($params['active']) : 0; $num = UrlManager::url_exist($urlCampus); - if (0 == $num) { + if ($num == 0) { // checking url - if ('/' == substr($urlCampus, strlen($urlCampus) - 1, strlen($urlCampus))) { + if (substr($urlCampus, strlen($urlCampus) - 1, strlen($urlCampus)) == '/') { $idCampus = UrlManager::add($urlCampus, $description, $active, true); } else { //create @@ -1377,7 +1489,7 @@ class Rest extends WebService /** * Edit Campus Virtual. * - * @param array Params Campus + * @param array Params Campus * * @return array */ @@ -1391,11 +1503,11 @@ class Rest extends WebService if (!empty($url_id)) { //we can't change the status of the url with id=1 - if (1 == $url_id) { + if ($url_id == 1) { $active = 1; } //checking url - if ('/' == substr($urlCampus, strlen($urlCampus) - 1, strlen($urlCampus))) { + if (substr($urlCampus, strlen($urlCampus) - 1, strlen($urlCampus)) == '/') { UrlManager::update($url_id, $urlCampus, $description, $active); } else { UrlManager::update($url_id, $urlCampus.'/', $description, $active); @@ -1410,7 +1522,7 @@ class Rest extends WebService /** * Delete Campus Virtual. * - * @param array Params Campus + * @param array Params Campus * * @return array */ @@ -1422,7 +1534,7 @@ class Rest extends WebService if ($result) { return [ 'status' => true, - 'message' => get_lang('URL deleted.'), + 'message' => get_lang('URLDeleted'), ]; } else { return [ @@ -1452,12 +1564,12 @@ class Rest extends WebService if ($result) { return [ 'status' => $result, - 'message' => 'Los cursos fueron añadidos a la sessión', + 'message' => get_lang('Updated'), ]; } else { return [ 'status' => $result, - 'message' => 'Error al añadir cursos a la sessión', + 'message' => get_lang('ErrorOccurred'), ]; } } @@ -1483,8 +1595,448 @@ class Rest extends WebService return [ 'status' => true, - 'message' => 'Error al añadir usuarios a la sessión', + 'message' => get_lang('UsersAdded'), + ]; + } + + /** + * Creates a session from a model session. + * + * @param $modelSessionId + * @param $sessionName + * @param $startDate + * @param $endDate + * + * @throws Exception + * + * @return int, the id of the new session + */ + public function createSessionFromModel($modelSessionId, $sessionName, $startDate, $endDate, array $extraFields = []) + { + if (empty($modelSessionId) || empty($sessionName) || empty($startDate) || empty($endDate)) { + throw new Exception(get_lang('NoData')); + } + + if (!SessionManager::isValidId($modelSessionId)) { + throw new Exception(get_lang('ModelSessionDoesNotExist')); + } + + $modelSession = SessionManager::fetch($modelSessionId); + + $modelSession['accessUrlId'] = 1; + if (api_is_multiple_url_enabled()) { + if (api_get_current_access_url_id() != -1) { + $modelSession['accessUrlId'] = api_get_current_access_url_id(); + } + } + + $newSessionId = SessionManager::create_session( + $sessionName, + $startDate, + $endDate, + $startDate, + $endDate, + $startDate, + $endDate, + $modelSession['id_coach'], + $modelSession['session_category_id'], + $modelSession['visibility'], + false, + $modelSession['duration'], + $modelSession['description'], + $modelSession['show_description'], + $extraFields, + $modelSession['session_admin_id'], + $modelSession['send_subscription_notification'], + $modelSession['accessUrlId'] + ); + + if (empty($newSessionId)) { + throw new Exception(get_lang('SessionNotRegistered')); + } + + if (is_string($newSessionId)) { + throw new Exception($newSessionId); + } + + $promotionId = $modelSession['promotion_id']; + if ($promotionId) { + $sessionList = array_keys(SessionManager::get_all_sessions_by_promotion($promotionId)); + $sessionList[] = $newSessionId; + SessionManager::subscribe_sessions_to_promotion($modelSession['promotion_id'], $sessionList); + } + + $modelExtraFields = []; + $fields = SessionManager::getFilteredExtraFields($modelSessionId); + if (is_array($fields) and !empty($fields)) { + foreach ($fields as $field) { + $modelExtraFields[$field['variable']] = $field['value']; + } + } + $allExtraFields = array_merge($modelExtraFields, $extraFields); + foreach ($allExtraFields as $name => $value) { + // SessionManager::update_session_extra_field_value returns false when no row is changed, + // which can happen since extra field values are initialized by SessionManager::create_session + // therefore we do not throw an exception when false is returned + SessionManager::update_session_extra_field_value($newSessionId, $name, $value); + } + + $courseList = array_keys(SessionManager::get_course_list_by_session_id($modelSessionId)); + if (is_array($courseList) + && !empty($courseList) + && !SessionManager::add_courses_to_session($newSessionId, $courseList)) { + throw new Exception(get_lang('CoursesNotAddedToSession')); + } + + if (api_is_multiple_url_enabled()) { + if (api_get_current_access_url_id() != -1) { + UrlManager::add_session_to_url( + $newSessionId, + api_get_current_access_url_id() + ); + } else { + UrlManager::add_session_to_url($newSessionId, 1); + } + } else { + UrlManager::add_session_to_url($newSessionId, 1); + } + + return $newSessionId; + } + + /** + * subscribes a user to a session. + * + * @param int $sessionId the session id + * @param string $loginName the user's login name + * + * @throws Exception + * + * @return boolean, whether it worked + */ + public function subscribeUserToSessionFromUsername($sessionId, $loginName) + { + if (!SessionManager::isValidId($sessionId)) { + throw new Exception(get_lang('SessionNotFound')); + } + + $userId = UserManager::get_user_id_from_username($loginName); + if (false === $userId) { + throw new Exception(get_lang('UserNotFound')); + } + + $subscribed = SessionManager::subscribeUsersToSession( + $sessionId, + [$userId], + SESSION_VISIBLE_READ_ONLY, + false + ); + if (!$subscribed) { + throw new Exception(get_lang('UserNotSubscribed')); + } + + return true; + } + + /** + * finds the session which has a specific value in a specific extra field. + * + * @param $fieldName + * @param $fieldValue + * + * @throws Exception when no session matched or more than one session matched + * + * @return int, the matching session id + */ + public function getSessionFromExtraField($fieldName, $fieldValue) + { + // find sessions that that have value in field + $valueModel = new ExtraFieldValue('session'); + $sessionIdList = $valueModel->get_item_id_from_field_variable_and_field_value( + $fieldName, + $fieldValue, + false, + false, + true + ); + + // throw if none found + if (empty($sessionIdList)) { + throw new Exception(get_lang('NoSessionMatched')); + } + + // throw if more than one found + if (count($sessionIdList) > 1) { + throw new Exception(get_lang('MoreThanOneSessionMatched')); + } + + // return sessionId + return intval($sessionIdList[0]['item_id']); + } + + /** + * updates a user identified by its login name. + * + * @param array $parameters + * + * @throws Exception on failure + * + * @return boolean, true on success + */ + public function updateUserFromUserName($parameters) + { + // find user + $userId = null; + if (!is_array($parameters) || empty($parameters)) { + throw new Exception('NoData'); + } + foreach ($parameters as $name => $value) { + if (strtolower($name) === 'loginname') { + $userId = UserManager::get_user_id_from_username($value); + if (false === $userId) { + throw new Exception(get_lang('UserNotFound')); + } + break; + } + } + if (is_null($userId)) { + throw new Exception(get_lang('NoData')); + } + /** @var User $user */ + $user = UserManager::getRepository()->find($userId); + if (empty($user)) { + throw new Exception(get_lang('CouldNotLoadUser')); + } + + // tell the world we are about to update a user + $hook = HookUpdateUser::create(); + if (!empty($hook)) { + $hook->notifyUpdateUser(HOOK_EVENT_TYPE_PRE); + } + + // apply submitted modifications + foreach ($parameters as $name => $value) { + switch (strtolower($name)) { + case 'email': + $user->setEmail($value); + break; + case 'enabled': + $user->setEnabled($value); + break; + case 'lastname': + $user->setLastname($value); + break; + case 'firstname': + $user->setFirstname($value); + break; + case 'phone': + $user->setPhone($value); + break; + case 'address': + $user->setAddress($value); + break; + case 'roles': + $user->setRoles($value); + break; + case 'profile_completed': + $user->setProfileCompleted($value); + break; + case 'auth_source': + $user->setAuthSource($value); + break; + case 'status': + $user->setStatus($value); + break; + case 'official_code': + $user->setOfficialCode($value); + break; + case 'picture_uri': + $user->setPictureUri($value); + break; + case 'creator_id': + $user->setCreatorId($value); + break; + case 'competences': + $user->setCompetences($value); + break; + case 'diplomas': + $user->setDiplomas($value); + break; + case 'openarea': + $user->setOpenArea($value); + break; + case 'teach': + $user->setTeach($value); + break; + case 'productions': + $user->setProductions($value); + break; + case 'language': + $languages = api_get_languages(); + if (!in_array($value, $languages['folder'])) { + throw new Exception(get_lang('LanguageUnavailable')); + } + $user->setLanguage($value); + break; + case 'registration_date': + $user->setRegistrationDate($value); + break; + case 'expiration_date': + $user->setExpirationDate( + new DateTime( + api_get_utc_datetime($value), + new DateTimeZone('UTC') + ) + ); + break; + case 'active': + // see UserManager::update_user() usermanager.lib.php:1205 + if ($user->getActive() != $value) { + $user->setActive($value); + Event::addEvent($value ? LOG_USER_ENABLE : LOG_USER_DISABLE, LOG_USER_ID, $userId); + } + break; + case 'openid': + $user->setOpenId($value); + break; + case 'theme': + $user->setTheme($value); + break; + case 'hr_dept_id': + $user->setHrDeptId($value); + break; + case 'extra': + if (is_array($value)) { + if (count($value) > 0) { + if (is_array($value[0])) { + foreach ($value as $field) { + $fieldName = $field['field_name']; + $fieldValue = $field['field_value']; + if (!isset($fieldName) || !isset($fieldValue) || + !UserManager::update_extra_field_value($userId, $fieldName, $fieldValue)) { + throw new Exception(get_lang('CouldNotUpdateExtraFieldValue').': '.print_r($field, true)); + } + } + } else { + foreach ($value as $fieldName => $fieldValue) { + if (!UserManager::update_extra_field_value($userId, $fieldName, $fieldValue)) { + throw new Exception(get_lang('CouldNotUpdateExtraFieldValue').': '.$fieldName); + } + } + } + } + } + break; + case 'username': + case 'api_key': + case 'action': + case 'loginname': + break; + case 'email_canonical': + case 'locked': + case 'expired': + case 'credentials_expired': + case 'credentials_expire_at': + case 'expires_at': + case 'salt': + case 'last_login': + case 'created_at': + case 'updated_at': + case 'confirmation_token': + case 'password_requested_at': + case 'password': // see UserManager::update_user usermanager.lib.php:1182 + case 'username_canonical': + default: + throw new Exception(get_lang('UnsupportedUpdate')." '$name'"); + } + } + + // save modifications + UserManager::getManager()->updateUser($user, true); + + // tell the world we just updated this user + if (!empty($hook)) { + $hook->setEventData(['user' => $user]); + $hook->notifyUpdateUser(HOOK_EVENT_TYPE_POST); + } + + // invalidate cache for this user + $cacheAvailable = api_get_configuration_value('apc'); + if ($cacheAvailable === true) { + $apcVar = api_get_configuration_value('apc_prefix').'userinfo_'.$userId; + if (apcu_exists($apcVar)) { + apcu_delete($apcVar); + } + } + + return true; + } + + /** + * Returns whether a user login name exists. + * + * @param string $loginname the user login name + * + * @return bool whether the user login name exists + */ + public function usernameExist($loginname) + { + return false !== api_get_user_info_from_username($loginname); + } + + /** + * This service roughly matches what the call to MDL's API core_course_get_contents function returns. + * + * @return array + */ + public function getCourseQuizMdlCompat() + { + $userId = $this->user->getId(); + $courseId = $this->course->getId(); + $sessionId = $this->session ? $this->session->getId() : 0; + + $toolVisibility = CourseHome::getToolVisibility(TOOL_QUIZ, $courseId, $sessionId); + + $json = [ + "id" => $this->course->getId(), + "name" => get_lang('Exercises'), + "visible" => (int) $toolVisibility, + "summary" => '', + "summaryformat" => 1, + "section" => 1, + "hiddenbynumsections" => 0, + "uservisible" => $toolVisibility, + "modules" => [], ]; + + $quizIcon = Display::return_icon('quiz.png', '', [], ICON_SIZE_SMALL, false, true); + + $json['modules'] = array_map( + function (array $exercise) use ($quizIcon) { + return [ + 'id' => $exercise['id'], + 'url' => $exercise['url'], + 'name' => $exercise['name'], + 'instance' => 1, + 'visible' => 1, + 'uservisible' => true, + 'visibleoncoursepage' => 0, + 'modicon' => $quizIcon, + 'modname' => 'quiz', + 'modplural' => get_lang('Exercises'), + 'availability' => null, + 'indent' => 0, + 'onclick' => '', + 'afterlink' => null, + 'customdata' => "", + 'noviewlink' => false, + 'completion' => (int) ($exercise[1] > 0), + ]; + }, + Exercise::exerciseGrid(0, '', $userId, $courseId, $sessionId, true) + ); + + return [$json]; } /** @@ -1494,12 +2046,14 @@ class Rest extends WebService */ private function encodeParams(array $additionalParams = []) { - $params = array_merge($additionalParams, [ - 'api_key' => $this->apiKey, - 'username' => $this->user->getUsername(), - ]); - $encoded = json_encode($params); + $params = array_merge( + $additionalParams, + [ + 'api_key' => $this->apiKey, + 'username' => $this->user->getUsername(), + ] + ); - return $encoded; + return json_encode($params); } } diff --git a/public/main/inc/lib/webservices/RestResponse.php b/public/main/inc/lib/webservices/RestResponse.php index 6ae87a8be6..3f8d36480a 100644 --- a/public/main/inc/lib/webservices/RestResponse.php +++ b/public/main/inc/lib/webservices/RestResponse.php @@ -28,7 +28,7 @@ class RestResponse public function __construct() { $this->error = true; - $this->errorMessage = null; + $this->errorMessage = ''; $this->data = []; }