diff --git a/lang/en_utf8/notes.php b/lang/en_utf8/notes.php
new file mode 100755
index 0000000000000..d0d32f79828ad
--- /dev/null
+++ b/lang/en_utf8/notes.php
@@ -0,0 +1,29 @@
+name - $a->date';
+$string['publishstate'] = 'Status';
+$string['personal'] = 'personal';
+$string['course'] = 'course';
+$string['site'] = 'site';
+?>
\ No newline at end of file
diff --git a/lang/en_utf8/role.php b/lang/en_utf8/role.php
index d470f12739544..633021ea547c6 100644
--- a/lang/en_utf8/role.php
+++ b/lang/en_utf8/role.php
@@ -145,4 +145,8 @@
$string['site:mnetlogintoremote'] = 'Roam to a remote Moodle';
$string['site:mnetloginfromremote'] = 'Login from a remote Moodle';
+// Notes
+$string['notes:view'] = 'View notes';
+$string['notes:manage'] = 'Manage notes';
+
?>
diff --git a/lib/db/access.php b/lib/db/access.php
index 7b23058838a51..6267042c3f645 100644
--- a/lib/db/access.php
+++ b/lib/db/access.php
@@ -1015,8 +1015,27 @@
'legacy' => array(
'user' => CAP_ALLOW
)
- )
-
+ ),
+
+ 'moodle/notes:view' => array(
+ 'captype' => 'read',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'legacy' => array(
+ 'teacher' => CAP_ALLOW,
+ 'editingteacher' => CAP_ALLOW,
+ 'admin' => CAP_ALLOW
+ )
+ ),
+
+ 'moodle/notes:manage' => array(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'legacy' => array(
+ 'teacher' => CAP_ALLOW,
+ 'editingteacher' => CAP_ALLOW,
+ 'admin' => CAP_ALLOW
+ )
+ ),
);
?>
diff --git a/lib/weblib.php b/lib/weblib.php
index 6bb1835bdc808..6ca90a4e73298 100644
--- a/lib/weblib.php
+++ b/lib/weblib.php
@@ -3744,7 +3744,11 @@ function print_user($user, $course, $messageselect=false, $return=false) {
if ($CFG->bloglevel > 0) {
$output .= ''.get_string('blogs','blog').'
';
}
-
+ //link to notes
+ if (has_capability('moodle/notes:manage', $context) || has_capability('moodle/notes:view', $context)) {
+ $output .= ''.get_string('notes','notes').'
';
+ }
+
if (has_capability('moodle/site:viewreports', $context)) {
$timemidnight = usergetmidnight(time());
$output .= ''. $string->activity .'
';
diff --git a/notes/add.php b/notes/add.php
new file mode 100644
index 0000000000000..60fbb91d3c6f3
--- /dev/null
+++ b/notes/add.php
@@ -0,0 +1,76 @@
+id);
+
+// check capability
+if (!has_capability('moodle/notes:manage', $context)) {
+ error('You may not create notes');
+}
+
+// build-up form
+require_once('edit_form.php');
+// get option values for the user select
+$extradata['userlist'] = array();
+$usersincourse = "SELECT * FROM {$CFG->prefix}user WHERE id IN (SELECT userid FROM {$CFG->prefix}role_assignments WHERE contextid={$context->id})";
+$userlist = get_records_sql($usersincourse);
+// format userdata using fullname
+if($userlist) {
+ foreach($userlist as $user) {
+ $extradata['userlist'][$user->id] = fullname($user);
+ }
+}
+// create form
+$noteform = new note_edit_form(null, $extradata);
+
+// if form was cancelled then return to the previous notes list
+if ($noteform->is_cancelled()) {
+ redirect($CFG->wwwroot . '/notes/index.php?course=' . $courseid . '&user=' . $userid);
+}
+
+// if data was submitted and validated, then save it to database
+if ($formdata = $noteform->get_data()) {
+ $note = new object();
+ $note->courseid = $formdata->course;
+ $note->content = $formdata->content;
+ $note->format = FORMAT_PLAIN;
+ $note->rating = $formdata->rating;
+ $note->userid = $formdata->user;
+ $note->publishstate = $formdata->publishstate;
+ if (note_save($note)) {
+ add_to_log($note->courseid, 'notes', 'add', 'index.php?course='.$note->courseid.'&user='.$note->userid . '#note-' . $note->id , 'add note');
+ }
+// redirect to notes list that contains this note
+ redirect($CFG->wwwroot . '/notes/index.php?course=' . $note->courseid . '&user=' . $note->userid);
+}
+
+if($noteform->is_submitted()) {
+// if data was submitted with errors, then use it as default for new form
+ $note = $noteform->get_submitted_data(false);
+} else {
+// if data was not submitted yet, then use default values
+ $note = new object();
+ $note->id = 0;
+ $note->course = $courseid;
+ $note->user = $userid;
+
+}
+$noteform->set_data($note);
+$strnotes = get_string('notes', 'notes');
+
+// output HTML
+print_header($course->shortname . ': ' . $strnotes, $course->fullname);
+$noteform->display();
+print_footer();
diff --git a/notes/delete.php b/notes/delete.php
new file mode 100644
index 0000000000000..e7de35cda9734
--- /dev/null
+++ b/notes/delete.php
@@ -0,0 +1,46 @@
+courseid)) {
+ error('Incorrect course id found');
+}
+
+// locate context information
+$context = get_context_instance(CONTEXT_COURSE, $course->id);
+
+// check capability
+if (!has_capability('moodle/notes:manage', $context)) {
+ error('You may not delete this note');
+}
+
+if (data_submitted() && confirm_sesskey()) {
+//if data was submitted and is valid, then delete note
+ $returnurl = $CFG->wwwroot . '/notes/index.php?course=' . $course->id . '&user=' . $note->userid;
+ if (note_delete($noteid)) {
+ add_to_log($note->courseid, 'notes', 'delete', 'index.php?course='.$note->courseid.'&user='.$note->userid . '#note-' . $note->id , 'delete note');
+ } else {
+ error('Error occured while deleting post', $returnurl);
+ }
+ redirect($returnurl);
+} else {
+// if data was not submitted yet, then show note data with a delete confirmation form
+ $strnotes = get_string('notes', 'notes');
+ $optionsyes = array('note'=>$noteid, 'sesskey'=>sesskey());
+ $optionsno = array('course'=>$course->id, 'user'=>$note->userid);
+ print_header($course->shortname . ': ' . $strnotes, $course->fullname);
+ notice_yesno(get_string('deleteconfirm', 'notes'), 'delete.php', 'index.php', $optionsyes, $optionsno, 'post', 'get');
+ echo '
';
+ note_print($note, NOTES_SHOW_BODY | NOTES_SHOW_HEAD);
+ print_footer();
+}
diff --git a/notes/edit.php b/notes/edit.php
new file mode 100644
index 0000000000000..48c04d4291c1f
--- /dev/null
+++ b/notes/edit.php
@@ -0,0 +1,82 @@
+courseid)) {
+ error('Incorrect course id found');
+}
+
+// locate context information
+$context = get_context_instance(CONTEXT_COURSE, $course->id);
+
+// check capability
+if (!has_capability('moodle/notes:manage', $context)) {
+ error('You may not modify notes');
+}
+
+// build-up form
+require_once('edit_form.php');
+// get option values for the user select
+$extradata['userlist'] = array();
+if ($course->id == SITEID) {
+ $usersincourse = "SELECT * FROM {$CFG->prefix}user WHERE id={$userid}";
+} else {
+ $usersincourse = "SELECT * FROM {$CFG->prefix}user WHERE id IN (SELECT userid FROM {$CFG->prefix}role_assignments WHERE contextid={$context->id})";
+}
+$userlist = get_records_sql($usersincourse);
+// format userdata using fullname
+if($userlist) {
+ foreach($userlist as $user) {
+ $extradata['userlist'][$user->id] = fullname($user);
+ }
+}
+// create form
+$noteform = new note_edit_form(null, $extradata);
+
+// if form was cancelled then return to the notes list of the note
+if ($noteform->is_cancelled()) {
+ redirect($CFG->wwwroot . '/notes/index.php?course=' . $note->courseid . '&user=' . $note->userid);
+}
+
+// if data was submitted and validated, then save it to database
+if ($formdata = $noteform->get_data()){
+ $note->courseid = $formdata->course;
+ $note->userid = $formdata->user;
+ $note->content = $formdata->content;
+ $note->format = FORMAT_PLAIN;
+ $note->rating = $formdata->rating;
+ $note->publishstate = $formdata->publishstate;
+ if (note_save($note)) {
+ add_to_log($note->courseid, 'notes', 'update', 'index.php?course='.$note->courseid.'&user='.$note->userid . '#note-' . $note->id, 'update note');
+ }
+// redirect to notes list that contains this note
+ redirect($CFG->wwwroot . '/notes/index.php?course=' . $note->courseid . '&user=' . $note->userid);
+}
+
+
+if($noteform->is_submitted()) {
+// if data was submitted with errors, then use it as default for new form
+ $note = $noteform->get_submitted_data(false);
+}else{
+// if data was not submitted yet, then used values retrieved from the database
+ $note->user = $note->userid;
+ $note->course = $note->courseid;
+ $note->note = $note->id;
+}
+$noteform->set_data($note);
+$strnotes = get_string('notes', 'notes');
+
+// output HTML
+print_header($course->shortname . ': ' . $strnotes, $course->fullname);
+$noteform->display();
+print_footer();
diff --git a/notes/edit_form.php b/notes/edit_form.php
new file mode 100644
index 0000000000000..0816f1c661fdd
--- /dev/null
+++ b/notes/edit_form.php
@@ -0,0 +1,35 @@
+libdir.'/formslib.php');
+
+class note_edit_form extends moodleform {
+
+ function definition() {
+ $mform =& $this->_form;
+
+ $mform->addElement('header', 'general', get_string('general', 'form'));
+
+ $mform->addElement('select', 'user', get_string('user'), $this->_customdata['userlist']);
+ $mform->addRule('user', get_string('nouser', 'notes'), 'required', null, 'client');
+
+ $mform->addElement('textarea', 'content', get_string('content', 'notes'), array('rows'=>15, 'cols'=>40));
+ $mform->setType('content', PARAM_RAW);
+ $mform->addRule('content', get_string('nocontent', 'notes'), 'required', null, 'client');
+ $mform->setHelpButton('content', array('writing', 'richtext'), false, 'editorhelpbutton');
+
+ $mform->addElement('select', 'rating', get_string('rating', 'notes'), note_get_rating_names());
+ $mform->setDefault('rating', 3);
+
+ $mform->addElement('select', 'publishstate', get_string('publishstate', 'notes'), note_get_state_names());
+ $mform->setDefault('publishstate', NOTES_STATE_PUBLIC);
+ $mform->setType('publishstate', PARAM_ALPHA);
+
+ $this->add_action_buttons();
+
+ $mform->addElement('hidden', 'course');
+ $mform->setType('course', PARAM_INT);
+
+ $mform->addElement('hidden', 'note');
+ $mform->setType('note', PARAM_INT);
+ }
+}
diff --git a/notes/index.php b/notes/index.php
new file mode 100644
index 0000000000000..1720558742f0d
--- /dev/null
+++ b/notes/index.php
@@ -0,0 +1,77 @@
+id;
+} else {
+ $filtertype = 'course';
+ $filterselect = $course->id;
+}
+
+// require login to access notes
+require_login($course->id);
+$strnotes = get_string('notes', 'notes');
+$crumbs = array(array('name' => $strnotes, 'link' => '', 'type' => 'activity'));
+$currenttab = 'notes';
+// output HTML
+print_header($course->shortname . ': ' . $strnotes, $course->fullname, build_navigation($crumbs));
+
+require_once($CFG->dirroot .'/user/tabs.php');
+
+if($courseid != SITEID) {
+ $context = get_context_instance(CONTEXT_COURSE, $courseid);
+ if (has_capability('moodle/notes:manage', $context)) {
+ $addlink = $CFG->wwwroot .'/notes/add.php?course=' . $courseid . '&user=' . $userid;
+ echo '
' . get_string('addnewnote', 'notes') . '
'; + } + note_print_notes(get_string('sitenotes', 'notes'), $context, 0, $userid, NOTES_STATE_SITE, 0); + note_print_notes(get_string('coursenotes', 'notes'), $context, $courseid, $userid, NOTES_STATE_PUBLIC, 0); + note_print_notes(get_string('personalnotes', 'notes'), $context, $courseid, $userid, NOTES_STATE_DRAFT, $USER->id); +} else { + $context = get_context_instance(CONTEXT_SYSTEM); + note_print_notes(get_string('sitenotes', 'notes'), $context, 0, $userid, NOTES_STATE_SITE, 0); + if($userid) { + $courses = get_my_courses($userid); + foreach($courses as $c) { + $header = '' . $c->fullname . ''; + note_print_notes($header, $context, $c->id, $userid, NOTES_STATE_PUBLIC, 0); + } + } +} + +add_to_log($courseid, 'notes', 'view', 'index.php?course='.$courseid.'&user='.$userid, 'view notes'); + +print_footer($course); diff --git a/notes/lib.php b/notes/lib.php new file mode 100644 index 0000000000000..b097580ceb26f --- /dev/null +++ b/notes/lib.php @@ -0,0 +1,278 @@ +module = 'notes'; + $note->lastmodified = time(); + $note->usermodified = $USER->id; + if(empty($note->rating)) { + $note->rating = NOTES_RATING_NORMAL; + } + if(empty($note->format)) { + $note->format = FORMAT_PLAIN; + } + if(empty($note->publishstate)) { + $note->publishstate = NOTES_STATE_PUBLIC; + } + // save data + if(empty($note->id)) { + // insert new note + $note->created = $note->lastmodified; + if($id = insert_record('post', $note)) { + $note->id = $id; + $result = true; + } else { + $result = false; + } + } else { + // update old note + $result = update_record('post', $note); + } + unset($note->module); + return $result; +} + +/** + * Deletes a note object based on its id. + * + * @param int $note_id id of the note to delete + * @return boolean true if the object was deleted; false otherwise + */ +function note_delete($noteid) { + return delete_records_select('post', 'id=' . $noteid . ' AND module="notes"'); +} + +/** + * Converts a rating value to its corespondent name + * + * @param int $rating rating value to convert + * @return string corespondent rating name + */ +function note_get_rating_name($rating) { + // cache rating names + static $ratings; + if (empty($ratings)) { + $ratings =& note_get_rating_names(); + } + return @$ratings[$rating]; +} + +/** + * Returns an array of mappings from rating values to rating names + * + * @return array of mappings + */ +function note_get_rating_names() { + return array( + 1 => get_string('low', 'notes'), + 2 => get_string('belownormal', 'notes'), + 3 => get_string('normal', 'notes'), + 4 => get_string('abovenormal', 'notes'), + 5 => get_string('high', 'notes'), + ); +} + +/** + * Converts a state value to its corespondent name + * + * @param string $state state value to convert + * @return string corespondent state name + */ +function note_get_state_name($state) { + // cache state names + static $states; + if (empty($states)) { + $states = note_get_state_names(); + } + return @$states[$state]; +} + +/** + * Returns an array of mappings from state values to state names + * + * @return array of mappings + */ +function note_get_state_names() { + return array( + NOTES_STATE_DRAFT => get_string('personal', 'notes'), + NOTES_STATE_PUBLIC => get_string('course', 'notes'), + NOTES_STATE_SITE => get_string('site', 'notes'), + ); +} + +/** + * Prints a note object + * + * @param note $note the note object to print + * @param int $detail OR-ed NOTES_SHOW_xyz flags that specify which note parts to print + */ +function note_print($note, $detail = NOTES_SHOW_FULL) { + + global $CFG, $USER; + $user = get_record('user','id',$note->userid); + $context = get_context_instance(CONTEXT_COURSE, $note->courseid); + $sitecontext = get_context_instance(CONTEXT_SYSTEM); + $authoring->name = fullname(get_record('user','id',$note->usermodified)); + $authoring->date = userdate($note->lastmodified); + echo '' . get_string('nonotes', 'notes') . '
'; + } + } else { + echo '' . get_string('notesnotvisible', 'notes') . '
'; + } +} diff --git a/notes/version.php b/notes/version.php new file mode 100644 index 0000000000000..fe471b86d92d1 --- /dev/null +++ b/notes/version.php @@ -0,0 +1,9 @@ +cron = 1800; // Period for cron to check this module (secs) diff --git a/theme/standard/styles_layout.css b/theme/standard/styles_layout.css index d1b8fc8b5bed0..400132642fc42 100644 --- a/theme/standard/styles_layout.css +++ b/theme/standard/styles_layout.css @@ -19,6 +19,8 @@ grades login message + notes + mymoodle question tabs user @@ -2347,6 +2349,52 @@ body#message-messages { padding:10px; } +/*** + *** Notes + ***/ +.notepost { + margin-bottom: 1em; + background-color: #F0F0F0; +} +.sitenotepost { + background-color: #FFFFF0; +} +.coursenotepost { +} +.draftnotepost { + background-color: #F0FFF0; +} + +.ownnotepost .info { + font-weight: bolder; +} + +.notepost .header { +} + +.notepost .user { + font-weight: bolder; +} + +.notepost .userpicture { + float: left; + margin: 5px; +} +.notepost .rating5 { + color: red; +} +.notepost .rating1 { + color: orange; +} +.notepost .info, .notepost .rating { + font-size: smaller; +} + +.notepost .content { +} + +.notepost .footer { +} /*** *** MyMoodle diff --git a/user/action_redir.php b/user/action_redir.php index 4351c3f3918d4..9880d356f99d2 100644 --- a/user/action_redir.php +++ b/user/action_redir.php @@ -13,6 +13,8 @@ 'messageselect.php', 'extendenrol.php', 'groupextendenrol.php', + 'addnote.php', + 'groupaddnote.php', ); if (array_search($formaction, $actions) === false) { diff --git a/user/addnote.php b/user/addnote.php new file mode 100644 index 0000000000000..731e283bf145b --- /dev/null +++ b/user/addnote.php @@ -0,0 +1,91 @@ +dirroot .'/notes/lib.php'); + +$id = required_param('id', PARAM_INT); // course id +$users = optional_param('userid', array(), PARAM_INT); // array of user id +$contents = optional_param('contents', array(), PARAM_RAW); // array of user notes +$ratings = optional_param('ratings', array(), PARAM_INT); // array of notes ratings +$states = optional_param('states', array(), PARAM_ALPHA); // array of notes states +if (! $course = get_record('course', 'id', $id)) { + error("Course ID is incorrect"); +} + +$context = get_context_instance(CONTEXT_COURSE, $id); +require_login($course->id); + +// to create notes the current user needs a capability +require_capability('moodle/notes:manage', $context); + +if (!empty($users) && confirm_sesskey()) { + if (count($users) != count($contents) || count($users) != count($ratings) || count($users) != count($states)) { + error('Parameters malformation', $CFG->wwwroot.'/user/index.php?id='.$id); + } + + $note = new object(); + $note->courseid = $id; + $note->format = FORMAT_PLAIN; + foreach ($users as $k => $v) { + if(!$user = get_record('user', 'id', $v) || empty($contents[$k])) { + continue; + } + $note->id = 0; + $note->content = $contents[$k]; + $note->rating = $ratings[$k]; + $note->publishstate = $states[$k]; + $note->userid = $v; + if (note_save($note)) { + add_to_log($note->courseid, 'notes', 'add', 'index.php?course='.$note->courseid.'&user='.$note->userid . '#note-' . $note->id , 'add note'); + } + } + redirect("$CFG->wwwroot/user/index.php?id=$id"); +} + +/// Print headers + +$straddnote = get_string('addnewnote', 'notes'); +if ($course->id != SITEID) { + print_header("$course->shortname: ".get_string('extendenrol'), $course->fullname, + "id\">$course->shortname -> ". + $straddnote, "", "", true, " ", navmenu($course)); +} else { + print_header("$course->shortname: ".get_string('extendenrol'), $course->fullname, + $straddnote, "", "", true, " ", navmenu($course)); +} + +// this will contain all available the based On select options, but we'll disable some on them on a per user basis + +print_heading($straddnote); +echo ''; +print_footer($course); diff --git a/user/groupaddnote.php b/user/groupaddnote.php new file mode 100644 index 0000000000000..c0fa9562c0407 --- /dev/null +++ b/user/groupaddnote.php @@ -0,0 +1,90 @@ +dirroot .'/notes/lib.php'); + +$id = required_param('id', PARAM_INT); // course id +$users = optional_param('userid', array(), PARAM_INT); // array of user id +$content = optional_param('content', '', PARAM_RAW); // note content +$rating = optional_param('rating', 0, PARAM_INT); // note rating +$state = optional_param('state', '', PARAM_ALPHA); // note publish state + +if (! $course = get_record('course', 'id', $id)) { + error("Course ID is incorrect"); +} + +$context = get_context_instance(CONTEXT_COURSE, $id); +require_login($course->id); + +// to create notes the current user needs a capability +require_capability('moodle/notes:manage', $context); + +if (!empty($users) && !empty($content) && confirm_sesskey()) { + $note = new object(); + $note->courseid = $id; + $note->format = FORMAT_PLAIN; + $note->content = $content; + $note->rating = $rating; + $note->publishstate = $state; + foreach ($users as $k => $v) { + if(!$user = get_record('user', 'id', $v)) { + continue; + } + $note->id = 0; + $note->userid = $v; + if (note_save($note)) { + add_to_log($note->courseid, 'notes', 'add', 'index.php?course='.$note->courseid.'&user='.$note->userid . '#note-' . $note->id , 'add note'); + } + } + + redirect("$CFG->wwwroot/user/index.php?id=$id"); +} + +/// Print headers + +$straddnote = get_string('groupaddnewnote', 'notes'); +if ($course->id != SITEID) { + print_header("$course->shortname: ".get_string('extendenrol'), $course->fullname, + "id\">$course->shortname -> ". + $straddnote, "", "", true, " ", navmenu($course)); +} else { + print_header("$course->shortname: ".get_string('extendenrol'), $course->fullname, + $straddnote, "", "", true, " ", navmenu($course)); +} + +// this will contain all available the based On select options, but we'll disable some on them on a per user basis + +print_heading($straddnote); +echo ''; +print_footer($course); diff --git a/user/index.php b/user/index.php index 1beca2599b9ca..9537a78c0dfaa 100644 --- a/user/index.php +++ b/user/index.php @@ -597,7 +597,10 @@ function checkchecked(form) { if (has_capability('moodle/site:readallmessages', $context) && !empty($CFG->messaging)) { $displaylist['messageselect.php'] = get_string('messageselectadd'); } - + if (has_capability('moodle/notes:manage', $context)) { + $displaylist['addnote.php'] = get_string('addnewnote', 'notes'); + $displaylist['groupaddnote.php'] = get_string('groupaddnewnote', 'notes'); + } $displaylist['extendenrol.php'] = get_string('extendenrol'); $displaylist['groupextendenrol.php'] = get_string('groupextendenrol'); diff --git a/user/tabs.php b/user/tabs.php index 9e47313dc1813..71c4103cb9acb 100644 --- a/user/tabs.php +++ b/user/tabs.php @@ -49,16 +49,20 @@ } else if ($filtertype == 'course' && $filterselect) { $course = get_record('course','id',$filterselect); + $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); print_heading(format_string($course->fullname)); - if ($CFG->bloglevel >= 3) { - - $toprow[] = new tabobject('participants', $CFG->wwwroot.'/user/index.php?id='.$filterselect.'&group=0', - get_string('participants')); //the groupid hack is necessary, otherwise the group in the session willbe used + $toprow[] = new tabobject('participants', $CFG->wwwroot.'/user/index.php?id='.$filterselect.'&group=0', + get_string('participants')); //the groupid hack is necessary, otherwise the group in the session willbe used + if ($CFG->bloglevel >= 3) { $toprow[] = new tabobject('blogs', $CFG->wwwroot.'/blog/index.php?filtertype=course&filterselect='.$filterselect, get_string('blogs','blog')); } + if (has_capability('moodle/notes:manage', $coursecontext) || has_capability('moodle/notes:view', $coursecontext)) { + $toprow[] = new tabobject('notes', $CFG->wwwroot.'/notes/index.php?filtertype=course&filterselect=' . $filterselect, get_string('notes', 'notes')); + } + /************************************** * Group Level participation or Blogs * **************************************/ @@ -167,6 +171,10 @@ $toprow[] = new tabobject('blogs', $CFG->wwwroot.'/blog/index.php?userid='.$user->id.'&courseid='.$course->id, get_string('blog', 'blog')); } + if (has_capability('moodle/notes:manage', $coursecontext) || has_capability('moodle/notes:view', $coursecontext)) { + $toprow[] = new tabobject('notes', $CFG->wwwroot.'/notes/index.php?course='.$course->id . '&user=' . $user->id, get_string('notes', 'notes')); + } + /// Current user must be teacher of the course or the course allows user to view their reports //print_object($course);