Merge branch '1.11.x' of github.com:chamilo/chamilo-lms into 1.11.x

pull/2487/head
jmontoyaa 9 years ago
commit 1f7eba21cd
  1. 54
      app/Migrations/Schema/V111/Version20160825155200.php
  2. 5
      documentation/installation_guide.html
  3. 32
      main/document/document.php
  4. 90
      main/forum/forumfunction.inc.php
  5. 250
      main/inc/lib/AnnouncementManager.php
  6. 34
      main/inc/lib/fileDisplay.lib.php
  7. 70
      main/inc/lib/notification.lib.php
  8. 237
      main/inc/lib/webservices/MessagesWebService.class.php
  9. 646
      main/inc/lib/webservices/Rest.php
  10. 65
      main/inc/lib/webservices/RestResponse.php
  11. 57
      main/inc/lib/webservices/WebService.class.php
  12. 5
      main/install/data.sql
  13. 157
      main/webservices/api/v2.php
  14. 2
      main/webservices/cm_webservice_forum.php
  15. 97
      main/webservices/rest.php
  16. 27
      src/Chamilo/CoreBundle/Entity/Course.php
  17. 2
      src/Chamilo/CoreBundle/Entity/ExtraFieldValues.php
  18. 9
      src/Chamilo/CourseBundle/Entity/CAnnouncement.php
  19. 11
      src/Chamilo/CourseBundle/Entity/CNotebook.php
  20. 83
      src/Chamilo/CourseBundle/Entity/Repository/CNotebookRepository.php

@ -0,0 +1,54 @@
<?php
/* For licensing terms, see /license.txt */
namespace Application\Migrations\Schema\V111;
use Application\Migrations\AbstractMigrationChamilo;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\Type;
/**
* Class Version20160825155200
* Add option to allow download documents with the api key
* @package Application\Migrations\Schema\V111
*/
class Version20160825155200 extends AbstractMigrationChamilo
{
/**
* @param Schema $schema
* @throws \Doctrine\DBAL\DBALException
* @throws \Doctrine\DBAL\Schema\SchemaException
*/
public function up(Schema $schema)
{
$this->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'");
}
}

