From 4635549f11ee83dbb507c06b46101f962cae7e78 Mon Sep 17 00:00:00 2001 From: Laurent Opprecht Date: Mon, 23 Apr 2012 11:10:10 +0200 Subject: [PATCH] Course notifications Rss --- .../course_notice_controller.class.php | 158 ++++++++++++ .../course_notice_query.class.php | 226 ++++++++++++++++++ .../course_notice/course_notice_rss.class.php | 213 +++++++++++++++++ main/course_notice/index.php | 17 ++ main/course_notice/index2.php | 8 + 5 files changed, 622 insertions(+) create mode 100644 main/course_notice/course_notice_controller.class.php create mode 100644 main/course_notice/course_notice_query.class.php create mode 100644 main/course_notice/course_notice_rss.class.php create mode 100644 main/course_notice/index.php create mode 100644 main/course_notice/index2.php diff --git a/main/course_notice/course_notice_controller.class.php b/main/course_notice/course_notice_controller.class.php new file mode 100644 index 0000000000..da7dbd8f7f --- /dev/null +++ b/main/course_notice/course_notice_controller.class.php @@ -0,0 +1,158 @@ + 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; + } + +} \ No newline at end of file diff --git a/main/course_notice/course_notice_query.class.php b/main/course_notice/course_notice_query.class.php new file mode 100644 index 0000000000..6e74f7a780 --- /dev/null +++ b/main/course_notice/course_notice_query.class.php @@ -0,0 +1,226 @@ + 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; + } + +} \ No newline at end of file diff --git a/main/course_notice/course_notice_rss.class.php b/main/course_notice/course_notice_rss.class.php new file mode 100644 index 0000000000..cd41a3e132 --- /dev/null +++ b/main/course_notice/course_notice_rss.class.php @@ -0,0 +1,213 @@ + 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 << + + + + {$channel->title} + + {$channel->link} + {$channel->description} + {$channel->last_build_date} + {$channel->language} + {$channel->update_period} + {$channel->update_frequency} + {$channel->generator} +EOT; + + foreach ($channel->items as $item) + { + echo << + {$item->title} + {$item->link} + {$item->date} + {$item->author} + course_title}]]> + description}]]> + + +EOT; + } + echo ''; + } + + 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 ? '
' : ''; + $result->description .= '' . $item->course_title . ' > ' . $this->get_tool_lang($item->tool) . ' > ' . $item->title . ''; + + $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 .= '
' . $course->title . ' > ' . get_lang('Agenda') . ' > ' . $item->title . ''; + } + +} \ No newline at end of file diff --git a/main/course_notice/index.php b/main/course_notice/index.php new file mode 100644 index 0000000000..f41f7491a2 --- /dev/null +++ b/main/course_notice/index.php @@ -0,0 +1,17 @@ + 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(); diff --git a/main/course_notice/index2.php b/main/course_notice/index2.php new file mode 100644 index 0000000000..f6e35627d9 --- /dev/null +++ b/main/course_notice/index2.php @@ -0,0 +1,8 @@ +