diff --git a/app/Migrations/Schema/V111/Version20160825155200.php b/app/Migrations/Schema/V111/Version20160825155200.php new file mode 100644 index 0000000000..dc0eed5709 --- /dev/null +++ b/app/Migrations/Schema/V111/Version20160825155200.php @@ -0,0 +1,54 @@ +addSettingCurrent( + 'allow_download_documents_by_api_key', + null, + 'radio', + 'WebServices', + 'false', + 'AllowDownloadDocumentsByApiKeyTitle', + 'AllowDownloadDocumentsByApiKeyComment', + null, + null, + 1, + true, + true, + [ + ['value' => 'false', 'text' => 'No'], + ['value' => 'true', 'text' => 'Yes'] + ] + ); + } + + /** + * @param Schema $schema + * @throws \Doctrine\DBAL\DBALException + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + public function down(Schema $schema) + { + $this->addSql("DELETE FROM settings_current WHERE variable = 'allow_download_documents_by_api_key'"); + $this->addSql("DELETE FROM settings_options WHERE variable = 'allow_download_documents_by_api_key'"); + } +} diff --git a/main/document/document.php b/main/document/document.php index 6b9a6c3789..ad49e7d6c3 100755 --- a/main/document/document.php +++ b/main/document/document.php @@ -31,6 +31,8 @@ use ChamiloSession as Session; require_once '../inc/global.inc.php'; +$allowDownloadDocumentsByApiKey = api_get_setting('allow_download_documents_by_api_key') === 'true'; + $current_course_tool = TOOL_DOCUMENT; $this_section = SECTION_COURSES; $to_user_id = null; @@ -38,8 +40,33 @@ $parent_id = null; $lib_path = api_get_path(LIBRARY_PATH); $actionsRight = ''; -api_protect_course_script(true); -api_protect_course_group(GroupManager::GROUP_TOOL_DOCUMENTS); + +$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null; + +$allowUseTool = false; + +if ($allowDownloadDocumentsByApiKey) { + try { + if ($action != 'download') { + throw new Exception(get_lang('SelectAnAction')); + } + + $username = isset($_GET['username']) ? Security::remove_XSS($_GET['username']) : null; + $apiKey = isset($_GET['api_key']) ? Security::remove_XSS($_GET['api_key']) : null; + + $restApi = Rest::validate($username, $apiKey); + + $allowUseTool = $restApi ? true : false; + } catch (Exception $e) { + $allowUseTool = false; + } +} + +if (!$allowUseTool) { + api_protect_course_script(true); + api_protect_course_group(GroupManager::GROUP_TOOL_DOCUMENTS); +} + DocumentManager::removeGeneratedAudioTempFile(); if ( @@ -173,7 +200,6 @@ if (!empty($groupId)) { // Actions. $document_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : null; -$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null; $currentUrl = api_get_self().'?'.api_get_cidreq().'&id='.$document_id; diff --git a/main/forum/forumfunction.inc.php b/main/forum/forumfunction.inc.php index 640645c403..e046ab63a1 100755 --- a/main/forum/forumfunction.inc.php +++ b/main/forum/forumfunction.inc.php @@ -1339,32 +1339,35 @@ function return_visible_invisible($current_visibility_status) return $status; } } + /** * Retrieve all the information off the forum categories (or one specific) for the current course. * The categories are sorted according to their sorting order (cat_order * - * @param int $id default ''. When an id is passed we only find the information + * @param int|string $id default ''. When an id is passed we only find the information * about that specific forum category. If no id is passed we get all the forum categories. + * @param int $courseId Optional. The course ID + * @param int $sessionId Optional. The session ID * @return array containing all the information about all the forum categories * * @author Patrick Cool , Ghent University * @version february 2006, dokeos 1.8 */ -function get_forum_categories($id = '') +function get_forum_categories($id = '', $courseId = 0, $sessionId = 0) { $table_categories = Database :: get_course_table(TABLE_FORUM_CATEGORY); $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY); // Condition for the session - $session_id = api_get_session_id(); - $course_id = api_get_course_int_id(); + $session_id = $sessionId ?: api_get_session_id(); + $course_id = $courseId ?: api_get_course_int_id(); $condition_session = api_get_session_condition($session_id, true, true, 'forum_categories.session_id'); $condition_session .= " AND forum_categories.c_id = $course_id AND item_properties.c_id = $course_id"; if (empty($id)) { $sql = "SELECT * - FROM ".$table_categories." forum_categories, ".$table_item_property." item_properties + FROM ".$table_item_property." item_properties, ".$table_categories." forum_categories WHERE forum_categories.cat_id=item_properties.ref AND item_properties.visibility=1 AND @@ -1373,7 +1376,7 @@ function get_forum_categories($id = '') ORDER BY forum_categories.cat_order ASC"; if (api_is_allowed_to_edit()) { $sql = "SELECT * - FROM ".$table_categories." forum_categories, ".$table_item_property." item_properties + FROM ".$table_item_property." item_properties, ".$table_categories." forum_categories WHERE forum_categories.cat_id=item_properties.ref AND item_properties.visibility<>2 AND @@ -1383,7 +1386,7 @@ function get_forum_categories($id = '') } } else { $sql = "SELECT * - FROM ".$table_categories." forum_categories, ".$table_item_property." item_properties + FROM ".$table_item_property." item_properties, ".$table_categories." forum_categories WHERE forum_categories.cat_id=item_properties.ref AND item_properties.tool='".TOOL_FORUM_CATEGORY."' AND @@ -1394,7 +1397,7 @@ function get_forum_categories($id = '') $result = Database::query($sql); $forum_categories_list = array(); - while ($row = Database::fetch_array($result)) { + while ($row = Database::fetch_assoc($result)) { if (empty($id)) { $forum_categories_list[$row['cat_id']] = $row; } else { @@ -1409,18 +1412,19 @@ function get_forum_categories($id = '') * This function retrieves all the fora in a given forum category * * @param int $cat_id the id of the forum category + * @param int $courseId Optional. The course ID * @return array containing all the information about the forums (regardless of their category) * * @author Patrick Cool , Ghent University * @version february 2006, dokeos 1.8 */ -function get_forums_in_category($cat_id) +function get_forums_in_category($cat_id, $courseId = 0) { $table_forums = Database::get_course_table(TABLE_FORUM); $table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY); $forum_list = array(); - $course_id = api_get_course_int_id(); + $course_id = $courseId ?: api_get_course_int_id(); $sql = "SELECT * FROM ".$table_forums." forum , ".$table_item_property." item_properties WHERE @@ -1475,15 +1479,10 @@ function get_forums( $table_forums = Database :: get_course_table(TABLE_FORUM); $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD); - $table_posts = Database :: get_course_table(TABLE_FORUM_POST); $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY); // Condition for the session - if (empty($sessionId)) { - $session_id = api_get_session_id(); - } else { - $session_id = $sessionId; - } + $session_id = intval($sessionId) ?: api_get_session_id(); $sessionIdLink = ($session_id === 0) ? '' : 'AND threads.session_id = item_properties.session_id'; @@ -1580,30 +1579,27 @@ function get_forums( we use this part of the function) */ // Select all the forum information of the given forum (that is not deleted). - $sql = "SELECT * FROM $table_forums forum, ".$table_item_property." item_properties + $sql = "SELECT * FROM ".$table_item_property." item_properties, $table_forums forum WHERE - forum.forum_id=item_properties.ref AND - forum_id = ".intval($id)." AND - item_properties.visibility<>2 AND - item_properties.tool='".TOOL_FORUM."' - $condition_session AND - forum.c_id = $course_id AND - item_properties.c_id = $course_id + forum.forum_id = item_properties.ref AND + forum.iid = " . intval($id) . " AND + item_properties.visibility != 2 AND + item_properties.tool = '".TOOL_FORUM."' AND + forum.c_id = item_properties.c_id ORDER BY forum_order ASC"; // Select the number of threads of the forum. $sql2 = "SELECT count(*) AS number_of_threads, forum_id FROM $table_threads WHERE - forum_id = ".intval($id)." AND - c_id = $course_id + forum_id = " . intval($id) . " GROUP BY forum_id"; } // Handling all the forum information. $result = Database::query($sql); - while ($row = Database::fetch_array($result)) { + while ($row = Database::fetch_assoc($result)) { if ($id == '') { $forum_list[$row['forum_id']] = $row; } else { @@ -1783,14 +1779,8 @@ function get_last_post_information($forum_id, $show_invisibles = false, $course_ * @author Patrick Cool , Ghent University * @version february 2006, dokeos 1.8 */ -function get_threads($forum_id, $course_code = null) +function get_threads($forum_id) { - $course_info = api_get_course_info($course_code); - if (empty($course_info)) { - return array(); - } - - $course_id = $course_info['real_id']; $groupId = api_get_group_id(); $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY); $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD); @@ -1803,18 +1793,17 @@ function get_threads($forum_id, $course_code = null) $groupCondition = api_get_group_id() != 0 ? " AND item_properties.to_group_id = '$groupId' " : ""; $sql = "SELECT DISTINCT - thread.*, item_properties.*, users.firstname, users.lastname, users.user_id, - thread.locked as locked + thread.locked as locked, + thread.* FROM $table_threads thread INNER JOIN $table_item_property item_properties ON thread.thread_id = item_properties.ref AND item_properties.c_id = thread.c_id AND - item_properties.c_id = $course_id AND item_properties.tool = '".TABLE_FORUM_THREAD."' $groupCondition LEFT JOIN $table_users users ON thread.thread_poster_id=users.user_id @@ -1825,18 +1814,17 @@ function get_threads($forum_id, $course_code = null) if (api_is_allowed_to_edit()) { $sql = "SELECT DISTINCT - thread.*, item_properties.*, users.firstname, users.lastname, users.user_id, - thread.locked as locked + thread.locked as locked, + thread.* FROM $table_threads thread INNER JOIN $table_item_property item_properties ON thread.thread_id = item_properties.ref AND - item_properties.c_id = $course_id AND - thread.c_id = $course_id AND + item_properties.c_id = thread.c_id AND item_properties.tool = '".TABLE_FORUM_THREAD."' $groupCondition LEFT JOIN $table_users users @@ -1918,7 +1906,6 @@ function getPosts($forumInfo, $threadId, $orderDirection = 'ASC', $recursive = f $criteria = Criteria::create(); $criteria ->where(Criteria::expr()->eq('threadId', $threadId)) - ->andWhere(Criteria::expr()->eq('cId', api_get_course_int_id())) ->andWhere($visibleCriteria) ; @@ -1956,6 +1943,7 @@ function getPosts($forumInfo, $threadId, $orderDirection = 'ASC', $recursive = f $user = $em->find('ChamiloUserBundle:User', $post->getPosterId()); $list[$post->getPostId()] = [ + 'iid' => $post->getIid(), 'c_id' => $post->getCId(), 'post_id' => $post->getPostId(), 'post_title' => $post->getPostTitle(), @@ -2038,19 +2026,17 @@ function get_thread_information($thread_id) { $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY); $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD); - $course_id = api_get_course_int_id(); $thread_id = intval($thread_id); - $sql = "SELECT * FROM ".$table_threads." threads, ".$table_item_property." item_properties + $sql = "SELECT * FROM " . $table_item_property . " item_properties, " . $table_threads . " threads WHERE item_properties.tool= '".TOOL_FORUM_THREAD."' AND - item_properties.c_id = $course_id AND - item_properties.ref = ".$thread_id." AND - threads.thread_id = ".$thread_id." AND - threads.c_id = $course_id + item_properties.ref = threads.thread_id AND + threads.iid = ".$thread_id." AND + threads.c_id = item_properties.c_id "; $result = Database::query($sql); - $row = Database::fetch_array($result); + $row = Database::fetch_assoc($result); return $row; } @@ -5434,7 +5420,7 @@ function get_all_post_from_user($user_id, $course_code) continue; } if ($j <= 4) { - $threads = get_threads($forum['forum_id'], $course_code); + $threads = get_threads($forum['forum_id']); if (is_array($threads)) { $i = 0; diff --git a/main/inc/lib/AnnouncementManager.php b/main/inc/lib/AnnouncementManager.php index a8ed66889d..1e33ef78e1 100755 --- a/main/inc/lib/AnnouncementManager.php +++ b/main/inc/lib/AnnouncementManager.php @@ -177,6 +177,68 @@ class AnnouncementManager } } + public static function getAnnouncementInfoById($announcementId, $courseId, $userId) + { + if (api_is_allowed_to_edit(false, true) || (api_get_course_setting('allow_user_edit_announcement') && !api_is_anonymous())) { + $dql = "SELECT CA, IP + FROM ChamiloCourseBundle:CAnnouncement CA, ChamiloCourseBundle:CItemProperty IP + WHERE + CA.id = IP.ref AND + CA.iid = :announcement AND + IP.tool = 'announcement' AND + CA.cId = IP.course AND + CA.cId = :course AND + ORDER BY CA.displayOrder DESC"; + } else { + $group_list = GroupManager::get_group_ids($courseId, api_get_user_id()); + + if (empty($group_list)) { + $group_list[] = 0; + } + + if (api_get_user_id() != 0) { + $dql = "SELECT CA, IP + FROM ChamiloCourseBundle:CAnnouncement CA, ChamiloCourseBundle:CItemProperty IP + WHERE + CA.id = IP.ref AND + CA.iid = :announcement AND + IP.tool='announcement' AND + ( + IP.toUser = $userId OR + IP.group IN ('0', '" . implode("', '", $group_list) . "') OR + IP.group IS NULL + ) AND + IP.visibility = '1' AND + CA.cId = IP.course AND + IP.course = :course + ORDER BY CA.displayOrder DESC"; + } else { + $dql = "SELECT CA, IP + FROM ChamiloCourseBundle:CAnnouncement CA, ChamiloCourseBundle:CItemProperty IP + WHERE + CA.id = IP.ref AND + CA.iid = :announcement AND + IP.tool = 'announcement' AND + (IP.group = '0' OR IP.group IS NULL) AND + IP.visibility = '1' AND + CA.cId = IP.course AND + IP.course = :course"; + } + } + + $result = Database::getManager() + ->createQuery($dql) + ->execute([ + 'announcement' => $announcementId, + 'course' => $courseId + ]); + + return [ + 'announcement' => $result[0], + 'item_property' => $result[1] + ]; + } + /** * Displays one specific announcement * @param int $announcement_id, the id of the announcement you want to display @@ -188,135 +250,80 @@ class AnnouncementManager } global $charset; - $tbl_announcement = Database::get_course_table(TABLE_ANNOUNCEMENT); - $tbl_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY); - $course_id = api_get_course_int_id(); + $html = ''; + $result = self::getAnnouncementInfoById($announcement_id, api_get_course_int_id(), api_get_user_id()); + $title = $result['announcement']->getTitle(); + $content = $result['announcement']->getContent(); + $html .= ""; + $html .= ""; - if (api_is_allowed_to_edit(false, true) || (api_get_course_setting('allow_user_edit_announcement') && !api_is_anonymous())) { - $sql = "SELECT announcement.*, toolitemproperties.* - FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties - WHERE - announcement.id = toolitemproperties.ref AND - announcement.id = '$announcement_id' AND - toolitemproperties.tool='announcement' AND - announcement.c_id = $course_id AND - toolitemproperties.c_id = $course_id - ORDER BY display_order DESC"; - } else { - $group_list = GroupManager::get_group_ids($course_id, api_get_user_id()); - if (empty($group_list)) { - $group_list[] = 0; - } - if (api_get_user_id() != 0) { - $sql = "SELECT announcement.*, toolitemproperties.* - FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties - WHERE - announcement.id = toolitemproperties.ref AND - announcement.id = '$announcement_id' AND - toolitemproperties.tool='announcement' AND - ( - toolitemproperties.to_user_id='" . api_get_user_id() . "' OR - toolitemproperties.to_group_id IN ('0', '" . implode("', '", $group_list) . "') OR - toolitemproperties.to_group_id IS NULL - ) AND - toolitemproperties.visibility='1' AND - announcement.c_id = $course_id AND - toolitemproperties.c_id = $course_id - ORDER BY display_order DESC"; + if (api_is_allowed_to_edit(false, true) || + (api_get_course_setting('allow_user_edit_announcement') && !api_is_anonymous()) + ) { + $modify_icons = "" . + Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL) . ""; + if ($result['item_property']->getVisibility() == 1) { + $image_visibility = "visible"; + $alt_visibility = get_lang('Hide'); } else { - $sql = "SELECT announcement.*, toolitemproperties.* - FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties - WHERE - announcement.id = toolitemproperties.ref AND - announcement.id = '$announcement_id' AND - toolitemproperties.tool='announcement' AND - (toolitemproperties.to_group_id='0' OR toolitemproperties.to_group_id IS NULL) AND - toolitemproperties.visibility='1' AND - announcement.c_id = $course_id AND - toolitemproperties.c_id = $course_id - "; + $image_visibility = "invisible"; + $alt_visibility = get_lang('Visible'); } - } - - $sql_result = Database::query($sql); - $html = null; - if (Database::num_rows($sql_result) > 0) { - $result = Database::fetch_array($sql_result, 'ASSOC'); - $title = $result['title']; - $content = $result['content']; - $html .= "