@ -701,6 +701,7 @@ If you have issues with files taking a long time to download, make sure you reco
location @rewrite{
rewrite ^/courses/([^/]+)/scorm/(.*)$ /main/document/download_scorm.php?doc_url=/$2&cDir=$1 last;
rewrite "^/courses/([^/]+)/document/certificates/(.*)$" /app/courses/$1/document/certificates/$2 last;
rewrite ^/courses/([^/]+)/document/(.*)$ /main/document/download.php?doc_url=/$2&cDir=$1 last;
rewrite ^/courses/([^/]+)/work/(.*)$ /main/work/download.php?file=work/$2&cDir=$1 last;
rewrite ^/courses/([^/]+)/upload/(.*)$ /app/courses/$1/upload/$2 last;
@ -711,7 +712,8 @@ If you have issues with files taking a long time to download, make sure you reco
location / {
rewrite ^/courses/([^/]+)/$ /main/course_home/course_home.php?cDir=$1 last;
rewrite ^/courses/([^/]+)/index.php$ /main/course_home/course_home.php?cDir=$1 last;
rewrite ^/badge/(\d+)/user/(\d+)$ /main/badge/issued.php?skill=$1&user=$2 last;
rewrite ^/skill/(\d+)/user/(\d+)$ /main/badge/issued_all.php?skill=$1&user=$2 last;
rewrite ^/badge/(\d+)/user/(\d+)$ /main/badge/issued_all.php?skill=$1&user=$2 last;
try_files $uri @rewrite;
}
@ -727,6 +729,7 @@ If you have issues with files taking a long time to download, make sure you reco
rewrite ^/courses/([^/]+)/$ /main/course_home/course_home.php?cDir=$1 last;
rewrite ^/courses/([^/]+)/index.php$ /main/course_home/course_home.php?cDir=$1 last;
rewrite ^/session/([^/]+)/about/?$ /main/session/about.php?session_id=$1 last;
rewrite ^/badge/([^/]+) /main/badge/issued.php?issue=$1 last;
rewrite ^/main/exercice/(.+)$ /main/exercise/$1 last;
rewrite ^/main/newscorm/(.+)$ /main/lp/$1 last;

@ -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;

@ -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 <patrick.cool@UGent.be>, 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 <patrick.cool@UGent.be>, 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';
@ -1504,7 +1503,7 @@ function get_forums(
if ($id == '') {
// Student
// Select all the forum information of all forums (that are visible to students).
$sql = "SELECT * FROM $table_forums forum
$sql = "SELECT item_properties.*, forum.* FROM $table_forums forum
INNER JOIN ".$table_item_property." item_properties
ON (
forum.forum_id = item_properties.ref AND
@ -1539,7 +1538,7 @@ function get_forums(
// Course Admin
if (api_is_allowed_to_edit()) {
// Select all the forum information of all forums (that are not deleted).
$sql = "SELECT * FROM ".$table_forums." forum
$sql = "SELECT item_properties.*, forum.* FROM ".$table_forums." forum
INNER JOIN ".$table_item_property." item_properties
ON (
forum.forum_id = item_properties.ref AND
@ -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 <patrick.cool@UGent.be>, 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;

@ -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 .= "<table height=\"100\" width=\"100%\" cellpadding=\"5\" cellspacing=\"0\" class=\"data_table\">";
$html .= "<tr><td><h2>" . $title . "</h2></td></tr>";
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 = "<a href=\"" . api_get_self() . "?" . api_get_cidreq() . "&action=modify&id=" . $announcement_id . "\">" .
Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL) . "</a>";
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 .= "<table height=\"100\" width=\"100%\" cellpadding=\"5\" cellspacing=\"0\" class=\"data_table\">";
$html .= "<tr><td><h2>" . $title . "</h2></td></tr>";
if (api_is_allowed_to_edit(false, true) ||
(api_get_course_setting('allow_user_edit_announcement') && !api_is_anonymous())
) {
$modify_icons = "<a href=\"" . api_get_self() . "?" . api_get_cidreq() . "&action=modify&id=" . $announcement_id . "\">" .
Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_SMALL) . "</a>";
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 .= "<a href=\"" . api_get_self() . "?" . api_get_cidreq() . "&origin=" . (!empty($_GET['origin']) ? Security::remove_XSS($_GET['origin']) : '') . "&action=showhide&id=" . $announcement_id . "&sec_token=" . $stok . "\">" .
Display::return_icon($image_visibility . '.png', $alt_visibility, '', ICON_SIZE_SMALL) . "</a>";
$modify_icons .= "<a href=\"" . api_get_self() . "?" . api_get_cidreq() . "&origin=" . (!empty($_GET['origin']) ? Security::remove_XSS($_GET['origin']) : '') . "&action=showhide&id=" . $announcement_id . "&sec_token=" . $stok . "\">" .
Display::return_icon($image_visibility . '.png', $alt_visibility, '', ICON_SIZE_SMALL) . "</a>";
if (api_is_allowed_to_edit(false, true)) {
$modify_icons .= "<a href=\"" . api_get_self() . "?" . api_get_cidreq() . "&action=delete&id=" . $announcement_id . "&sec_token=" . $stok . "\" onclick=\"javascript:if(!confirm('" . addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, $charset)) . "')) return false;\">" .
Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL) .
"</a>";
}
$html .= "<tr><th style='text-align:right'>$modify_icons</th></tr>";
if (api_is_allowed_to_edit(false, true)) {
$modify_icons .= "<a href=\"" . api_get_self() . "?" . api_get_cidreq() . "&action=delete&id=" . $announcement_id . "&sec_token=" . $stok . "\" onclick=\"javascript:if(!confirm('" . addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, $charset)) . "')) return false;\">" .
Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL) .
"</a>";
}
$html .= "<tr><th style='text-align:right'>$modify_icons</th></tr>";
}
$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 .= "<tr><td>$content</td></tr>";
$html .= "<tr><td class=\"announcements_datum\">" . get_lang('LastUpdateDate') . " : " . api_convert_and_format_date($result['insert_date'], DATE_TIME_FORMAT_LONG) . "</td></tr>";
$html .= "<tr><td>$content</td></tr>";
$html .= "<tr><td class=\"announcements_datum\">" . get_lang('LastUpdateDate') . " : " . api_convert_and_format_date(
$result['item_property']->getInsertDate(), DATE_TIME_FORMAT_LONG
) . "</td></tr>";
// 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 .= "<tr><td>";
$realname = $attachment_list['path'];
$user_filename = $attachment_list['filename'];
$full_file_name = 'download.php?'.api_get_cidreq().'&file=' . $realname;
$html .= '<br/>';
$html .= Display::return_icon('attachment.gif', get_lang('Attachment'));
$html .= '<a href="' . $full_file_name . ' "> ' . $user_filename . ' </a>';
$html .= ' - <span class="forum_attach_comment" >' . $attachment_list['comment'] . '</span>';
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 .= "<tr><td>";
$realname = $attachment_list['path'];
$user_filename = $attachment_list['filename'];
$full_file_name = 'download.php?'.api_get_cidreq().'&file=' . $realname;
$html .= '<br/>';
$html .= Display::return_icon('attachment.gif', get_lang('Attachment'));
$html .= '<a href="' . $full_file_name . ' "> ' . $user_filename . ' </a>';
$html .= ' - <span class="forum_attach_comment" >' . $attachment_list['comment'] . '</span>';
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 .= '</td></tr>';
}
$html .= "</table>";
return $html;
$html .= '</td></tr>';
}
$html .= "</table>";
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());

