parent
f46721c0ea
commit
4635549f11
@ -0,0 +1,158 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* Controller for course notice. Displays activity of courses tools to which |
||||
* the user is subscribed in RSS format. |
||||
* |
||||
* Controller of CourseNotice. |
||||
* |
||||
* @license see /license.txt |
||||
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva |
||||
*/ |
||||
class CourseNoticeController |
||||
{ |
||||
|
||||
/** |
||||
* @return CourseNoticeController |
||||
*/ |
||||
public static function instance() |
||||
{ |
||||
static $result = null; |
||||
if(empty($result)) |
||||
{ |
||||
$result = new self(); |
||||
} |
||||
return $result; |
||||
} |
||||
|
||||
protected function __construct() |
||||
{ |
||||
; |
||||
} |
||||
|
||||
/** |
||||
* Name of the service for the API Key. |
||||
* !! 10 chars max !! |
||||
*/ |
||||
public function get_service_name() |
||||
{ |
||||
return 'chamilorss'; |
||||
} |
||||
|
||||
/** |
||||
* Returns true if security accepts to run otherwise returns false. |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public function accept() |
||||
{ |
||||
$user_id = $this->get_user_id(); |
||||
return ! empty($user_id); |
||||
} |
||||
|
||||
/** |
||||
* Returns the url used to access the rss for a specific user. |
||||
* Note that the url is protected by token |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function get_secret_url($action = 'display', $format = 'rss') |
||||
{ |
||||
$user_id = $this->get_user_id(); |
||||
$token = $this->ensure_user_token(); |
||||
$params = array('user_id' => $user_id, 'token' => $token, 'format' => $format, 'action' => $action); |
||||
return Uri::url('main/course_notice/index.php', $params); |
||||
} |
||||
|
||||
/** |
||||
* Returns the request user id |
||||
* |
||||
* @return int |
||||
*/ |
||||
public function get_user_id() |
||||
{ |
||||
return api_get_user_id(); |
||||
} |
||||
|
||||
/** |
||||
* Returns the format requested. Defaults to rss |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function get_format() |
||||
{ |
||||
return Request::get('format', 'rss'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the action requested. Defaults to display |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function get_action() |
||||
{ |
||||
return Request::get('action', 'display'); |
||||
} |
||||
|
||||
/** |
||||
* Ensure a security token is available for the user and rss service- create one if needed. |
||||
* |
||||
* @return string The security token |
||||
*/ |
||||
public function ensure_user_token() |
||||
{ |
||||
$user_id = $this->get_user_id(); |
||||
$service = $this->service_name(); |
||||
$keys = UserManager::get_api_keys($user_id, $service); |
||||
if (empty($keys)) |
||||
{ |
||||
UserManager::add_api_key($user_id, $service); |
||||
$keys = UserManager::get_api_keys($user_id, $service); |
||||
} |
||||
return end($keys); |
||||
} |
||||
|
||||
/** |
||||
* Run the controller. Ensure security and execute requested action. |
||||
*/ |
||||
public function run() |
||||
{ |
||||
if (!$this->accept()) |
||||
{ |
||||
Display::display_header(); |
||||
Display::display_error_message(get_lang('NotAuthorized')); |
||||
Display::display_footer(); |
||||
die; |
||||
} |
||||
|
||||
$action = $this->get_action(); |
||||
$format = $this->get_format(); |
||||
$f = array($this, $action . '_' . $format); |
||||
if (is_callable($f)) |
||||
{ |
||||
call_user_func($f); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Display rss action. Display the notfication Rss for the user. |
||||
* Result is cached. It will refresh every hour. |
||||
*/ |
||||
public function display_rss() |
||||
{ |
||||
Header::content_type_xml(); |
||||
|
||||
$rss = new CourseNoticeRss($this->get_user_id()); |
||||
$limit = (time() - 3600); |
||||
if ($result = Cache::get($rss, $limit)) |
||||
{ |
||||
echo $result; |
||||
exit; |
||||
} |
||||
|
||||
$result = $rss->to_string(); |
||||
Cache::put($rss, $result); |
||||
echo $result; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,226 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* Returns tool notifications for a specific user. I.e. course activity for courses to |
||||
* which the user is registered. |
||||
* |
||||
* @license see /license.txt |
||||
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva |
||||
*/ |
||||
class CourseNoticeQuery implements IteratorAggregate |
||||
{ |
||||
|
||||
/** |
||||
* |
||||
* @param int $user_id |
||||
* @param int $limit |
||||
* @return CourseNotices |
||||
*/ |
||||
public static function create($user_id = null, $limit = 20) |
||||
{ |
||||
return new self($user_id, $limit); |
||||
} |
||||
|
||||
protected $user_id; |
||||
protected $limit; |
||||
|
||||
function __construct($user_id = null, $limit = 20) |
||||
{ |
||||
if (empty($user_id)) |
||||
{ |
||||
global $_user; |
||||
$user_id = $_user['user_id']; |
||||
} |
||||
$this->user_id = (int) $user_id; |
||||
$this->limit = $limit; |
||||
} |
||||
|
||||
public function get_limit() |
||||
{ |
||||
return $this->limit; |
||||
} |
||||
|
||||
public function get_user_id() |
||||
{ |
||||
return $this->user_id; |
||||
} |
||||
|
||||
function get_tools() |
||||
{ |
||||
return array( |
||||
array('name' => TOOL_ANNOUNCEMENT, 'table' => TABLE_ANNOUNCEMENT, 'filter' => ''), |
||||
array('name' => TOOL_DOCUMENT, 'table' => TABLE_DOCUMENT, 'filter' => "tool.filetype = 'file'"), |
||||
array('name' => TOOL_CALENDAR_EVENT, 'table' => TABLE_AGENDA, 'filter' => ''), |
||||
array('name' => TOOL_LINK, 'table' => TABLE_LINK, 'filter' => '') |
||||
); |
||||
} |
||||
|
||||
public function getIterator() |
||||
{ |
||||
return new ArrayIterator($this->get_items()); |
||||
} |
||||
|
||||
private $_get_user_courses = null; |
||||
|
||||
function get_user_courses() |
||||
{ |
||||
if (!is_null($this->_get_user_courses)) |
||||
{ |
||||
return $this->_get_user_courses; |
||||
} |
||||
|
||||
$user_id = $this->user_id; |
||||
return $this->_get_user_courses = CourseManager::get_courses_list_by_user_id($user_id); |
||||
} |
||||
|
||||
function get_user_groups() |
||||
{ |
||||
$result = array(); |
||||
|
||||
$user_id = $this->user_id; |
||||
$tbl_group = Database::get_course_table(TABLE_GROUP_USER); |
||||
$tbl_group_tutor = Database::get_course_table(TABLE_GROUP_TUTOR); |
||||
|
||||
$sql = "(SELECT c_id, group_id FROM $tbl_group WHERE user_id = $user_id) |
||||
UNION DISTINCT |
||||
(SELECT c_id, group_id FROM $tbl_group_tutor WHERE user_id = $user_id)"; |
||||
|
||||
$rs = Database::query($sql); |
||||
while ($row = Database::fetch_array($rs)) |
||||
{ |
||||
$result[] = $row; |
||||
} |
||||
|
||||
return $result; |
||||
} |
||||
|
||||
function get_items() |
||||
{ |
||||
$result = array(); |
||||
$tools = $this->get_tools(); |
||||
foreach ($tools as $tool) |
||||
{ |
||||
$tool_name = $tool['name']; |
||||
$tool_table = $tool['table']; |
||||
$tool_filter = $tool['filter']; |
||||
$items = $this->get_tool_items($tool_name, $tool_table, $tool_filter); |
||||
$result = array_merge($result, $items); |
||||
} |
||||
usort($result, array($this, 'sort_item')); |
||||
return $result; |
||||
} |
||||
|
||||
protected function sort_item($left, $right) |
||||
{ |
||||
if ($left->lastedit_date == $right->lastedit_date) |
||||
{ |
||||
return 0; |
||||
} |
||||
return ($left->lastedit_date <= $right->lastedit_date) ? 1 : -1; |
||||
} |
||||
|
||||
function get_tool_items($tool_name, $tool_table, $tool_filter = '') |
||||
{ |
||||
$item_property_table = Database :: get_course_table(TABLE_ITEM_PROPERTY); |
||||
$course_description = Database :: get_course_table(TABLE_COURSE_DESCRIPTION); |
||||
$course_table = Database::get_main_table(TABLE_MAIN_COURSE); |
||||
$tool_table = Database :: get_course_table($tool_table); |
||||
$user_id = $this->user_id; |
||||
|
||||
//courses |
||||
$course_ids = array(); |
||||
$user_courses = $this->get_user_courses(); |
||||
foreach ($user_courses as $course) |
||||
{ |
||||
$course_ids[] = $course['real_id']; |
||||
} |
||||
$course_ids = implode(',', $course_ids); |
||||
|
||||
//groups |
||||
$group_filter = array(); |
||||
$user_groups = $this->get_user_groups(); |
||||
foreach ($user_groups as $group) |
||||
{ |
||||
$group_id = $group['group_id']; |
||||
$course_id = $group['c_id']; |
||||
$group_filter[] = "(prop.to_group_id = $group_id AND prop.c_id = $course_id)"; |
||||
} |
||||
$group_filter = implode(' OR ', $user_groups); |
||||
$group_filter = $group_filter ? ' OR ' . $group_filter : ''; |
||||
|
||||
//AND prop.lastedit_date > '" . $access_date . "' |
||||
//doc.filetype = 'file'AND |
||||
//$access_date = $this->get_last_access_date($course->code, TOOL_DOCUMENT); |
||||
|
||||
$sql = "SELECT tool.*, |
||||
prop.tool, prop.insert_user_id, prop.insert_date, prop.lastedit_date, |
||||
prop.ref, prop.lastedit_type, prop.lastedit_user_id, prop.to_group_id, |
||||
prop.to_user_id, prop.visibility, prop.start_visible, prop.end_visible, prop.id_session, |
||||
course.code, course.title AS course_title, des.content AS course_description |
||||
FROM $item_property_table prop, $tool_table tool, $course_table course, $course_description des |
||||
WHERE ( |
||||
course.id = prop.c_id AND |
||||
des.c_id = course.id AND |
||||
des.id = 1 AND |
||||
prop.tool = '$tool_name' AND |
||||
tool.id = prop.ref AND |
||||
tool.c_id = prop.c_id AND |
||||
prop.c_id IN ($course_ids) AND |
||||
prop.visibility != 2 AND |
||||
((prop.to_user_id IS NULL AND prop.to_group_id = 0) OR (prop.to_user_id = $user_id) $group_filter) |
||||
)"; |
||||
|
||||
$sql = $tool_filter ? "$sql AND ($tool_filter)" : $sql; |
||||
$sql .= 'ORDER BY lastedit_date DESC'; |
||||
$sql .= ' LIMIT ' . $this->limit; |
||||
$rs = Database::query($sql); |
||||
$result = array(); |
||||
while ($data = Database::fetch_array($rs, 'ASSOC')) |
||||
{ |
||||
$result[] = $this->format_item($data); |
||||
} |
||||
return $result; |
||||
} |
||||
|
||||
protected function format($items) |
||||
{ |
||||
$result = array(); |
||||
foreach ($items as $item) |
||||
{ |
||||
$result[] = $this->format_item($item); |
||||
} |
||||
return $result; |
||||
} |
||||
|
||||
protected function format_item($item) |
||||
{ |
||||
$result = (object) $item; |
||||
$item = (object) $item; |
||||
|
||||
|
||||
if (!isset($result->title)) |
||||
{ |
||||
if (isset($item->name)) |
||||
{ |
||||
$result->title = $item->name; |
||||
} |
||||
} |
||||
|
||||
if (!isset($result->description)) |
||||
{ |
||||
if (isset($item->content)) |
||||
{ |
||||
$result->description = $item->content; |
||||
} |
||||
else if (isset($item->comment)) |
||||
{ |
||||
$result->description = $item->comment; |
||||
} |
||||
} |
||||
|
||||
$result->course_code = $item->code; |
||||
$result->course_id = $item->c_id; |
||||
return $result; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,213 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* Formats in RSS the courses notices returned by CourseNoticeQuery. |
||||
* |
||||
* View of CourseNotice |
||||
* |
||||
* @license see /license.txt |
||||
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva |
||||
*/ |
||||
class CourseNoticeRss |
||||
{ |
||||
|
||||
protected $query; |
||||
|
||||
function __construct($user_id = null, $limit = 20) |
||||
{ |
||||
$this->query = CourseNoticeQuery::create($user_id, $limit); |
||||
} |
||||
|
||||
/** |
||||
* unique id used by the cache |
||||
*/ |
||||
function get_unique_id() |
||||
{ |
||||
return strtolower(__CLASS__) . $this->get_query()->get_user_id(); |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @return CourseNoticeQuery |
||||
*/ |
||||
function get_query() |
||||
{ |
||||
return $this->query; |
||||
} |
||||
|
||||
function get_title() |
||||
{ |
||||
return get_lang('CourseRssTitle'); |
||||
} |
||||
|
||||
function get_description() |
||||
{ |
||||
return get_lang('CourseRssDescription'); |
||||
} |
||||
|
||||
function to_string() |
||||
{ |
||||
return (string)$this; |
||||
} |
||||
|
||||
function __toString() |
||||
{ |
||||
ob_start(); |
||||
$this->display(); |
||||
$result = ob_get_clean(); |
||||
return $result; |
||||
} |
||||
|
||||
function display() |
||||
{ |
||||
$channel = $this->channel(); |
||||
|
||||
echo <<<EOT |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<rss version="2.0" |
||||
xmlns:content="http://purl.org/rss/1.0/modules/content/" |
||||
xmlns:wfw="http://wellformedweb.org/CommentAPI/" |
||||
xmlns:dc="http://purl.org/dc/elements/1.1/" |
||||
xmlns:atom="http://www.w3.org/2005/Atom" |
||||
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" |
||||
xmlns:slash="http://purl.org/rss/1.0/modules/slash/" |
||||
> |
||||
|
||||
<channel> |
||||
<title>{$channel->title}</title> |
||||
<atom:link href="" rel="self" type="application/rss+xml" /> |
||||
<link>{$channel->link}</link> |
||||
<description>{$channel->description}</description> |
||||
<lastBuildDate>{$channel->last_build_date}</lastBuildDate> |
||||
<language>{$channel->language}</language> |
||||
<sy:updatePeriod>{$channel->update_period}</sy:updatePeriod> |
||||
<sy:updateFrequency>{$channel->update_frequency}</sy:updateFrequency> |
||||
<generator>{$channel->generator}</generator> |
||||
EOT; |
||||
|
||||
foreach ($channel->items as $item) |
||||
{ |
||||
echo <<<EOT |
||||
|
||||
<item> |
||||
<title>{$item->title}</title> |
||||
<link>{$item->link}</link> |
||||
<pubDate>{$item->date}</pubDate> |
||||
<dc:creator>{$item->author}</dc:creator> |
||||
<category><![CDATA[{$item->course_title}]]></category> |
||||
<description><![CDATA[{$item->description}]]></description> |
||||
</item> |
||||
|
||||
EOT; |
||||
} |
||||
echo '</channel></rss>'; |
||||
} |
||||
|
||||
function channel() |
||||
{ |
||||
$result = (object) array(); |
||||
$result->title = $this->get_title(); |
||||
$result->description = $this->get_description(); |
||||
$result->link = Uri::www(); |
||||
$result->last_build_date = time(); |
||||
$result->language = api_get_language_isocode(); |
||||
$result->update_period = 'hourly'; |
||||
$result->update_frequency = 1; |
||||
$result->generator = Uri::chamilo(); |
||||
|
||||
$items = $this->get_query()->get_items(); |
||||
$items = $this->format($items); |
||||
$result->items = $items; |
||||
return $result; |
||||
} |
||||
|
||||
protected function format($items) |
||||
{ |
||||
$result = array(); |
||||
foreach ($items as $item) |
||||
{ |
||||
$result[] = $this->format_item($item); |
||||
} |
||||
return $result; |
||||
} |
||||
|
||||
protected function format_item($item) |
||||
{ |
||||
$result = (object) array(); |
||||
$item = (object) $item; |
||||
|
||||
$author = (object) UserManager::get_user_info_by_id($item->lastedit_user_id); |
||||
|
||||
$result->title = $item->title; |
||||
$result->description = $item->description; |
||||
$result->description .= $result->description ? '<br/>' : ''; |
||||
$result->description .= '<i>' . $item->course_title . ' > ' . $this->get_tool_lang($item->tool) . ' > ' . $item->title . '</i>'; |
||||
|
||||
$result->date = date('r', strtotime($item->lastedit_date)); |
||||
$result->author = htmlentities($author->firstname . ' ' . $author->lastname . ' <' . $author->email . '>'); |
||||
$result->author_email = $author->email; |
||||
$result->tool = $item->tool; |
||||
$result->course_code = $item->code; |
||||
$result->course_title = $item->course_title; |
||||
$result->course_description = $item->course_description; |
||||
$result->course_id = $item->c_id; |
||||
|
||||
$tool = $item->tool; |
||||
$f = array($this, "format_$tool"); |
||||
if (is_callable($f)) |
||||
{ |
||||
call_user_func($f, $result, $item); |
||||
} |
||||
return $result; |
||||
} |
||||
|
||||
protected function get_tool_lang($tool_name) |
||||
{ |
||||
if ($tool_name = TOOL_CALENDAR_EVENT) |
||||
{ |
||||
return get_lang('Agenda'); |
||||
} |
||||
else if ($tool_name = TOOL_DOCUMENT) |
||||
{ |
||||
return get_lang('Document'); |
||||
} |
||||
else if ($tool_name = TOOL_LINK) |
||||
{ |
||||
return get_lang('Link'); |
||||
} |
||||
else if ($tool_name = TOOL_ANNOUNCEMENT) |
||||
{ |
||||
return get_lang('Announcement'); |
||||
} |
||||
} |
||||
|
||||
protected function format_document($result, $item) |
||||
{ |
||||
$params = Uri::course_params($item->code, $item->session_id, $item->to_group_id); |
||||
$params['id'] = $item->ref; |
||||
$params['action'] = 'download'; |
||||
$result->link = Uri::url('main/document/document.php', $params); |
||||
} |
||||
|
||||
protected function format_announcement($result, $item) |
||||
{ |
||||
$params = Uri::course_params($item->code, $item->session_id, $item->to_group_id); |
||||
$params['id'] = $item->ref; |
||||
$params['action'] = 'view'; |
||||
$result->link = Uri::url('main/announcements/announcements.php', $params); |
||||
} |
||||
|
||||
protected function format_link($result, $item) |
||||
{ |
||||
$result->link = $item->url; |
||||
} |
||||
|
||||
protected function format_calendar_event($result, $item) |
||||
{ |
||||
$params = Uri::course_params($item->code, $item->session_id, $item->to_group_id); |
||||
// . 'calendar/agenda.php?cidReq=' . $item->code . '#' . $item->id; |
||||
$result->link = Uri::url('main/calendar/agenda.php', $params); |
||||
//$result->description .= '<br/><i>' . $course->title . ' > ' . get_lang('Agenda') . ' > ' . $item->title . '</i>'; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,17 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* Displays courses tools activities in RSS format. |
||||
* |
||||
* @license see /license.txt |
||||
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva |
||||
*/ |
||||
require_once dirname(__FILE__) . '/../inc/autoload.inc.php'; |
||||
|
||||
$controller = CourseNoticeController::instance(); |
||||
KeyAuth::enable_services($controller); |
||||
|
||||
$language_file = array('announcements', 'document', 'link', 'agenda', 'admin'); |
||||
require_once dirname(__FILE__) . '/../inc/global.inc.php'; |
||||
|
||||
$controller->run(); |
@ -0,0 +1,8 @@ |
||||
<?php |
||||
|
||||
/* |
||||
* Blank age used to test the performance impact of global. So that we can |
||||
* compare other pages against a benchmark. |
||||
*/ |
||||
|
||||
require_once dirname(__FILE__) . '/../../main/inc/global.inc.php'; |
Loading…
Reference in new issue