" . $title . "

"; - $html .= ""; - - if (api_is_allowed_to_edit(false, true) || - (api_get_course_setting('allow_user_edit_announcement') && !api_is_anonymous()) - ) { - $modify_icons = "" . - Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL) . ""; - if ($result['visibility'] == 1) { - $image_visibility = "visible"; - $alt_visibility = get_lang('Hide'); - } else { - $image_visibility = "invisible"; - $alt_visibility = get_lang('Visible'); - } - global $stok; + global $stok; - $modify_icons .= "" . - Display::return_icon($image_visibility . '.png', $alt_visibility, '', ICON_SIZE_SMALL) . ""; + $modify_icons .= "" . + Display::return_icon($image_visibility . '.png', $alt_visibility, '', ICON_SIZE_SMALL) . ""; - if (api_is_allowed_to_edit(false, true)) { - $modify_icons .= "" . - Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL) . - ""; - } - $html .= ""; + if (api_is_allowed_to_edit(false, true)) { + $modify_icons .= "" . + Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL) . + ""; } + $html .= ""; + } - $content = self::parse_content($result['to_user_id'], $content, api_get_course_id(), api_get_session_id()); + $content = self::parse_content($result['item_property']->getToUser()->getId(), $content, api_get_course_id(), api_get_session_id()); - $html .= ""; - $html .= ""; + $html .= ""; + $html .= ""; - // User or group icon - $sent_to_icon = ''; - if ($result['to_group_id'] !== '0' and $result['to_group_id'] !== 'NULL') { - $sent_to_icon = Display::return_icon('group.gif', get_lang('AnnounceSentToUserSelection')); - } + if ($result['item_property']->getGroup() !== null) { + $sent_to_icon = Display::return_icon('group.gif', get_lang('AnnounceSentToUserSelection')); + } + if (api_is_allowed_to_edit(false, true)) { + $sent_to = self::sent_to('announcement', $announcement_id); + $sent_to_form = self::sent_to_form($sent_to); + $html .= Display::tag( + 'td', + get_lang('SentTo') . ' : ' . $sent_to_form, + array('class' => 'announcements_datum') + ); + } + $attachment_list = self::get_attachment($announcement_id); + + if (count($attachment_list) > 0) { + $html .= "'; - } - $html .= "