@ -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.

@ -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(['<br>', '<br/>', '<br />'], "\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']);
}
}

@ -1,237 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\UserBundle\Entity\User;
/**
* Class for manage the messages web service
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
* @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(['<br>', '<br/>', '<br />'], "\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;
}
}

@ -0,0 +1,646 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\UserBundle\Entity\User;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\ExtraFieldValues;
use Chamilo\CourseBundle\Entity\Repository\CAnnouncementRepository;
use Chamilo\CourseBundle\Entity\CAnnouncement;
use Chamilo\CourseBundle\Entity\Repository\CNotebookRepository;
/**
* Class RestApi
*/
class Rest extends WebService
{
const SERVIVE_NAME = 'MsgREST';
const EXTRA_FIELD_GCM_REGISTRATION = 'gcm_registration_id';
const ACTION_AUTH = 'authenticate';
const ACTION_USER_MESSAGES = 'user_messages';
const ACTION_GCM_ID = 'gcm_id';
const ACTION_USER_COURSES = 'user_courses';
const ACTION_PROFILE = 'user_profile';
const ACTION_COURSE_INFO = 'course_info';
const ACTION_COURSE_DESCRIPTIONS = 'course_descriptions';
const ACTION_COURSE_DOCUMENTS = 'course_documents';
const ACTION_COURSE_ANNOUNCEMENTS = 'course_announcements';
const ACTION_COURSE_ANNOUNCEMENT = 'course_announcement';
const ACTION_COURSE_AGENDA = 'course_agenda';
const ACTION_COURSE_NOTEBOOKS = 'course_notebooks';
const ACTION_COURSE_FORUM_CATEGORIES = 'course_forumcategories';
const ACTION_COURSE_FORUM = 'course_forum';
const ACTION_COURSE_FORUM_THREAD = 'course_forumthread';
const EXTRAFIELD_GCM_ID = 'gcm_registration_id';
/**
* Rest constructor.
* @param string $username
* @param string $apiKey
*/
public function __construct($username, $apiKey)
{
parent::__construct($username, $apiKey);
}
/**
* @param string $username
* @param string $apiKeyToValidate
* @return Rest
* @throws Exception
*/
public static function validate($username, $apiKeyToValidate)
{
$apiKey = self::findUserApiKey($username, self::SERVIVE_NAME);
if ($apiKey != $apiKeyToValidate) {
throw new Exception(get_lang('InvalidApiKey'));
}
return new self($username, $apiKey);
}
/**
* Create the gcm_registration_id extra field for users
*/
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
]);
}
}
/**
* @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 => $forumInfo) {
$forum = [
'id' => intval($forumInfo['iid']),
'catId' => intval($forumInfo['forum_category']),
'title' => $forumInfo['forum_title'],
'description' => $forumInfo['forum_comment'],
'image' => $forumInfo['forum_image'] ? ($webCoursePath . $forumInfo['forum_image']) : '',
'numberOfThreads' => intval($forumInfo['number_of_threads']),
'lastPost' => null
];
$lastPostInfo = get_last_post_information($forumId, false, $course->getId());
if ($lastPostInfo) {
$forum['lastPost'] = [
'date' => api_convert_and_format_date($lastPostInfo['last_post_date']),
'user' => api_get_person_name(
$lastPostInfo['last_poster_firstname'],
$lastPostInfo['last_poster_lastname']
)
];
}
$forums[] = $forum;
}
foreach ($categoriesFullData as $category) {
$categoryForums = array_filter(
$forums,
function (array $forum) use ($category) {
if ($forum['catId'] != $category['cat_id']) {
return false;
}
return true;
}
);
$categories[] = [
'id' => intval($category['iid']),
'title' => $category['cat_title'],
'catId' => intval($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);
if (!isset($forumInfo['iid'])) {
throw new Exception(get_lang('NoForum'));
}
/** @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'],
'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'][] = [
'id' => $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'],
'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;
}
}

@ -0,0 +1,65 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Class RestApiResponse
*/
class RestResponse
{
/**
* @var bool
*/
private $error;
/**
* @var string
*/
private $errorMessage;
/**
* @var array
*/
private $data;
/**
* RestApiResponse constructor.
*/
public function __construct()
{
$this->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);
}
}

