Course notifications Rss

skala
Laurent Opprecht 13 years ago
parent f46721c0ea
commit 4635549f11
  1. 158
      main/course_notice/course_notice_controller.class.php
  2. 226
      main/course_notice/course_notice_query.class.php
  3. 213
      main/course_notice/course_notice_rss.class.php
  4. 17
      main/course_notice/index.php
  5. 8
      main/course_notice/index2.php

@ -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 . ' &gt; ' . $this->get_tool_lang($item->tool) . ' &gt; ' . $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 . ' &gt; ' . get_lang('Agenda') . ' &gt; ' . $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…
Cancel
Save