" . $title . "

$modify_icons
$modify_icons
$content
" . get_lang('LastUpdateDate') . " : " . api_convert_and_format_date($result['insert_date'], DATE_TIME_FORMAT_LONG) . "
$content
" . get_lang('LastUpdateDate') . " : " . api_convert_and_format_date( + $result['item_property']->getInsertDate(), DATE_TIME_FORMAT_LONG + ) . "
"; + $realname = $attachment_list['path']; + $user_filename = $attachment_list['filename']; + $full_file_name = 'download.php?'.api_get_cidreq().'&file=' . $realname; + $html .= '
'; + $html .= Display::return_icon('attachment.gif', get_lang('Attachment')); + $html .= ' ' . $user_filename . ' '; + $html .= ' - ' . $attachment_list['comment'] . ''; if (api_is_allowed_to_edit(false, true)) { - $sent_to = self::sent_to('announcement', $announcement_id); - $sent_to_form = self::sent_to_form($sent_to); - $html .= Display::tag( - 'td', - get_lang('SentTo') . ' : ' . $sent_to_form, - array('class' => 'announcements_datum') + $html .= Display::url( + Display::return_icon('delete.png', get_lang('Delete'), '', 16), + api_get_self() . "?" . api_get_cidreq() . "&action=delete_attachment&id_attach=" . $attachment_list['id'] . "&sec_token=" . $stok ); } - $attachment_list = self::get_attachment($announcement_id); - - if (count($attachment_list) > 0) { - $html .= "
"; - $realname = $attachment_list['path']; - $user_filename = $attachment_list['filename']; - $full_file_name = 'download.php?'.api_get_cidreq().'&file=' . $realname; - $html .= '
'; - $html .= Display::return_icon('attachment.gif', get_lang('Attachment')); - $html .= ' ' . $user_filename . ' '; - $html .= ' - ' . $attachment_list['comment'] . ''; - if (api_is_allowed_to_edit(false, true)) { - $html .= Display::url( - Display::return_icon('delete.png', get_lang('Delete'), '', 16), - api_get_self() . "?" . api_get_cidreq() . "&action=delete_attachment&id_attach=" . $attachment_list['id'] . "&sec_token=" . $stok - ); - } - $html .= '
"; - - return $html; + $html .= ''; } + $html .= ""; - return null; + return $html; } /** @@ -1395,7 +1402,9 @@ class AnnouncementManager * @param string $sord * @param string $titleToSearch * @param int $userIdToSearch - * + * @param int $userId + * @param int $courseId + * @param int $sessionId * @return array */ public static function getAnnouncements( @@ -1407,16 +1416,19 @@ class AnnouncementManager $sidx = '', $sord = '', $titleToSearch = '', - $userIdToSearch = 0 + $userIdToSearch = 0, + $userId = 0, + $courseId = 0, + $sessionId = 0 ) { $tbl_announcement = Database::get_course_table(TABLE_ANNOUNCEMENT); $tbl_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY); - $user_id = api_get_user_id(); + $user_id = $userId ?: api_get_user_id(); $group_id = api_get_group_id(); - $session_id = api_get_session_id(); + $session_id = $sessionId ?: api_get_session_id(); $condition_session = api_get_session_condition($session_id, true, true, 'announcement.session_id'); - $course_id = api_get_course_int_id(); + $course_id = $courseId ?: api_get_course_int_id(); $_course = api_get_course_info(); $group_memberships = GroupManager::get_group_ids($course_id, api_get_user_id()); diff --git a/main/inc/lib/fileDisplay.lib.php b/main/inc/lib/fileDisplay.lib.php index adb8458976..c4ed0cfcf3 100755 --- a/main/inc/lib/fileDisplay.lib.php +++ b/main/inc/lib/fileDisplay.lib.php @@ -171,6 +171,40 @@ function choose_image($file_name) return 'defaut.gif'; } +/** + * Get the icon to display for a folder by its path + * @param string $folderPath + * @return string + */ +function chooseFolderIcon($folderPath) +{ + if ($folderPath == '/shared_folder') { + return 'folder_users.gif'; + } + + if (strstr($folderPath, 'shared_folder_session_')) { + return 'folder_users.gif'; + } + + switch ($folderPath) { + case '/audio'; + return 'folder_audio.gif'; + case '/flash': + return 'folder_flash.gif'; + case '/images'; + return 'folder_images.gif'; + case '/video': + return 'folder_video.gif'; + case '/images/gallery': + return 'folder_gallery.gif'; + case '/chat_files': + return 'folder_chat.gif'; + case '/learning_path': + return 'folder_learningpath.gif'; + } + + return 'folder_document.gif'; +} /** * Transform a UNIX time stamp in human readable format date. diff --git a/main/inc/lib/notification.lib.php b/main/inc/lib/notification.lib.php index 9a0d588177..5400a10b84 100644 --- a/main/inc/lib/notification.lib.php +++ b/main/inc/lib/notification.lib.php @@ -329,7 +329,7 @@ class Notification extends Model $this->save($params); } - MessagesWebService::sendPushNotification($user_list, $title, $content); + self::sendPushNotification($user_list, $title, $content); } } @@ -443,4 +443,72 @@ class Notification extends Model return $content; } + + /** + * Send the push notifications to Chamilo Mobile app + * @param array $userIds The IDs of users who will be notified + * @param string $title The notification title + * @param string $content The notification content + * @return int The number of success notifications. Otherwise returns false + */ + public static function sendPushNotification(array $userIds, $title, $content) + { + if (api_get_setting('messaging_allow_send_push_notification') !== 'true') { + return false; + } + + $gdcApiKey = api_get_setting('messaging_gdc_api_key'); + + if ($gdcApiKey === false) { + return false; + } + + $content = str_replace(['
', '
', '
'], "\n", $content); + $content = strip_tags($content); + $content = html_entity_decode($content, ENT_QUOTES); + + $gcmRegistrationIds = []; + + foreach ($userIds as $userId) { + $extraFieldValue = new ExtraFieldValue('user'); + $valueInfo = $extraFieldValue->get_values_by_handler_and_field_variable( + $userId, + Rest::EXTRA_FIELD_GCM_REGISTRATION + ); + + if (empty($valueInfo)) { + continue; + } + + $gcmRegistrationIds[] = $valueInfo['value']; + } + + $headers = [ + 'Authorization: key=' . $gdcApiKey, + 'Content-Type: application/json' + ]; + + $fields = json_encode([ + 'registration_ids' => $gcmRegistrationIds, + 'data' => [ + 'title' => $title, + 'message' => $content + ] + ]); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, 'https://gcm-http.googleapis.com/gcm/send'); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); + $result = curl_exec($ch); + curl_close($ch); + + /** @var array $decodedResult */ + $decodedResult = json_decode($result, true); + + return intval($decodedResult['success']); + } } diff --git a/main/inc/lib/webservices/MessagesWebService.class.php b/main/inc/lib/webservices/MessagesWebService.class.php deleted file mode 100644 index afd6caba60..0000000000 --- a/main/inc/lib/webservices/MessagesWebService.class.php +++ /dev/null @@ -1,237 +0,0 @@ - - * @package chamilo.webservices.messages - */ -class MessagesWebService extends WebService -{ - const SERVICE_NAME = 'MsgREST'; - /** - * @var string EXTRA_FIELD_GCM_REGISTRATION Variable name of the user extra field. - * Necessary for register the registration token from the Google Cloud Messaging - */ - const EXTRA_FIELD_GCM_REGISTRATION = 'gcm_registration_id'; - - /** - * Generate the api key for a user - * @param int $userId The user id - * @return string The api key - */ - public function generateApiKey($userId) - { - $apiKey = UserManager::get_api_keys($userId, self::SERVICE_NAME); - - if (empty($apiKey)) { - UserManager::add_api_key($userId, self::SERVICE_NAME); - - $apiKey = UserManager::get_api_keys($userId, self::SERVICE_NAME); - } - - return current($apiKey); - } - - /** - * Get the user api key - * @param string $username The user name - * @return string The api key - */ - public function getApiKey($username) - { - $userInfo = api_get_user_info_from_username($username); - $userId = $userInfo['user_id']; - - if ($this->apiKey !== null) { - return $this->apiKey; - } else { - $this->apiKey = $this->generateApiKey($userId); - - return $this->apiKey; - } - } - - /** - * Check if the api is valid for a user - * @param string $username The username - * @param string $apiKeyToValidate The api key - * @return boolean Whether the api belongs to the user return true. Otherwise return false - */ - public static function isValidApiKey($username, $apiKeyToValidate) - { - $userInfo = api_get_user_info_from_username($username); - $userId = $userInfo['user_id']; - - $apiKeys = UserManager::get_api_keys($userId, self::SERVICE_NAME); - - if (!empty($apiKeys)) { - $apiKey = current($apiKeys); - - if ($apiKey == $apiKeyToValidate) { - return true; - } - } - - return false; - } - - /** - * Get the count of new messages for a user - * @param string $username The username - * @param int $lastId The id of the last received message - * @return int The count fo new messages - */ - public function countNewMessages($username, $lastId = 0) - { - $userInfo = api_get_user_info_from_username($username); - $userId = $userInfo['user_id']; - - return MessageManager::countMessagesFromLastReceivedMessage($userId, $lastId); - } - - /** - * Get the list of new messages for a user - * @param string $username The username - * @param int $lastId The id of the last received message - * @return array the new message list - */ - public function getNewMessages($username, $lastId = 0) - { - $messages = array(); - - $userInfo = api_get_user_info_from_username($username); - $userId = $userInfo['user_id']; - - $lastMessages = MessageManager::getMessagesFromLastReceivedMessage($userId, $lastId); - - foreach ($lastMessages as $message) { - $hasAttachments = MessageManager::hasAttachments($message['id']); - - $messages[] = array( - 'id' => $message['id'], - 'title' => $message['title'], - 'sender' => array( - '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, - 'platform' => array( - 'website' => api_get_path(WEB_PATH), - 'messagingTool' => api_get_path(WEB_PATH) . 'main/messages/inbox.php' - ) - ); - } - - return $messages; - } - - /** - * Create the user extra field - */ - public static function init() - { - $extraField = new ExtraField('user'); - $fieldInfo = $extraField->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 - ]); - } - } - - /** - * Register the Registration ID (token) obtained from Google Cloud Messaging for a user - * @param User $user The user - * @param string $registrationId The token registration id from Google Cloud Messaging - * - * @return int The id after insert or the number of affected rows after update. Otherwhise return false - */ - public static function setGcmRegistrationId(User $user, $registrationId) - { - $registrationId = Security::remove_XSS($registrationId); - $extraFieldValue = new ExtraFieldValue('user'); - - return $extraFieldValue->save([ - 'variable' => self::EXTRA_FIELD_GCM_REGISTRATION, - 'value' => $registrationId, - 'item_id' => $user->getId() - ]); - } - - /** - * Send the push notifications to MobileMessaging app - * @param array $userIds The IDs of users who will be notified - * @param string $title The notification title - * @param string $content The notification content - * @return int The number of success notifications. Otherwise returns false - */ - public static function sendPushNotification(array $userIds, $title, $content) - { - if (api_get_configuration_value('messaging_allow_send_push_notification') !== 'true') { - return false; - } - - $gdcApiKey = api_get_configuration_value('messaging_gdc_api_key'); - - if ($gdcApiKey === false) { - return false; - } - - $content = str_replace(['
', '
', '
'], "\n", $content); - $content = strip_tags($content); - $content = html_entity_decode($content, ENT_QUOTES); - - $gcmRegistrationIds = []; - - foreach ($userIds as $userId) { - $extraFieldValue = new ExtraFieldValue('user'); - $valueInfo = $extraFieldValue->get_values_by_handler_and_field_variable( - $userId, - self::EXTRA_FIELD_GCM_REGISTRATION - ); - - if (empty($valueInfo)) { - continue; - } - - $gcmRegistrationIds[] = $valueInfo['value']; - } - - $headers = [ - 'Authorization: key=' . $gdcApiKey, - 'Content-Type: application/json' - ]; - - $fields = json_encode([ - 'registration_ids' => $gcmRegistrationIds, - 'data' => [ - 'title' => $title, - 'message' => $content - ] - ]); - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, 'https://gcm-http.googleapis.com/gcm/send'); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); - $result = curl_exec($ch); - curl_close($ch); - - $decodedResult = json_decode($result); - - return $decodedResult->success; - } -} diff --git a/main/inc/lib/webservices/Rest.php b/main/inc/lib/webservices/Rest.php new file mode 100644 index 0000000000..72a455613c --- /dev/null +++ b/main/inc/lib/webservices/Rest.php @@ -0,0 +1,639 @@ +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 $registrationId + * @return bool + */ + public function setGcmId($registrationId) + { + $registrationId = Security::remove_XSS($registrationId); + $extraFieldValue = new ExtraFieldValue('user'); + + return $extraFieldValue->save([ + 'variable' => self::EXTRA_FIELD_GCM_REGISTRATION, + 'value' => $registrationId, + 'item_id' => $this->user->getId() + ]); + } + + /** + * @param int $lastMessageId + * @return array + */ + public function getUserMessages($lastMessageId = 0) + { + $lastMessages = MessageManager::getMessagesFromLastReceivedMessage($this->user->getId(), $lastMessageId); + $messages = []; + + foreach ($lastMessages as $message) { + $hasAttachments = MessageManager::hasAttachments($message['id']); + + $messages[] = array( + 'id' => $message['id'], + 'title' => $message['title'], + 'sender' => array( + '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' => '' + ); + } + + return $messages; + } + + /** + * Get the user courses + * @return array + */ + public function getUserCourses() + { + $courses = CourseManager::get_courses_list_by_user_id($this->user->getId()); + $data = []; + + foreach ($courses as $courseId) { + /** @var Course $course */ + $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseId['real_id']); + + $teachers = CourseManager::get_teacher_list_from_course_code_to_string($course->getCode()); + + $data[] = [ + 'id' => $course->getId(), + 'title' => $course->getTitle(), + 'code' => $course->getCode(), + 'directory' => $course->getDirectory(), + 'urlPicture' => $course->getPicturePath(true), + 'teachers' => $teachers + ]; + } + + return $data; + } + + /** + * @param int $courseId + * @return array + * @throws Exception + */ + public function getCourseInfo($courseId) + { + /** @var Course $course */ + $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseId); + + if (!$course) { + throw new Exception(get_lang('NoCourse')); + } + + $teachers = CourseManager::get_teacher_list_from_course_code_to_string($course->getCode()); + + return [ + 'id' => $course->getId(), + 'title' => $course->getTitle(), + 'code' => $course->getCode(), + 'directory' => $course->getDirectory(), + 'urlPicture' => $course->getPicturePath(true), + 'teachers' => $teachers + ]; + } + + /** + * Get the course descriptions + * @param int $courseId + * @return array + * @throws Exception + */ + public function getCourseDescriptions($courseId) + { + /** @var Course $course */ + $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseId); + + if (!$course) { + throw new Exception(get_lang('NoCourse')); + } + + $descriptions = CourseDescription::get_descriptions($course->getId()); + $results = []; + + /** @var CourseDescription $description */ + foreach($descriptions as $description) { + $results[] = [ + 'id' => $description->get_description_type(), + 'title' => $description->get_title(), + 'content' => str_replace('src="/', 'src="' . api_get_path(WEB_PATH), $description->get_content()) + ]; + } + + return $results; + } + + /** + * @param int $courseId + * @param int $directoryId + * @return array + * @throws Exception + */ + public function getCourseDocuments($courseId, $directoryId = 0) + { + /** @var Course $course */ + $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseId); + + if (!$course) { + throw new Exception(get_lang('NoCourse')); + } + + /** @var string $path */ + $path = '/'; + + if ($directoryId) { + $directory = DocumentManager::get_document_data_by_id($directoryId, $course->getCode(), false, 0); + + if (!$directory) { + throw new Exception('NoDataAvailable'); + } + + $path = $directory['path']; + } + + require_once api_get_path(LIBRARY_PATH) . 'fileDisplay.lib.php'; + + $courseInfo = api_get_course_info_by_id($course->getId()); + + $documents = DocumentManager::get_all_document_data($courseInfo, $path); + $results = []; + + if (is_array($documents)) { + $webPath = api_get_path(WEB_CODE_PATH) . 'document/document.php?'; + + /** @var array $document */ + foreach($documents as $document) { + if ($document['visibility'] != '1') { + continue; + } + + $icon = $document['filetype'] == 'file' + ? choose_image($document['path']) + : chooseFolderIcon($document['path']); + + $results[] = [ + 'id' => $document['id'], + 'type' => $document['filetype'], + 'title' => $document['title'], + 'path' => $document['path'], + 'url' => $webPath . http_build_query([ + 'username' => $this->user->getUsername(), + 'api_key' => $this->apiKey, + 'cidReq' => $course->getCode(), + 'id_session' => 0, + 'gidReq' => 0, + 'gradebook' => 0, + 'origin' => '', + 'action' => 'download', + 'id' => $document['id'] + ]), + 'icon' => $icon, + 'size' => format_file_size($document['size']) + ]; + } + } + + return $results; + } + + /** + * @param int $courseId + * @return array + * @throws Exception + */ + public function getCourseAnnouncements($courseId) + { + /** @var Course $course */ + $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseId); + + if (!$course) { + throw new Exception(get_lang('NoCourse')); + } + + $announcements = AnnouncementManager::getAnnouncements( + null, + null, + false, + null, + null, + null, + null, + null, + 0, + $this->user->getId(), + $courseId + ); + + $announcements = array_map(function ($announcement) { + return [ + 'id' => intval($announcement['id']), + 'title' => strip_tags($announcement['title']), + 'creatorName' => strip_tags($announcement['username']), + 'date' => strip_tags($announcement['insert_date']) + ]; + }, $announcements); + + return $announcements; + } + + /** + * @param int $announcementId + * @param int $courseId + * @return array + * @throws Exception + */ + public function getCourseAnnouncement($announcementId, $courseId) + { + /** @var Course $course */ + $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseId); + + if (!$course) { + throw new Exception(get_lang('NoCourse')); + } + + $announcement = AnnouncementManager::getAnnouncementInfoById( + $announcementId, + $course->getId(), + $this->user->getId() + ); + + if (!$announcement) { + throw new Exception(get_lang('NoAnnouncement')); + } + + return [ + 'id' => intval($announcement['announcement']->getIid()), + 'title' => $announcement['announcement']->getTitle(), + 'creatorName' => $announcement['item_property']->getInsertUser()->getCompleteName(), + 'date' => api_convert_and_format_date($announcement['item_property']->getInsertDate(), DATE_TIME_FORMAT_LONG_24H), + 'content' => AnnouncementManager::parse_content( + $this->user->getId(), + $announcement['announcement']->getContent(), + $course->getCode() + ) + ]; + } + + /** + * @param int $courseId + * @return array + * @throws Exception + */ + public function getCourseAgenda($courseId) + { + /** @var Course $course */ + $course = Database::getManager()->find('ChamiloCoreBundle:Course', $courseId); + + if (!$course) { + throw new Exception(get_lang('NoCourse')); + } + + $agenda = new Agenda(); + $agenda->setType('course'); + $result = $agenda->parseAgendaFilter(null); + + $start = new DateTime('now'); + $start->modify('first day of month'); + $end = new DateTime('now'); + $end->modify('first day of month'); + + $groupId = current($result['groups']); + $userId = current($result['users']); + + $events = $agenda->getEvents( + $start->getTimestamp(), + $end->getTimestamp(), + $course->getId(), + $groupId, + $userId, + 'array' + ); + + if (!is_array($events)) { + return []; + } + + $webPath = api_get_path(WEB_PATH); + + return array_map( + function ($event) use ($webPath) { + return [ + 'id' => intval($event['unique_id']), + 'title' => $event['title'], + 'content' => str_replace('src="/', 'src="' . $webPath, $event['description']), + 'startDate' => $event['start_date_localtime'], + 'endDate' => $event['end_date_localtime'], + 'isAllDay' => $event['allDay'] ? true : false + ]; + }, + $events + ); + } + + /** + * @param int $courseId + * @return array + * @throws Exception + */ + public function getCourseNotebooks($courseId) + { + $em = Database::getManager(); + /** @var Course $course */ + $course = $em->find('ChamiloCoreBundle:Course', $courseId); + + if (!$course) { + throw new Exception(get_lang('NoCourse')); + } + + /** @var CNotebookRepository $notebooksRepo */ + $notebooksRepo = $em->getRepository('ChamiloCourseBundle:CNotebook'); + $notebooks = $notebooksRepo->findByUser($this->user, $course, null); + + return array_map( + function (\Chamilo\CourseBundle\Entity\CNotebook $notebook) { + return [ + 'id' => $notebook->getIid(), + 'title' => $notebook->getTitle(), + 'description' => $notebook->getDescription(), + 'creationDate' => api_format_date( + $notebook->getCreationDate()->getTimestamp() + ), + 'updateDate' => api_format_date( + $notebook->getUpdateDate()->getTimestamp() + ) + ]; + }, + $notebooks + ); + } + + /** + * @param int $courseId + * @return array + * @throws Exception + */ + public function getCourseForumCategories($courseId) + { + $em = Database::getManager(); + /** @var Course $course */ + $course = $em->find('ChamiloCoreBundle:Course', $courseId); + + if (!$course) { + throw new Exception(get_lang('NoCourse')); + } + + $webCoursePath = api_get_path(WEB_COURSE_PATH) . $course->getDirectory() . '/upload/forum/images/'; + + require_once api_get_path(SYS_CODE_PATH) . 'forum/forumfunction.inc.php'; + + $categoriesFullData = get_forum_categories('', $course->getId()); + $categories = []; + $includeGroupsForums = api_get_setting('display_groups_forum_in_general_tool') === 'true'; + $forumsFullData = get_forums('', $course->getCode(), $includeGroupsForums); + $forums = []; + + foreach ($forumsFullData as $forumId => $forum) { + $lastPostInfo = get_last_post_information($forumId, false, $course->getId()); + + $forums[] = [ + 'id' => $forum['iid'], + 'catId' => $forum['forum_category'], + 'forumId' => $forum['forum_id'], + 'title' => $forum['forum_title'], + 'description' => $forum['forum_comment'], + 'image' => $forum['forum_image'] ? ($webCoursePath . $forum['forum_image']) : '', + 'lastPost' => [ + 'date' => api_convert_and_format_date($lastPostInfo['last_post_date']), + 'user' => api_get_person_name( + $lastPostInfo['last_poster_firstname'], + $lastPostInfo['last_poster_lastname'] + ) + ] + ]; + } + + foreach ($categoriesFullData as $category) { + $categoryForums = array_filter( + $forums, + function ($forum) use ($category) { + if ($forum['catId'] != $category['cat_id']) { + return false; + } + + return true; + } + ); + + $categories[] = [ + 'id' => $category['iid'], + 'title' => $category['cat_title'], + 'catId' => $category['cat_id'], + 'description' => $category['cat_comment'], + 'forums' => $categoryForums, + 'courseId' => $course->getId() + ]; + } + + return $categories; + } + + /** + * @param int $forumId + * @return array + * @throws Exception + */ + public function getCourseForum($forumId) + { + require_once api_get_path(SYS_CODE_PATH) . 'forum/forumfunction.inc.php'; + + $forumInfo = get_forums($forumId); + + /** @var Course $course */ + $course = Database::getManager()->find('ChamiloCoreBundle:Course', $forumInfo['c_id']); + + if (!$course) { + throw new Exception(get_lang('NoCourse')); + } + + $webCoursePath = api_get_path(WEB_COURSE_PATH) . $course->getDirectory() . '/upload/forum/images/'; + $forum = [ + 'id' => $forumInfo['iid'], + 'forumId' => $forumInfo['forum_id'], + 'title' => $forumInfo['forum_title'], + 'description' => $forumInfo['forum_comment'], + 'image' => $forumInfo['forum_image'] ? ($webCoursePath . $forumInfo['forum_image']) : '', + 'threads' => [] + ]; + + $threads = get_threads($forumInfo['iid']); + + foreach ($threads as $thread) { + $forum['threads'][] = [ + 'iid' => $thread['iid'], + 'title' => $thread['thread_title'], + 'lastEditDate' => api_convert_and_format_date($thread['lastedit_date'], DATE_TIME_FORMAT_LONG_24H), + 'numberOfReplies' => $thread['thread_replies'], + 'numberOfViews' => $thread['thread_views'], + 'author' => api_get_person_name($thread['firstname'], $thread['lastname']) + ]; + } + + return $forum; + } + + /** + * @param int $threadId + * @return array + */ + public function getCourseForumThread($threadId) + { + require_once api_get_path(SYS_CODE_PATH) . 'forum/forumfunction.inc.php'; + + $threadInfo = get_thread_information($threadId); + + $thread = [ + 'id' => intval($threadInfo['iid']), + 'cId' => intval($threadInfo['c_id']), + 'title' => $threadInfo['thread_title'], + 'numberOfReplies' => intval($threadInfo['thread_replies']), + 'numberOfViews' => intval($threadInfo['thread_views']), + 'forumId' => intval($threadInfo['forum_id']), + 'posts' => [] + ]; + + $forumInfo = get_forums($threadInfo['forum_id']); + + $postsInfo = getPosts($forumInfo, $threadInfo['iid'], 'ASC'); + + foreach ($postsInfo as $postInfo) { + $thread['posts'][] = [ + 'id' => $postInfo['iid'], + 'title' => $postInfo['post_title'], + 'text' => $postInfo['post_text'], + 'author' => api_get_person_name($postInfo['firstname'], $postInfo['lastname']), + 'date' => api_convert_and_format_date($postInfo['post_date'], DATE_TIME_FORMAT_LONG_24H), + 'parentId' => $postInfo['post_parent_id'] + ]; + } + + return $thread; + } + + /** + * @return array + */ + public function getUserProfile() + { + $pictureInfo = UserManager::get_user_picture_path_by_id($this->user->getId(), 'web'); + + $result = [ + 'pictureUri' => $pictureInfo['dir'] . $pictureInfo['file'], + 'fullName' => $this->user->getCompleteName(), + 'username' => $this->user->getUsername(), + 'officialCode' => $this->user->getOfficialCode(), + 'phone' => $this->user->getPhone(), + 'extra' => [] + ]; + + $fieldValue = new ExtraFieldValue('user'); + $extraInfo = $fieldValue->getAllValuesForAnItem($this->user->getId(), true); + + foreach ($extraInfo as $extra) { + /** @var ExtraFieldValues $extraValue */ + $extraValue = $extra['value']; + + $result['extra'][] = [ + 'title' => $extraValue->getField()->getDisplayText(true), + 'value' => $extraValue->getValue() + ]; + } + + return $result; + } +} diff --git a/main/inc/lib/webservices/RestResponse.php b/main/inc/lib/webservices/RestResponse.php new file mode 100644 index 0000000000..967c496ddd --- /dev/null +++ b/main/inc/lib/webservices/RestResponse.php @@ -0,0 +1,65 @@ +error = true; + $this->errorMessage = null; + $this->data = []; + } + + /** + * @param array $data + */ + public function setData(array $data) + { + $this->error = false; + $this->data = $data; + } + + /** + * @param string $message + */ + public function setErrorMessage($message) + { + $this->error = true; + $this->errorMessage = $message; + } + + /** + * @return string + */ + public function format() + { + $json = ['error' => $this->error]; + + if ($this->error) { + $json['message'] = $this->errorMessage; + } else { + $json['data'] = $this->data; + } + + return json_encode($json, JSON_PRETTY_PRINT); + } +} diff --git a/main/inc/lib/webservices/WebService.class.php b/main/inc/lib/webservices/WebService.class.php index 5a56b7d561..664a024af2 100644 --- a/main/inc/lib/webservices/WebService.class.php +++ b/main/inc/lib/webservices/WebService.class.php @@ -1,42 +1,72 @@ * @package chamilo.webservices */ -abstract class WebService +class WebService { + /** + * @var User + */ + protected $user; + /** + * @var string + */ protected $apiKey; /** * Class constructor + * @param $username + * @param $apiKey */ - public function __construct() + protected function __construct($username, $apiKey) { - $this->apiKey = null; + /** @var User user */ + $this->user = UserManager::getManager()->findUserByUsername($username); + $this->apiKey = $apiKey; } /** - * Set the api key - * @param string $apiKey The api key + * @param string $username + * @param string $apiKeyToValidate + * @return WebService */ - public function setApiKey($apiKey) + public static function validate($username, $apiKeyToValidate) { - $this->apiKey = $apiKey; + return new self($username, $apiKeyToValidate); } /** - * @abstract + * Find the api key for a user. If the api key does not exists is created + * @param string $username + * @param string $serviceName + * @return string */ - abstract public function getApiKey($username); + public static function findUserApiKey($username, $serviceName) + { + $user = UserManager::getManager()->findUserByUsername($username); + + $apiKeys = UserManager::get_api_keys($user->getId(), $serviceName); + + if (empty($apiKeys)) { + UserManager::add_api_key($user->getId(), $serviceName); + } + + $apiKeys = UserManager::get_api_keys($user->getId(), $serviceName); + + return current($apiKeys); + } /** * Check whether the username and password are valid - * @param string $username The username - * @param string $password the password - * @return boolean Whether the password belongs to the username return true. Otherwise return false + * @param string $username + * @param string $password + * @return bool Return true if the password belongs to the username. Otherwise return false + * @throws Exception */ public static function isValidUser($username, $password) { @@ -48,11 +78,10 @@ abstract class WebService $user = UserManager::getRepository() ->findOneBy(['username' => $username]); - if (empty($user)) { + if (!$user) { return false; } return UserManager::isPasswordValid($user->getPassword(), $password, $user->getSalt()); } - } diff --git a/main/install/data.sql b/main/install/data.sql index fa22674438..47f8560d6a 100644 --- a/main/install/data.sql +++ b/main/install/data.sql @@ -1955,3 +1955,8 @@ INSERT INTO settings_options (variable, value, display_text) VALUES ('icons_mode INSERT INTO branch_sync (access_url_id, branch_name, unique_id, ssl_pub_key) VALUES (1, 'localhost', SHA1(UUID()), SHA1(UUID())); + +INSERT INTO settings_current (variable, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) +VALUES ('allow_download_documents_by_api_key', NULL, 'radio', 'WebServices', 'false', 'AllowDownloadDocumentsByApiKeyTitle', 'AllowDownloadDocumentsByApiKeyComment', '', NULL, 1); +INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_download_documents_by_api_key', 'true', 'Yes'); +INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_download_documents_by_api_key', 'false', 'No'); diff --git a/main/webservices/api/v2.php b/main/webservices/api/v2.php new file mode 100644 index 0000000000..368502dd72 --- /dev/null +++ b/main/webservices/api/v2.php @@ -0,0 +1,156 @@ +setData([ + 'url' => api_get_path(WEB_PATH), + 'apiKey' => Rest::findUserApiKey($username, Rest::SERVIVE_NAME), + 'gcmSenderId' => api_get_setting('messaging_gdc_project_number') + ]); + break; + + case Rest::ACTION_GCM_ID: + $gcmId = isset($_POST['registration_id']) ? Security::remove_XSS($_POST['registration_id']) : null; + + $restApi->setGcmId($gcmId); + + $restResponse->setData(['status' => true]); + break; + + case Rest::ACTION_USER_MESSAGES: + $lastMessageId = isset($_POST['last']) ? intval($_POST['last']) : 0; + + $messages = $restApi->getUserMessages($lastMessageId); + + $restResponse->setData($messages); + break; + + case Rest::ACTION_USER_COURSES: + $courses = $restApi->getUserCourses(); + + $restResponse->setData($courses); + break; + + case Rest::ACTION_COURSE_INFO: + $courseId = isset($_POST['c_id']) ? Security::remove_XSS($_POST['c_id']) : 0; + $courseInfo = $restApi->getCourseInfo($courseId); + + $restResponse->setData($courseInfo); + break; + + case Rest::ACTION_COURSE_DESCRIPTIONS: + $courseId = isset($_POST['c_id']) ? Security::remove_XSS($_POST['c_id']) : 0; + + $descriptions = $restApi->getCourseDescriptions($courseId); + + $restResponse->setData($descriptions); + break; + + case Rest::ACTION_COURSE_DOCUMENTS: + $courseId = isset($_POST['c_id']) ? Security::remove_XSS($_POST['c_id']) : 0; + $directoryId = isset($_POST['dir_id']) ? Security::remove_XSS($_POST['dir_id']) : null; + + $documents = $restApi->getCourseDocuments($courseId, $directoryId); + + $restResponse->setData($documents); + break; + + case Rest::ACTION_COURSE_ANNOUNCEMENTS: + $courseId = isset($_POST['c_id']) ? Security::remove_XSS($_POST['c_id']) : 0; + + $announcements = $restApi->getCourseAnnouncements($courseId); + + $restResponse->setData($announcements); + break; + + case Rest::ACTION_COURSE_ANNOUNCEMENT: + $courseId = isset($_POST['c_id']) ? Security::remove_XSS($_POST['c_id']) : 0; + $announcementId = isset($_POST['a_id']) ? Security::remove_XSS($_POST['a_id']) : 0; + + $announcement = $restApi->getCourseAnnouncement($announcementId, $courseId); + + $restResponse->setData($announcement); + break; + + case Rest::ACTION_COURSE_AGENDA: + $courseId = isset($_POST['c_id']) ? Security::remove_XSS($_POST['c_id']) : 0; + + $agenda = $restApi->getCourseAgenda($courseId); + + $restResponse->setData($agenda); + break; + + case Rest::ACTION_COURSE_NOTEBOOKS: + $courseId = isset($_POST['c_id']) ? Security::remove_XSS($_POST['c_id']) : 0; + + $notebooks = $restApi->getCourseNotebooks($courseId); + + $restResponse->setData($notebooks); + break; + + case Rest::ACTION_COURSE_FORUM_CATEGORIES: + $courseId = isset($_POST['c_id']) ? Security::remove_XSS($_POST['c_id']) : 0; + + $forums = $restApi->getCourseForumCategories($courseId); + + $restResponse->setData($forums); + break; + + case Rest::ACTION_COURSE_FORUM: + $forumId = isset($_POST['forum']) ? Security::remove_XSS($_POST['forum']) : 0; + + $forum = $restApi->getCourseForum($forumId); + + $restResponse->setData($forum); + break; + + case Rest::ACTION_COURSE_FORUM_THREAD: + $threadId = isset($_POST['thread']) ? Security::remove_XSS($_POST['thread']) : 0; + + $thread = $restApi->getCourseForumThread($threadId); + + $restResponse->setData($thread); + break; + + case Rest::ACTION_PROFILE: + $userInfo = $restApi->getUserProfile(); + + $restResponse->setData($userInfo); + break; + + default: + throw new Exception(get_lang('InvalidAction')); + } +} catch (Exception $exeption) { + $restResponse->setErrorMessage( + $exeption->getMessage() + ); +} + +header('Content-Type: application/json'); +header('Access-Control-Allow-Origin: *'); + +echo $restResponse->format(); diff --git a/main/webservices/cm_webservice_forum.php b/main/webservices/cm_webservice_forum.php index c5250a29ed..350b175a74 100755 --- a/main/webservices/cm_webservice_forum.php +++ b/main/webservices/cm_webservice_forum.php @@ -61,7 +61,7 @@ class WSCMForum extends WSCM public function get_forum_threads_id($username, $password, $course_code, $forum_id) { if($this->verifyUserPass($username, $password) == "valid") { - $threads_info = get_threads($forum_id, $course_code); + $threads_info = get_threads($forum_id); $threads_id = '#'; foreach ($threads_info as $thread) { diff --git a/main/webservices/rest.php b/main/webservices/rest.php deleted file mode 100644 index 8b40465c02..0000000000 --- a/main/webservices/rest.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @package chamilo.webservices - */ -/* Require libs and classes */ -require_once '../inc/global.inc.php'; - -/* Manage actions */ -$json = array(); - -$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'nothing'; -$username = isset($_POST['username']) ? Security::remove_XSS($_POST['username']) : null; -$apiKey = isset($_POST['api_key']) ? Security::remove_XSS($_POST['api_key']) : null; - -$em = Database::getManager(); - -switch ($action) { - case 'loginNewMessages': - $password = isset($_POST['password']) ? Security::remove_XSS($_POST['password']) : null; - - if (MessagesWebService::isValidUser($username, $password)) { - MessagesWebService::init(); - - $webService = new MessagesWebService(); - $apiKey = $webService->getApiKey($username); - - $json = array( - 'status' => true, - 'apiKey' => $apiKey, - 'gcmSenderId' => api_get_setting('messaging_gdc_project_number'), - ); - } else { - $json = array( - 'status' => false - ); - } - break; - case 'countNewMessages': - if (MessagesWebService::isValidApiKey($username, $apiKey)) { - $webService = new MessagesWebService(); - $webService->setApiKey($apiKey); - - $lastId = isset($_POST['last']) ? $_POST['last'] : 0; - - $count = $webService->countNewMessages($username, $lastId); - - $json = array( - 'status' => true, - 'count' => $count - ); - } else { - $json = array( - 'status' => false - ); - } - break; - case 'getNewMessages': - if (MessagesWebService::isValidApiKey($username, $apiKey)) { - $webService = new MessagesWebService(); - $webService->setApiKey($apiKey); - - $lastId = isset($_POST['last']) ? $_POST['last'] : 0; - - $messages = $webService->getNewMessages($username, $lastId); - - $json = array( - 'status' => true, - 'messages' => $messages - ); - } else { - $json = array( - 'status' => false - ); - } - break; - case 'setGcmRegistrationId': - if (!MessagesWebService::isValidApiKey($username, $apiKey)) { - $json = ['status' => false]; - break; - } - - $user = $em->getRepository('ChamiloUserBundle:User')->findOneBy(['username' => $username]); - - MessagesWebService::setGcmRegistrationId($user, $_POST['registration_id']); - - $json = ['status' => true]; - break; - default: -} - -/* View */ -header('Content-Type: application/json'); -header('Access-Control-Allow-Origin: *'); -echo json_encode($json); diff --git a/src/Chamilo/CoreBundle/Entity/Course.php b/src/Chamilo/CoreBundle/Entity/Course.php index 396736024b..365eb64e9d 100644 --- a/src/Chamilo/CoreBundle/Entity/Course.php +++ b/src/Chamilo/CoreBundle/Entity/Course.php @@ -1184,4 +1184,31 @@ class Course } return $this; } + + /** + * Check if the course has a picture + * @return bool + */ + public function hasPicture() + { + return file_exists(api_get_path(SYS_COURSE_PATH) . $this->directory . '/course-pic85x85.png'); + } + + /** + * Get the course picture path + * @param bool $fullSize + * @return null|string + */ + public function getPicturePath($fullSize = false) + { + if (!$this->hasPicture()) { + return null; + } + + if ($fullSize) { + return api_get_path(WEB_COURSE_PATH) . $this->directory . '/course-pic.png'; + } + + return api_get_path(WEB_COURSE_PATH) . $this->directory . '/course-pic85x85.png'; + } } diff --git a/src/Chamilo/CoreBundle/Entity/ExtraFieldValues.php b/src/Chamilo/CoreBundle/Entity/ExtraFieldValues.php index a6ca88e142..207dd3f718 100644 --- a/src/Chamilo/CoreBundle/Entity/ExtraFieldValues.php +++ b/src/Chamilo/CoreBundle/Entity/ExtraFieldValues.php @@ -79,7 +79,7 @@ class ExtraFieldValues extends BaseAttributeValue } /** - * @return mixed + * @return ExtraField */ public function getField() { diff --git a/src/Chamilo/CourseBundle/Entity/CAnnouncement.php b/src/Chamilo/CourseBundle/Entity/CAnnouncement.php index 9585a97e31..bf2891df0b 100644 --- a/src/Chamilo/CourseBundle/Entity/CAnnouncement.php +++ b/src/Chamilo/CourseBundle/Entity/CAnnouncement.php @@ -267,4 +267,13 @@ class CAnnouncement { return $this->cId; } + + /** + * Get iid + * @return int + */ + public function getIid() + { + return $this->iid; + } } diff --git a/src/Chamilo/CourseBundle/Entity/CNotebook.php b/src/Chamilo/CourseBundle/Entity/CNotebook.php index 3cfd942691..1a294e4913 100644 --- a/src/Chamilo/CourseBundle/Entity/CNotebook.php +++ b/src/Chamilo/CourseBundle/Entity/CNotebook.php @@ -14,7 +14,7 @@ use Doctrine\ORM\Mapping as ORM; * @ORM\Index(name="course", columns={"c_id"}) * } * ) - * @ORM\Entity + * @ORM\Entity(repositoryClass="Chamilo\CourseBundle\Entity\Repository\CNotebookRepository") */ class CNotebook { @@ -326,4 +326,13 @@ class CNotebook { return $this->cId; } + + /** + * Get iid + * @return int + */ + public function getIid() + { + return $this->iid; + } } diff --git a/src/Chamilo/CourseBundle/Entity/Repository/CNotebookRepository.php b/src/Chamilo/CourseBundle/Entity/Repository/CNotebookRepository.php new file mode 100644 index 0000000000..5c2b526913 --- /dev/null +++ b/src/Chamilo/CourseBundle/Entity/Repository/CNotebookRepository.php @@ -0,0 +1,83 @@ +createQueryBuilder('N'); + $qb + ->where( + $qb->expr()->andX( + $qb->expr()->eq('N.userId', $user->getId()), + $qb->expr()->eq('N.cId', $course->getId()) + ) + ); + + if ($session) { + $qb->andWhere( + $qb->expr()->eq('N.sessionId', $session->getId()) + ); + } else { + $qb->andWhere( + $qb->expr()->orX( + $qb->expr()->eq('N.sessionId', 0), + $qb->expr()->isNull('N.sessionId') + ) + ); + } + + if ($orderField === 'N.updateDate') { + $qb->andWhere( + $qb->expr()->orX( + $qb->expr()->neq('N.updateDate', ''), + $qb->expr()->isNotNull('N.updateDate') + ) + ); + } + + $qb->orderBy($orderField, $orderDirection); + + error_log($qb->getQuery()->getSQL()); + + return $qb->getQuery()->getResult(); + } +}