@ -1,42 +1,72 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\UserBundle\Entity\User;
/**
* Base class for Web Services
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
* @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());
}
}

@ -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');

@ -0,0 +1,157 @@
<?php
/* For licensing terms, see /license.txt */
require_once '../../inc/global.inc.php';
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
$username = isset($_POST['username']) ? Security::remove_XSS($_POST['username']) : null;
$apiKey = isset($_POST['api_key']) ? Security::remove_XSS($_POST['api_key']) : null;
$restResponse = new RestResponse();
try {
/** @var Rest $restApi */
$restApi = $apiKey ? Rest::validate($username, $apiKey) : null;
switch ($action) {
case Rest::ACTION_AUTH:
Rest::init();
$password = isset($_POST['password']) ? $_POST['password'] : null;
$isValid = Rest::isValidUser($username, $password);
if (!$isValid) {
throw new Exception(get_lang('InvalideUserDetected'));
}
$restResponse->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();

@ -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)
{

@ -1,97 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Controller for REST request
* @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
* @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);

@ -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';
}
}

@ -79,7 +79,7 @@ class ExtraFieldValues extends BaseAttributeValue
}
/**
* @return mixed
* @return ExtraField
*/
public function getField()
{

@ -267,4 +267,13 @@ class CAnnouncement
{
return $this->cId;
}
/**
* Get iid
* @return int
*/
public function getIid()
{
return $this->iid;
}
}

@ -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;
}
}

@ -0,0 +1,83 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\CourseBundle\Entity\Repository;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\UserBundle\Entity\User;
use Doctrine\ORM\EntityRepository;
/**
* Class CNotebookRepository
* @package Chamilo\CourseBundle\Entity\Repository
*/
class CNotebookRepository extends EntityRepository
{
/**
* Get the user notebooks in a course
* @param User $user
* @param Course $course
* @param Session|null $session
* @param string $orderField
* @param string $orderDirection
* @return array
*/
public function findByUser(
User $user,
Course $course,
Session $session = null,
$orderField = 'creation_date',
$orderDirection = 'DESC')
{
switch ($orderField) {
case 'creation_date':
$orderField = 'N.creationDate';
break;
case 'update_date':
$orderField = 'N.updateDate';
break;
case 'title':
$orderField = 'N.title';
break;
}
$qb = $this->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();
}
}
Loading…
Cancel
Save