function annotation_summary_query($a)
 {
     $this->moodlemia = moodle_marginalia::get_instance();
     if ($a) {
         $this->from_params($a);
     }
 }
Exemple #2
0
 function moodle_keyword_service($userid)
 {
     global $CFG;
     $moodlemia = moodle_marginalia::get_instance();
     KeywordService::KeywordService($moodlemia->get_host(), $moodlemia->get_keyword_service_path(), $userid, $CFG->wwwroot);
     $this->tablePrefix = $CFG->prefix;
 }
 public static function get_instance()
 {
     if (!moodle_marginalia::$singleton) {
         moodle_marginalia::$singleton = new moodle_marginalia();
     }
     return moodle_marginalia::$singleton;
 }
Exemple #4
0
if (!empty($parent) && !forum_user_can_see_post($forum, $discussion, $post, null, $cm)) {
    print_error('cannotreply', 'forum');
}
if (empty($parent) && empty($edit) && !forum_user_can_post_discussion($forum, $groupid, -1, $cm, $modcontext)) {
    print_error('cannotcreatediscussion', 'forum');
}
if ($forum->type == 'qanda' && !has_capability('mod/forum:viewqandawithoutposting', $modcontext) && !empty($discussion->id) && !forum_user_has_posted($forum->id, $discussion->id, $USER->id)) {
    echo $OUTPUT->notification(get_string('qandanotify', 'forum'));
}
forum_check_throttling($forum, $cm);
if (!empty($parent)) {
    if (!($discussion = $DB->get_record('forum_discussions', array('id' => $parent->discussion)))) {
        print_error('notpartofdiscussion', 'forum');
    }
    // #marginalia begin
    $moodlemia = moodle_marginalia::get_instance();
    $miaprofile = $moodlemia->get_profile($PAGE->url->out(false));
    if ($miaprofile) {
        $miaprofile->emit_body();
        $miaprofile->emit_margin_controls();
    }
    // #marginalia end
    forum_print_post($parent, $discussion, $forum, $cm, $course, false, false, false);
    if (empty($post->edit)) {
        if ($forum->type != 'qanda' || forum_user_can_see_discussion($forum, $discussion, $modcontext)) {
            $forumtracked = forum_tp_is_tracked($forum);
            $posts = forum_get_all_discussion_posts($discussion->id, "created ASC", $forumtracked);
            forum_print_posts_threaded($course, $cm, $forum, $discussion, $parent, 0, false, $forumtracked, $posts);
        }
    }
} else {
Exemple #5
0
 function show_html($annotations, $annotation_count)
 {
     global $CFG, $USER, $PAGE, $OUTPUT, $DB;
     $PAGE->set_url($this->summary->summary_url());
     $blockpath = '/blocks/marginalia';
     // was ANNOTATION_PATH
     $PAGE->requires->css($blockpath . '/summary-styles.php');
     // This loads way more than is needed here, but reduces code paths
     // and hence bugs.
     $moodlemia = moodle_marginalia::get_instance();
     $profile = $moodlemia->get_profile($this->summary->summary_url());
     $profile->emit_requires();
     $PAGE->requires->js($blockpath . '/summary.js', true);
     // Get the course.  This can't be passed as a GET parameter because this URL could be via the
     // Atom feed, and the Atom feed is generated exclusively by annotation code which doesn't know
     // that much about Moodle.  So the handler has to query it based on a discussion ID or the like.
     $this->course = null;
     $this->courseid = $this->summary->handler->courseid;
     if (null != $this->courseid) {
         if (!($this->course = $DB->get_record("course", array('id' => $this->courseid)))) {
             error("Course ID is incorrect");
         }
         // Ok, now this is probably very wrong.  If the user looks for annotations within a course,
         // it requires a login.  Without the course (i.e. in a more general search), it doesn't!
         // I would eleminate this, but I don't really know how Moodle security works. #geof#
         if ($this->course->category) {
             require_login($this->course->id);
         }
     }
     // #geof#: not quite correct - should fetch the URL from the summary object
     $PAGE->set_url('/mod/forum/summary.php');
     if (null != $this->course) {
         $PAGE->set_title($this->course->shortname . ": " . get_string('summary_title', ANNOTATION_STRINGS));
         $PAGE->set_heading($this->course->fullname);
     } else {
         $PAGE->set_title(get_string('summary_title', ANNOTATION_STRINGS));
         $PAGE->set_heading(get_string('summary_title', ANNOTATION_STRINGS));
     }
     // #geof# Must change to split requires from inline JS:
     if ($this->logger && $this->logger->is_active()) {
         $this->logger->header_html();
     }
     if (null != $this->course && $this->course->category) {
         $PAGE->navbar->add($this->course->shortname, $CFG->wwwroot . '/course/view.php?id=' . $this->course->id);
     }
     $PAGE->navbar->add(get_string('summary_title', ANNOTATION_STRINGS));
     echo $OUTPUT->header();
     $swwwroot = htmlspecialchars($CFG->wwwroot);
     if (isloggedin()) {
         $profile->emit_body();
         $sannotationpath = s(ANNOTATION_PATH);
         echo "<script language='JavaScript' type='text/javascript'>\n" . "var annotationService = new RestAnnotationService('{$sannotationpath}/annotate.php', " . "{ csrfCookie: 'MoodleSession" . $CFG->sessioncookie . "', noPutDelete: true } );\n" . "window.annotationSummary = new AnnotationSummary('{$swwwroot}', {" . " \n annotationService: annotationService" . ",\n userid: " . (int) $USER->id . ",\n useLog: " . ($this->logger && $this->logger->is_active() ? 'true' : 'false') . ",\n csrfCookie: 'MoodleSession" . $CFG->sessioncookie . "'" . "} );\n" . "window.preferences = new Preferences( new RestPreferenceService('{$sannotationpath}/user-preference.php' ) );\n" . "</script>\n";
     }
     // Needed later to determine whether a given annotation is a keyword
     $keywords = isloggedin() ? annotation_keywords_db::list_keywords($USER->id) : array();
     $keywordhash = array();
     for ($i = 0; $i < count($keywords); ++$i) {
         $keyword = $keywords[$i];
         $keywordhash[$keyword->name] = true;
     }
     // print search header
     //  * my annotations
     //  * shared annotations
     //  * instructor annotations
     //  * annotations of my work
     echo "<form id='annotation-search' method='get' action='summary.php'>\n";
     echo "<fieldset>\n";
     echo "<label for=''>" . get_string('prompt_find', ANNOTATION_STRINGS) . "</label>\n";
     if ($this->summary->ofuser) {
         echo "<input type='hidden' name='search-of' id='search-of' value='" . s($this->moodlemia->fullname($this->summary->ofuser)) . "'/>\n";
     }
     if ($this->summary->user) {
         echo "<input type='hidden' name='u' id='u' value='" . s($this->moodlemia->fullname($this->summary->user)) . "'/>\n";
     }
     echo "<input type='text' id='search-text' name='q' value='" . s($this->summary->text) . "'/>\n";
     echo "<input type='submit' value='" . get_string('go') . "'/>\n";
     echo "<input type='hidden' name='url' value='" . s($this->summary->url) . "'/>\n";
     //		echo $OUTPUT->help_icon( 'annotation_summary', ANNOTATION_STRINGS ); //'block_marginalia', get_string( 'summary_help', ANNOTATION_STRINGS ) );
     echo "</fieldset>\n";
     echo "</form>";
     // If this page is an error, explain what it's about
     if ('range-mismatch' == $this->errorpage) {
         echo '<p class="error"><em class="range-error">!</em>' . get_string('summary_range_error', ANNOTATION_STRINGS) . "</p>\n";
     }
     $a = new object();
     $a->n = $annotations ? count($annotations) : 0;
     $a->m = $annotation_count;
     echo '<p id="query">' . get_string('prompt_search_desc', ANNOTATION_STRINGS, $a) . ' ' . $this->summary->desc_with_links(null) . ":</p>\n";
     $cursection = null;
     $cursectiontype = null;
     $curuser = null;
     $cururl = null;
     // make sure some records came back
     if (null != $annotations) {
         // Convert $annotations to an indexable array (why isn't it?  for efficiency with large data sets?)
         $annotationa = array();
         foreach ($annotations as $annotation) {
             $annotationa[] = $annotation;
         }
         $ncols = 6;
         if (AN_SUMMARY_ORDER_TIME == $this->summary->orderby) {
             $ncols += 1;
         }
         echo '<table cellspacing="0" class="annotations">' . "\n";
         for ($annotationi = 0; $annotationi < count($annotationa); ++$annotationi) {
             $annotation = $annotationa[$annotationi];
             // Display a heading for each new section URL
             if ($annotation->section_type != $cursectiontype || $annotation->section_url != $cursection) {
                 if ($cursection != null) {
                     echo "</tbody>\n";
                 }
                 echo "<thead><tr><th colspan='{$ncols}'>";
                 $a->section_type = htmlspecialchars($annotation->section_type);
                 echo '<h3>' . s($annotation->section_type) . '</h3>: ' . "<a href='" . s($annotation->section_url) . "' title='" . get_string('prompt_section', ANNOTATION_STRINGS, $a) . "'>" . s($annotation->section_name) . "</a>";
                 if ($annotation->section_url != $this->summary->url) {
                     $tsummary = $this->summary->derive(array('url' => $annotation->section_url));
                     $turl = $tsummary->summary_url();
                     echo "<a class='zoom' title='" . get_string('zoom_url_hover', ANNOTATION_STRINGS, $annotation) . "' href='" . s($turl) . "'>" . AN_FILTERICON_HTML . "</a>\n";
                 }
                 echo '</th></tr></thead>' . "\n";
                 if (AN_SUMMARYHEADINGSTOP) {
                     $this->show_column_headings($this->summary, 'top');
                 }
                 echo '<tbody>' . "\n";
                 $cursection = $annotation->section_url;
                 $cursectiontype = $annotation->section_type;
                 $curuser = $annotation->userid;
                 $cururl = null;
             }
             // For each new url, display the title and author
             if ($annotation->url != $cururl) {
                 //|| $annotation->userid != $curUser ) {
                 $cururl = $annotation->url;
                 $curuser = $annotation->userid;
                 echo "<tr class='fragment first'>";
                 // Figure out how many rows this source will span
                 $nrows = 1;
                 for ($j = $annotationi + 1; $j < count($annotationa); ++$j) {
                     if ($annotationa[$j]->url != $cururl) {
                         break;
                     }
                     $nrows += 1;
                 }
                 // Only prefix the URL with the site root if it doesn't already have a scheme
                 // Only check for http and https schemes to prevent obscure attacks
                 $url = $annotation->url;
                 if (!(str_startswith($url, 'http://') || str_startswith($url, 'https://'))) {
                     $url = $CFG->wwwroot . $annotation->url;
                 }
                 echo "<th rowspan='{$nrows}'>";
                 $url = MarginaliaHelper::isUrlSafe($url) ? $url : '';
                 $a->row_type = $annotation->row_type;
                 $a->author = $this->moodlemia->fullname2($annotation->quote_author_firstname, $annotation->quote_author_lastname);
                 echo "<a class='url' href='" . s($url) . "' title='" . get_string('prompt_row', ANNOTATION_STRINGS, $a) . "'>";
                 echo s($annotation->quote_title) . '</a>';
                 echo "<br/>by <span class='quote-author'>" . s($a->author) . "</span>\n";
                 // Link to filter only annotations by this user
                 if (!$this->summary->ofuser || $annotation->quote_author_username != $this->summary->ofuser->username) {
                     $tsummary = $this->summary->derive(array('ofuserid' => $annotation->quote_author_id));
                     $turl = $tsummary->summary_url();
                     $a->fullname = $this->moodlemia->fullname2($annotation->quote_author_firstname, $annotation->quote_author_lastname);
                     echo $this->zoom_link($tsummary->summary_url(), get_string('zoom_author_hover', ANNOTATION_STRINGS, $a));
                 }
                 echo "</th>\n";
             } else {
                 echo "<tr>";
             }
             // Show the quoted text
             echo "<td class='quote'>";
             p($annotation->quote);
             echo "</td>\n";
             // Show the note
             echo "<td class='note'>";
             if (!$annotation->note) {
                 echo '&#160;';
             } else {
                 echo s($annotation->note);
             }
             if (!$this->summary->exactmatch && array_key_exists($annotation->note, $keywordhash)) {
                 $tsummary = $this->summary->derive(array('text' => $annotation->note, 'exactmatch' => true));
                 echo ' ' . $this->zoom_link($tsummary->summary_url(), get_string('zoom_match_hover', ANNOTATION_STRINGS));
             }
             echo "</td>\n";
             // Show annotation time (if requested)
             if (AN_SUMMARY_ORDER_TIME == $this->summary->orderby) {
                 echo "<td class='modified'>" . s(date('Y-m-d G:i', $annotation->modified)) . "</td>\n";
             }
             // Show edit controls or the user who created the annotation
             echo "<td class='user" . (isloggedin() && $annotation->userid == $USER->id ? ' isloginuser' : '') . "'>\n";
             // Smartquote button
             if (AN_USESMARTQUOTE) {
                 // $SMARTQUOTE_SYMBOL = AN_SMARTQUOTEICON_PHP; //'&#9850;';
                 $sqid = s('sq' . $annotation->id);
                 $sqtitle = get_string('smartquote_annotation', ANNOTATION_STRINGS);
                 echo "<button class='smartquote' id='{$sqid}' title='{$sqtitle}'>" . AN_SMARTQUOTEICON_HTML . "</button>\n";
             }
             // Controls for current user
             if (isloggedin() && $annotation->userid == $USER->id) {
                 $delid = s('del' . $annotation->id);
                 $deltitle = get_string('js_delete_annotation_button', ANNOTATION_STRINGS);
                 echo "<button class='delete-button' id='{$delid}' title='{$deltitle}'>x</button>\n";
             }
             // User name (or "me" for current user)
             $displayusername = s($this->moodlemia->fullname2($annotation->firstname, $annotation->lastname));
             $hiddenusername = '';
             $class = 'user-name';
             if (isloggedin() && $annotation->userid == $USER->id) {
                 $hiddenusername = "******";
                 $displayusername = get_string('me', ANNOTATION_STRINGS);
                 $class = '';
             }
             $url = $CFG->wwwroot . $annotation->url;
             if (MarginaliaHelper::isUrlSafe($url)) {
                 echo "<a class='{$class}' onclick='setAnnotationUser(\"" . s($annotation->userid) . "\")' href='" . s($url) . "'>" . "{$displayusername}</a>\n";
             } else {
                 echo "<span class='{$class}'>{$displayusername}</span>\n";
             }
             echo $hiddenusername;
             // Link to filter only annotations by this user
             if (!$this->summary->user || $annotation->userid != $this->summary->user->username) {
                 $tsummary = $this->summary->derive(array('userid' => $annotation->userid));
                 $turl = $tsummary->summary_url();
                 $a->fullname = $this->moodlemia->fullname2($annotation->firstname, $annotation->lastname);
                 echo $this->zoom_link($tsummary->summary_url(), get_string('zoom_user_hover', ANNOTATION_STRINGS, $a));
             }
             echo "</td>\n";
             echo "</tr>\n";
         }
         // Build scripts for individual buttons
         echo "<script type='text/javascript'>\n";
         for ($annotationi = 0; $annotationi < count($annotationa); ++$annotationi) {
             $annotation = $annotationa[$annotationi];
             if (AN_USESMARTQUOTE) {
                 // HTML ID of smartquote button
                 $sqid = s('sq' . $annotation->id);
                 $tuserid = s($annotation->userid);
                 echo "  addEvent(document.getElementById('{$sqid}'),'click',function() {" . "    window.annotationSummary.quote('{$sqid}','{$tuserid}'); } );";
             }
             if (isloggedin() && $annotation->userid == $USER->id) {
                 // HTML ID of delete button
                 $delid = s('del' . $annotation->id);
                 echo "  addEvent(document.getElementById('{$delid}'),'click',function() {" . "    window.annotationSummary.deleteAnnotation('{$delid}'," . (int) $annotation->id . "); } );\n";
             }
         }
         echo "</script>\n";
         if ($cururl != null) {
             echo "</tbody>\n";
         }
         if (!AN_SUMMARYHEADINGSTOP) {
             $this->show_column_headings('');
         }
         echo "</table>\n";
     }
     marginalia_summary_lib::show_result_pages($this->first, $annotation_count, $this->maxrecords, $this->summary->summary_url('{first}'));
     /*
     		// Show the list of result pages
     		$npages = ceil( $annotation_count / $this->maxrecords );
     		if ( $npages > 1 )
     		{
     			$this_page = 1 + floor( ( $this->first - 1 ) / $this->maxrecords );
     			echo "<ol class='result-pages'>\n";
     			for ( $i = 1; $i <= $npages;  ++$i )
     			{
     				if ( $i == $this_page )
     					echo "  <li>".$i."</li>\n";
     				else
     					echo "  <li><a href='".s($this->summary->summary_url('{first}')."'>".$i."</a></li>\n";
     			}
     			echo "</ol>\n";
     		}
     */
     //$moodlePath = getMoodlePath( );
     // Link for sorting by date or document order
     if ($this->summary->orderby == AN_SUMMARY_ORDER_DOCUMENT) {
         $tsummary = $this->summary->derive(array('orderby' => AN_SUMMARY_ORDER_TIME));
         echo "<p><a href='" . s($tsummary->summary_url()) . "'>" . get_string('summary_sort_time', ANNOTATION_STRINGS) . "</a></p>\n";
     } else {
         $tsummary = $this->summary->derive(array('orderby' => AN_SUMMARY_ORDER_DOCUMENT));
         echo "<p><a href='" . s($tsummary->summary_url()) . "'>" . get_string('summary_sort_document', ANNOTATION_STRINGS) . "</a></p>\n";
     }
     /*		Feed removed because Moodle should require a login for it to be of much
     		use, and the feed reader would then need to authenticate.  So it's likely
     		to be more frustrating than useful.
     		
     		// Provide a feed URL.  I don't know how to do authentication for the feed, so for now
     		// if a login is required I won't include the feature.
     		if ( ! ANNOTATION_REQUIRE_USER )  {
     			$tsummary = $this->summary->derive( array( 'orderby' => AN_SUMMARY_ORDER_TIME ) );
     			$turl = $tsummary->get_feed_url( 'atom' );
     			echo "<p class='feed' title='".get_string( 'atom_feed', ANNOTATION_STRINGS )
     				."'><a href='".s($turl)."'><img border='0' alt='"
     				.get_string( 'atom_feed', ANNOTATION_STRINGS )."' src='".s( $CFG->wwwroot )."/pix/i/rss.gif'/>"
     				. '</a> '.get_string( 'atom_feed_desc', ANNOTATION_STRINGS )."</p>\n";
     		}
     */
     echo "<p><a href='help.php?component=block_marginalia&topic=annotation_summary'>" . get_string('annotation_summary_help_link', ANNOTATION_STRINGS) . '</a></p>';
     $OUTPUT->footer($this->course);
     $logurl = $_SERVER['REQUEST_URI'];
     $urlparts = parse_url($logurl);
     $logurl = array_key_exists('query', $urlparts) ? $urlparts['query'] : null;
     $this->moodlemia->moodle_log('summary', 'summary.php' . ($logurl ? '?' . $logurl : ''), $this->summary->desc(null));
     // Marginalia logging
     if ($this->logger && $this->logger->is_active()) {
         $this->logger->summarizeAnnotations($this->summary->summary_url(), $this->summary->desc());
     }
 }
Exemple #6
0
 function doDeleteAnnotation($annotation)
 {
     global $USER, $DB;
     if (!$this->can_annotate($annotation->url)) {
         $this->httpError(403, 'Forbidden', 'User lacks permission to annotate.');
         return False;
     } else {
         $DB->delete_records(AN_DBTABLE, array('id' => $annotation->id));
         $DB->delete_records(AN_READ_TABLE, array('annotationid' => $annotation->id));
         if ($this->extService) {
             $extService = $this->extService;
             $extService->deleteAnnotation($annotation->id);
         }
         $moodlemia = moodle_marginalia::get_instance();
         $logurl = "annotate.php?id=" . $annotation->id;
         $moodlemia->moodle_log('delete', $logurl, $annotation->id);
         return True;
     }
 }
Exemple #7
0
/**
 * Print a forum post
 *
 * @global object
 * @global object
 * @uses FORUM_MODE_THREADED
 * @uses PORTFOLIO_FORMAT_PLAINHTML
 * @uses PORTFOLIO_FORMAT_FILE
 * @uses PORTFOLIO_FORMAT_RICHHTML
 * @uses PORTFOLIO_ADD_TEXT_LINK
 * @uses CONTEXT_MODULE
 * @param object $post The post to print.
 * @param object $discussion
 * @param object $forum
 * @param object $cm
 * @param object $course
 * @param boolean $ownpost Whether this post belongs to the current user.
 * @param boolean $reply Whether to print a 'reply' link at the bottom of the message.
 * @param boolean $link Just print a shortened version of the post as a link to the full post.
 * @param string $footer Extra stuff to print after the message.
 * @param string $highlight Space-separated list of terms to highlight.
 * @param int $post_read true, false or -99. If we already know whether this user
 *          has read this post, pass that in, otherwise, pass in -99, and this
 *          function will work it out.
 * @param boolean $dummyifcantsee When forum_user_can_see_post says that
 *          the current user can't see this post, if this argument is true
 *          (the default) then print a dummy 'you can't see this post' post.
 *          If false, don't output anything at all.
 * @param bool|null $istracked
 * @return void
 */
function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost = false, $reply = false, $link = false, $footer = "", $highlight = "", $postisread = null, $dummyifcantsee = true, $istracked = null, $return = false)
{
    global $USER, $CFG, $OUTPUT;
    require_once $CFG->libdir . '/filelib.php';
    // String cache
    static $str;
    $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
    $post->course = $course->id;
    $post->forum = $forum->id;
    $post->message = file_rewrite_pluginfile_urls($post->message, 'pluginfile.php', $modcontext->id, 'mod_forum', 'post', $post->id);
    // caching
    if (!isset($cm->cache)) {
        $cm->cache = new stdClass();
    }
    if (!isset($cm->cache->caps)) {
        $cm->cache->caps = array();
        $cm->cache->caps['mod/forum:viewdiscussion'] = has_capability('mod/forum:viewdiscussion', $modcontext);
        $cm->cache->caps['moodle/site:viewfullnames'] = has_capability('moodle/site:viewfullnames', $modcontext);
        $cm->cache->caps['mod/forum:editanypost'] = has_capability('mod/forum:editanypost', $modcontext);
        $cm->cache->caps['mod/forum:splitdiscussions'] = has_capability('mod/forum:splitdiscussions', $modcontext);
        $cm->cache->caps['mod/forum:deleteownpost'] = has_capability('mod/forum:deleteownpost', $modcontext);
        $cm->cache->caps['mod/forum:deleteanypost'] = has_capability('mod/forum:deleteanypost', $modcontext);
        $cm->cache->caps['mod/forum:viewanyrating'] = has_capability('mod/forum:viewanyrating', $modcontext);
        $cm->cache->caps['mod/forum:exportpost'] = has_capability('mod/forum:exportpost', $modcontext);
        $cm->cache->caps['mod/forum:exportownpost'] = has_capability('mod/forum:exportownpost', $modcontext);
    }
    if (!isset($cm->uservisible)) {
        $cm->uservisible = coursemodule_visible_for_user($cm);
    }
    if ($istracked && is_null($postisread)) {
        $postisread = forum_tp_is_post_read($USER->id, $post);
    }
    if (!forum_user_can_see_post($forum, $discussion, $post, NULL, $cm)) {
        $output = '';
        if (!$dummyifcantsee) {
            if ($return) {
                return $output;
            }
            echo $output;
            return;
        }
        $output .= html_writer::tag('a', '', array('id' => 'p' . $post->id));
        $output .= html_writer::start_tag('div', array('class' => 'forumpost clearfix'));
        $output .= html_writer::start_tag('div', array('class' => 'row header'));
        $output .= html_writer::tag('div', '', array('class' => 'left picture'));
        // Picture
        if ($post->parent) {
            $output .= html_writer::start_tag('div', array('class' => 'topic'));
        } else {
            $output .= html_writer::start_tag('div', array('class' => 'topic starter'));
        }
        $output .= html_writer::tag('div', get_string('forumsubjecthidden', 'forum'), array('class' => 'subject'));
        // Subject
        $output .= html_writer::tag('div', get_string('forumauthorhidden', 'forum'), array('class' => 'author'));
        // author
        $output .= html_writer::end_tag('div');
        $output .= html_writer::end_tag('div');
        // row
        $output .= html_writer::start_tag('div', array('class' => 'row'));
        $output .= html_writer::tag('div', '&nbsp;', array('class' => 'left side'));
        // Groups
        $output .= html_writer::tag('div', get_string('forumbodyhidden', 'forum'), array('class' => 'content'));
        // Content
        $output .= html_writer::end_tag('div');
        // row
        $output .= html_writer::end_tag('div');
        // forumpost
        if ($return) {
            return $output;
        }
        echo $output;
        return;
    }
    if (empty($str)) {
        $str = new stdClass();
        $str->edit = get_string('edit', 'forum');
        $str->delete = get_string('delete', 'forum');
        $str->reply = get_string('reply', 'forum');
        $str->parent = get_string('parent', 'forum');
        $str->pruneheading = get_string('pruneheading', 'forum');
        $str->prune = get_string('prune', 'forum');
        $str->displaymode = get_user_preferences('forum_displaymode', $CFG->forum_displaymode);
        $str->markread = get_string('markread', 'forum');
        $str->markunread = get_string('markunread', 'forum');
    }
    $discussionlink = new moodle_url('/mod/forum/discuss.php', array('d' => $post->discussion));
    // Build an object that represents the posting user
    $postuser = new stdClass();
    $postuser->id = $post->userid;
    $postuser->firstname = $post->firstname;
    $postuser->lastname = $post->lastname;
    $postuser->imagealt = $post->imagealt;
    $postuser->picture = $post->picture;
    $postuser->email = $post->email;
    // Some handy things for later on
    $postuser->fullname = fullname($postuser, $cm->cache->caps['moodle/site:viewfullnames']);
    $postuser->profilelink = new moodle_url('/user/view.php', array('id' => $post->userid, 'course' => $course->id));
    // Prepare the groups the posting user belongs to
    if (isset($cm->cache->usersgroups)) {
        $groups = array();
        if (isset($cm->cache->usersgroups[$post->userid])) {
            foreach ($cm->cache->usersgroups[$post->userid] as $gid) {
                $groups[$gid] = $cm->cache->groups[$gid];
            }
        }
    } else {
        $groups = groups_get_all_groups($course->id, $post->userid, $cm->groupingid);
    }
    // Prepare the attachements for the post, files then images
    list($attachments, $attachedimages) = forum_print_attachments($post, $cm, 'separateimages');
    // Determine if we need to shorten this post
    $shortenpost = $link && strlen(strip_tags($post->message)) > $CFG->forum_longpost;
    // Prepare an array of commands
    $commands = array();
    // SPECIAL CASE: The front page can display a news item post to non-logged in users.
    // Don't display the mark read / unread controls in this case.
    if ($istracked && $CFG->forum_usermarksread && isloggedin()) {
        $url = new moodle_url($discussionlink, array('postid' => $post->id, 'mark' => 'unread'));
        $text = $str->markunread;
        if (!$postisread) {
            $url->param('mark', 'read');
            $text = $str->markread;
        }
        if ($str->displaymode == FORUM_MODE_THREADED) {
            $url->param('parent', $post->parent);
        } else {
            $url->set_anchor('p' . $post->id);
        }
        $commands[] = array('url' => $url, 'text' => $text);
    }
    // Zoom in to the parent specifically
    if ($post->parent) {
        $url = new moodle_url($discussionlink);
        if ($str->displaymode == FORUM_MODE_THREADED) {
            $url->param('parent', $post->parent);
        } else {
            $url->set_anchor('p' . $post->parent);
        }
        $commands[] = array('url' => $url, 'text' => $str->parent);
    }
    // Hack for allow to edit news posts those are not displayed yet until they are displayed
    $age = time() - $post->created;
    if (!$post->parent && $forum->type == 'news' && $discussion->timestart > time()) {
        $age = 0;
    }
    if ($ownpost && $age < $CFG->maxeditingtime || $cm->cache->caps['mod/forum:editanypost']) {
        $commands[] = array('url' => new moodle_url('/mod/forum/post.php', array('edit' => $post->id)), 'text' => $str->edit);
    }
    if ($cm->cache->caps['mod/forum:splitdiscussions'] && $post->parent && $forum->type != 'single') {
        $commands[] = array('url' => new moodle_url('/mod/forum/post.php', array('prune' => $post->id)), 'text' => $str->prune, 'title' => $str->pruneheading);
    }
    if ($ownpost && $age < $CFG->maxeditingtime && $cm->cache->caps['mod/forum:deleteownpost'] || $cm->cache->caps['mod/forum:deleteanypost']) {
        $commands[] = array('url' => new moodle_url('/mod/forum/post.php', array('delete' => $post->id)), 'text' => $str->delete);
    }
    if ($reply) {
        $commands[] = array('url' => new moodle_url('/mod/forum/post.php', array('reply' => $post->id)), 'text' => $str->reply);
    }
    if ($CFG->enableportfolios && ($cm->cache->caps['mod/forum:exportpost'] || $ownpost && $cm->cache->caps['mod/forum:exportownpost'])) {
        $p = array('postid' => $post->id);
        require_once $CFG->libdir . '/portfoliolib.php';
        $button = new portfolio_add_button();
        $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id), '/mod/forum/locallib.php');
        if (empty($attachments)) {
            $button->set_formats(PORTFOLIO_FORMAT_PLAINHTML);
        } else {
            $button->set_formats(PORTFOLIO_FORMAT_RICHHTML);
        }
        $porfoliohtml = $button->to_html(PORTFOLIO_ADD_TEXT_LINK);
        if (!empty($porfoliohtml)) {
            $commands[] = $porfoliohtml;
        }
    }
    // Finished building commands
    // Begin output
    $output = '';
    if ($istracked) {
        if ($postisread) {
            $forumpostclass = ' read';
        } else {
            $forumpostclass = ' unread';
            $output .= html_writer::tag('a', '', array('name' => 'unread'));
        }
    } else {
        // ignore trackign status if not tracked or tracked param missing
        $forumpostclass = '';
    }
    $topicclass = '';
    if (empty($post->parent)) {
        $topicclass = ' firstpost starter';
    }
    $output .= html_writer::tag('a', '', array('id' => 'p' . $post->id));
    $output .= html_writer::start_tag('div', array('class' => 'forumpost clearfix' . $forumpostclass . $topicclass));
    $output .= html_writer::start_tag('div', array('class' => 'row header clearfix'));
    $output .= html_writer::start_tag('div', array('class' => 'left picture'));
    $output .= $OUTPUT->user_picture($postuser, array('courseid' => $course->id));
    $output .= html_writer::end_tag('div');
    $output .= html_writer::start_tag('div', array('class' => 'topic' . $topicclass));
    $postsubject = $post->subject;
    if (empty($post->subjectnoformat)) {
        $postsubject = format_string($postsubject);
    }
    $output .= html_writer::tag('div', $postsubject, array('class' => 'subject'));
    $by = new stdClass();
    $by->name = html_writer::link($postuser->profilelink, $postuser->fullname);
    $by->date = userdate($post->modified);
    $output .= html_writer::tag('div', get_string('bynameondate', 'forum', $by), array('class' => 'author'));
    $output .= html_writer::end_tag('div');
    //topic
    $output .= html_writer::end_tag('div');
    //row
    $output .= html_writer::start_tag('div', array('class' => 'row maincontent clearfix'));
    $output .= html_writer::start_tag('div', array('class' => 'left'));
    $groupoutput = '';
    if ($groups) {
        $groupoutput = print_group_picture($groups, $course->id, false, true, true);
    }
    if (empty($groupoutput)) {
        $groupoutput = '&nbsp;';
    }
    $output .= html_writer::tag('div', $groupoutput, array('class' => 'grouppictures'));
    $output .= html_writer::end_tag('div');
    //left side
    $output .= html_writer::start_tag('div', array('class' => 'no-overflow'));
    $output .= html_writer::start_tag('div', array('class' => 'content'));
    if (!empty($attachments)) {
        $output .= html_writer::tag('div', $attachments, array('class' => 'attachments'));
    }
    $options = new stdClass();
    $options->para = false;
    $options->trusted = $post->messagetrust;
    $options->context = $modcontext;
    if ($shortenpost) {
        // Prepare shortened version
        $postclass = 'shortenedpost';
        $postcontent = format_text(forum_shorten_post($post->message), $post->messageformat, $options, $course->id);
        $postcontent .= html_writer::link($discussionlink, get_string('readtherest', 'forum'));
        $postcontent .= html_writer::tag('span', '(' . get_string('numwords', 'moodle', count_words(strip_tags($post->message))) . ')...', array('class' => 'post-word-count'));
    } else {
        // Prepare whole post
        $postclass = 'fullpost';
        $postcontent = format_text($post->message, $post->messageformat, $options, $course->id);
        if (!empty($highlight)) {
            $postcontent = highlight($highlight, $postcontent);
        }
        $postcontent .= html_writer::tag('div', $attachedimages, array('class' => 'attachedimages'));
    }
    // #marginalia begin
    // Write out the margin.  It goes before the content, then floats right.
    global $PAGE;
    $miamoodle = moodle_marginalia::get_instance();
    $miaprofile = $miamoodle->get_profile($PAGE->url->out(false));
    if ($miaprofile) {
        $output .= $miaprofile->output_margin();
    }
    // #marginalia end
    // Output the post content
    $output .= html_writer::tag('div', $postcontent, array('class' => 'posting ' . $postclass));
    $output .= html_writer::end_tag('div');
    // Content
    $output .= html_writer::end_tag('div');
    // Content mask
    $output .= html_writer::end_tag('div');
    // Row
    $output .= html_writer::start_tag('div', array('class' => 'row side'));
    $output .= html_writer::tag('div', '&nbsp;', array('class' => 'left'));
    $output .= html_writer::start_tag('div', array('class' => 'options clearfix'));
    // Output ratings
    if (!empty($post->rating)) {
        $output .= html_writer::tag('div', $OUTPUT->render($post->rating), array('class' => 'forum-post-rating'));
    }
    // Output the commands
    $commandhtml = array();
    foreach ($commands as $command) {
        if (is_array($command)) {
            $commandhtml[] = html_writer::link($command['url'], $command['text']);
        } else {
            $commandhtml[] = $command;
        }
    }
    // #marginalia begin
    // Ack.  Moodle assumes that commands should be links.  This doesn't work
    // for the quote button, because it has to call some JS to get the quote.
    if ($miaprofile) {
        $commandhtml[] = $miaprofile->output_quote_button();
    }
    // #marginalia end
    $output .= html_writer::tag('div', implode(' | ', $commandhtml), array('class' => 'commands'));
    // Output link to post if required
    if ($link) {
        if ($post->replies == 1) {
            $replystring = get_string('repliesone', 'forum', $post->replies);
        } else {
            $replystring = get_string('repliesmany', 'forum', $post->replies);
        }
        $output .= html_writer::start_tag('div', array('class' => 'link'));
        $output .= html_writer::link($discussionlink, get_string('discussthistopic', 'forum'));
        $output .= '&nbsp;(' . $replystring . ')';
        $output .= html_writer::end_tag('div');
        // link
    }
    // Output footer if required
    if ($footer) {
        $output .= html_writer::tag('div', $footer, array('class' => 'footer'));
    }
    // Close remaining open divs
    $output .= html_writer::end_tag('div');
    // content
    $output .= html_writer::end_tag('div');
    // row
    $output .= html_writer::end_tag('div');
    // forumpost
    // Mark the forum post as read if required
    if ($istracked && !$CFG->forum_usermarksread && !$postisread) {
        forum_tp_mark_post_read($USER->id, $post, $forum->id);
    }
    if ($return) {
        return $output;
    }
    echo $output;
    return;
}
Exemple #8
0
                $url = "discuss.php?d={$discussion->id}&amp;fromforum={$discussion->forum}&amp;move={$courseforum->id}";
                $forummenu[$url] = format_string($courseforum->name, true);
            }
        }
        if (!empty($forummenu)) {
            echo "<div style=\"float:right;\">";
            echo popup_form("{$CFG->wwwroot}/mod/forum/", $forummenu, "forummenu", "", get_string("movethisdiscussionto", "forum"), "", "", true);
            echo "</div>";
        }
    }
}
// Annotation controls (help, user dropdown, link to summary page)
echo "</td>\n<td id='annotation-controls'>";
moodle_marginalia::show_help('forum');
moodle_marginalia::show_user_dropdown($refurl, true);
echo moodle_marginalia::summary_link_html($refurl, $USER->username);
echo "</td></tr></table>";
if (!empty($forum->blockafter) && !empty($forum->blockperiod)) {
    $a->blockafter = $forum->blockafter;
    $a->blockperiod = get_string('secondstotime' . $forum->blockperiod);
    notify(get_string('thisforumisthrottled', 'forum', $a));
}
if ($forum->type == 'qanda' && !has_capability('mod/forum:viewqandawithoutposting', $modcontext) && !forum_user_has_posted($forum->id, $discussion->id, $USER->id)) {
    notify(get_string('qandanotify', 'forum'));
}
if (isset($discussionmoved)) {
    notify(get_string("discussionmoved", "forum", format_string($forum->name, true)));
}
/// Print the actual discussion
if (!$canviewdiscussion) {
    notice(get_string('noviewdiscussionspermission', 'forum'));
Exemple #9
0
 function show_user_dropdown($refurl)
 {
     global $USER;
     $summary = annotation_summary_query::from_url($refurl);
     $userlist = get_records_sql($summary->list_users_sql());
     $annotationuserid = moodle_marginalia::get_userid();
     $showannotationspref = moodle_marginalia::get_show_annotations_pref() == 'true';
     echo "<select name='anuser' id='anuser' onchange='window.moodleMarginalia.changeAnnotationUser(this,\"{$refurl}\");'>\n";
     $selected = $showannotationspref ? '' : " selected='selected' ";
     echo " <option {$selected} value=''>" . get_string('hide_annotations', ANNOTATION_STRINGS) . "</option>\n";
     if (!isguest()) {
         $selected = $showannotationspref && ($USER->username == $annotationuserid ? "selected='selected' " : '') ? " selected='selected' " : '';
         echo " <option {$selected}" . "value='" . s($USER->username) . "'>" . get_string('my_annotations', ANNOTATION_STRINGS) . "</option>\n";
     }
     if ($userlist) {
         foreach ($userlist as $user) {
             if ($user->username != $USER->username) {
                 $selected = $showannotationspref && ($user->id == $annotationuserid ? "selected='selected' " : '') ? " selected='selected' " : '';
                 echo " <option {$selected}" . "value='" . s($user->username) . "'>" . s($user->firstname . ' ' . $user->lastname) . "</option>\n";
             }
         }
     }
     // Show item for all users
     if (true) {
         $selected = $showannotationspref && ('*' == $annotationuserid ? "selected='selected' " : '') ? " selected='selected' " : '';
         echo " <option {$selected} value='*'>" . get_string('all_annotations', ANNOTATION_STRINGS) . "</option>\n";
     }
     echo "</select>\n";
 }