function test_everything()
 {
     // Add a bunch of comments
     ouwiki_add_comment(13, 'frog', 'Frogs', 'My happy comment', 'This comment has a title');
     ouwiki_add_comment(13, 'frog', 'Frogs', null, 'This one does not');
     ouwiki_add_comment(13, null, null, null, 'This comment is on the main page section');
     ouwiki_add_comment(13, 'zombie', 'Zombies', null, 'This one is on a different section');
     ouwiki_add_comment(66, null, null, null, 'This one is on another page');
     ouwiki_add_comment(66, 'frog', 'Frogs', null, 'This one is on another page but same section');
     ouwiki_add_comment(13, null, null, null, 'Main 2', 2);
     ouwiki_add_comment(13, null, null, null, 'Main 3', OUWIKI_SYSTEMUSER);
     ouwiki_add_comment(13, null, null, null, 'Main 4');
     ouwiki_add_comment(13, 'frog', 'Frogs', null, 'Frog 3');
     ouwiki_add_comment(13, 'frog', 'Frogs', null, 'Frog 4');
     ouwiki_add_comment(13, 'frog', 'Frogs', null, 'Frog 5');
     // Check sections
     $sections = get_records('ouwiki_sections');
     $this->assertEqual(count($sections), 5);
     $this->assertEqual((array) array_shift($sections), array('pageid' => 13, 'xhtmlid' => 'frog', 'title' => 'Frogs', 'id' => 1));
     $this->assertEqual((array) array_shift($sections), array('pageid' => 13, 'xhtmlid' => null, 'title' => null, 'id' => 2));
     $this->assertEqual((array) array_shift($sections), array('pageid' => 13, 'xhtmlid' => 'zombie', 'title' => 'Zombies', 'id' => 3));
     $this->assertEqual((array) array_shift($sections), array('pageid' => 66, 'xhtmlid' => null, 'title' => null, 'id' => 4));
     $this->assertEqual((array) array_shift($sections), array('pageid' => 66, 'xhtmlid' => 'frog', 'title' => 'Frogs', 'id' => 5));
     $comments = get_records('ouwiki_comments');
     $this->assertEqual(count($comments), 12);
     // Check timeposted once then chuck it because it makes comparison harder
     $this->assertTrue(time() - $comments[1]->timeposted < 5 && time() - $comments[1]->timeposted >= 0);
     for ($i = 1; $i <= 12; $i++) {
         unset($comments[$i]->timeposted);
     }
     $this->assertEqual((array) array_shift($comments), array('sectionid' => 1, 'title' => 'My happy comment', 'xhtml' => 'This comment has a title', 'userid' => 1, 'deleted' => 0, 'id' => 1));
     $this->assertEqual((array) array_shift($comments), array('sectionid' => 1, 'title' => null, 'xhtml' => 'This one does not', 'userid' => 1, 'deleted' => 0, 'id' => 2));
     $this->assertEqual((array) array_shift($comments), array('sectionid' => 2, 'title' => null, 'xhtml' => 'This comment is on the main page section', 'userid' => 1, 'deleted' => 0, 'id' => 3));
     $this->assertEqual((array) array_shift($comments), array('sectionid' => 3, 'title' => null, 'xhtml' => 'This one is on a different section', 'userid' => 1, 'deleted' => 0, 'id' => 4));
     $this->assertEqual((array) array_shift($comments), array('sectionid' => 4, 'title' => null, 'xhtml' => 'This one is on another page', 'userid' => 1, 'deleted' => 0, 'id' => 5));
     $this->assertEqual((array) array_shift($comments), array('sectionid' => 5, 'title' => null, 'xhtml' => 'This one is on another page but same section', 'userid' => 1, 'deleted' => 0, 'id' => 6));
     $this->assertEqual((array) array_shift($comments), array('sectionid' => 2, 'title' => null, 'xhtml' => 'Main 2', 'userid' => 2, 'deleted' => 0, 'id' => 7));
     $this->assertEqual((array) array_shift($comments), array('sectionid' => 2, 'title' => null, 'xhtml' => 'Main 3', 'userid' => null, 'deleted' => 0, 'id' => 8));
     $this->assertEqual((array) array_shift($comments), array('sectionid' => 2, 'title' => null, 'xhtml' => 'Main 4', 'userid' => 1, 'deleted' => 0, 'id' => 9));
     $this->assertEqual((array) array_shift($comments), array('sectionid' => 1, 'title' => null, 'xhtml' => 'Frog 3', 'userid' => 1, 'deleted' => 0, 'id' => 10));
     $this->assertEqual((array) array_shift($comments), array('sectionid' => 1, 'title' => null, 'xhtml' => 'Frog 4', 'userid' => 1, 'deleted' => 0, 'id' => 11));
     $this->assertEqual((array) array_shift($comments), array('sectionid' => 1, 'title' => null, 'xhtml' => 'Frog 5', 'userid' => 1, 'deleted' => 0, 'id' => 12));
     // Now delete Frog 3
     ouwiki_delete_comment(13, 10, 1);
     $comment = get_record('ouwiki_comments', 'id', 10);
     unset($comment->timeposted);
     $this->assertEqual((array) $comment, array('sectionid' => 1, 'title' => null, 'xhtml' => 'Frog 3', 'userid' => 1, 'deleted' => 1, 'id' => 10));
     // Check query for all content...
     $comments = ouwiki_get_all_comments(13, 'frog');
     $comment = $comments[1];
     unset($comment->timeposted);
     // Ensure comments have all expected details (just taking one example)
     $this->assertEqual((array) $comment, array('sectionid' => 1, 'title' => 'My happy comment', 'xhtml' => 'This comment has a title', 'userid' => 1, 'deleted' => 0, 'sectiontitle' => 'Frogs', 'section' => 'frog', 'firstname' => 'user', 'lastname' => 'one', 'username' => 'u1', 'id' => 1));
     // Now check correct comments are included
     $this->assertEqual(self::get_id_array($comments), array(1, 2, 11, 12));
     // Check it works to include deleted ones if asked
     $comments = ouwiki_get_all_comments(13, 'frog', true);
     $this->assertEqual(self::get_id_array($comments), array(1, 2, 10, 11, 12));
     // Ask for comments from main section with everything else valid...
     $comments = ouwiki_get_all_comments(13, null, false, array('frog' => 0, 'zombie' => 0));
     $this->assertEqual(self::get_id_array($comments), array(3, 7, 8, 9));
     // ...and with nothing else valid
     $comments = ouwiki_get_all_comments(13, null, false, array());
     $this->assertEqual(self::get_id_array($comments), array(1, 2, 3, 4, 7, 8, 9, 11, 12));
     // Check query for page-display content
     $comments = ouwiki_get_recent_comments(13, array('frog' => 0, 'zombie' => 0));
     $this->assertEqual($comments['']->count, 4);
     $this->assertEqual(self::get_id_array($comments['']->comments), array(7, 8, 9));
     $this->assertEqual($comments['frog']->count, 4);
     $this->assertEqual(self::get_id_array($comments['frog']->comments), array(2, 11, 12));
     $this->assertEqual($comments['zombie']->count, 1);
     $this->assertEqual(self::get_id_array($comments['zombie']->comments), array(4));
 }
/**
 * @param object $subwiki For details of user/group and ID so that
 *   we can make links
 * @param object $cm Course-module object (again for making links)
 * @param object $pageversion Data from page and version tables.
 * @return string HTML content for page
 */
function ouwiki_display_page($subwiki, $cm, $pageversion, $gewgaws = false, $page = 'history')
{
    global $CFG;
    // Get comments - only if using per-section comment system. prevents unnecessary db access
    $comments = array();
    if (ouwiki_get_commenting($subwiki->commenting) == OUWIKI_COMMENTS_PERSECTION || ouwiki_get_commenting($subwiki->commenting) == OUWIKI_COMMENTS_BOTH) {
        if ($gewgaws) {
            $comments = ouwiki_get_recent_comments($pageversion->pageid, ouwiki_find_sections($pageversion->xhtml));
        }
    }
    // And params
    $params = ouwiki_display_wiki_parameters($pageversion->title, $subwiki, $cm);
    // Get annotations - only if using annotation comment system. prevents unnecessary db access
    if (ouwiki_get_commenting($subwiki->commenting) == OUWIKI_COMMENTS_ANNOTATION || ouwiki_get_commenting($subwiki->commenting) == OUWIKI_COMMENTS_BOTH) {
        $annotations = ouwiki_get_annotations($pageversion);
    } else {
        $annotations = '';
    }
    // Title
    $title = is_null($pageversion->title) ? get_string('startpage', 'ouwiki') : htmlspecialchars($pageversion->title);
    // setup annotations according to the page we are on
    if ($page == 'view') {
        // create the annotations
        if ((ouwiki_get_commenting($subwiki->commenting) == OUWIKI_COMMENTS_ANNOTATION || ouwiki_get_commenting($subwiki->commenting) == OUWIKI_COMMENTS_BOTH) && count($annotations)) {
            ouwiki_highlight_existing_annotations(&$pageversion->xhtml, $annotations, 'view');
        }
    } elseif ($page == 'annotate') {
        // call function for the annotate page
        ouwiki_setup_annotation_markers(&$pageversion->xhtml);
        ouwiki_highlight_existing_annotations(&$pageversion->xhtml, $annotations, 'annotate');
    }
    $result = '';
    $result .= '<div class="ouwiki_content"><div class="ouw_topheading">';
    $returncomments = true;
    $result .= '<div class="ouw_heading"><h1 id="ouw_topheading">' . $title . '</h1>' . ($gewgaws ? ouwiki_internal_display_heading_bit(1, $pageversion->title, $subwiki, $cm, $comments, null, $annotations, $pageversion->locked, $returncomments) : '</div>');
    // List of recent changes
    if ($gewgaws && $pageversion->recentversions) {
        $result .= '<div class="ouw_recentchanges">' . get_string('recentchanges', 'ouwiki') . ': <span class="ouw_recentchanges_list">';
        $first = true;
        foreach ($pageversion->recentversions as $recentversion) {
            if ($first) {
                $first = false;
            } else {
                $result .= '; ';
            }
            $result .= ouwiki_recent_span($recentversion->timecreated);
            $result .= ouwiki_nice_date($recentversion->timecreated) . '</span> (';
            $recentversion->id = $recentversion->userid;
            // so it looks like a user object
            $result .= ouwiki_display_user($recentversion, $cm->course, false) . ')';
        }
        if (class_exists('ouflags') && ou_get_is_mobile()) {
            $result .= '; </span></div>';
        } else {
            $result .= '; <br/><a class="seedetails" href="history.php?' . $params . '">' . get_string('seedetails', 'ouwiki') . '</a></span></div>';
        }
    }
    $result .= '</div><div class="ouw_belowmainhead">';
    if ($returncomments !== true) {
        $result .= $returncomments;
    }
    $result .= '<div class="ouw_topspacer"></div>';
    // Content of page
    $result .= ouwiki_convert_content($pageversion->xhtml, $subwiki, $cm);
    if ($gewgaws) {
        // Add in links/etc. around headings
        global $ouwiki_internal_re;
        $ouwiki_internal_re->comments = $comments;
        $ouwiki_internal_re->pagename = $pageversion->title;
        $ouwiki_internal_re->subwiki = $subwiki;
        $ouwiki_internal_re->cm = $cm;
        $ouwiki_internal_re->annotations = $annotations;
        $ouwiki_internal_re->locked = $pageversion->locked;
        $result = preg_replace_callback('|<h([1-9]) id="ouw_s([0-9]+_[0-9]+)">(.*?)(<br\\s*/>)?</h[1-9]>|s', 'ouwiki_internal_re_heading_bits', $result);
    }
    $result .= '<div class="clearer"></div></div></div>';
    if ($gewgaws) {
        $links = ouwiki_get_links_to($pageversion->pageid);
        if (count($links) > 0) {
            $result .= '<div class="ouw_linkedfrom"><h3>' . get_string(count($links) == 1 ? 'linkedfromsingle' : 'linkedfrom', 'ouwiki') . '</h3><ul>';
            $first = true;
            foreach ($links as $link) {
                $result .= ' <li>';
                if ($first) {
                    $first = false;
                } else {
                    $result .= '&#8226; ';
                }
                $result .= '<a href="view.php?' . ouwiki_display_wiki_parameters($link->title, $subwiki, $cm) . '">' . ($link->title ? htmlspecialchars($link->title) : get_string('startpage', 'ouwiki')) . '</a></li>';
            }
            $result .= '</ul></div>';
        }
        if ($subwiki->cancomment && (ouwiki_get_commenting($subwiki->commenting) == OUWIKI_COMMENTS_PERSECTION || ouwiki_get_commenting($subwiki->commenting) == OUWIKI_COMMENTS_BOTH)) {
            $result .= '<div id="ouw_ac_formcontainer" style="display:none">' . ouwiki_display_comment_form('view', null, null, $pageversion->title, $subwiki, $cm) . '</div>';
        }
    }
    // disply the orphaned annotations
    if ((ouwiki_get_commenting($subwiki->commenting) == OUWIKI_COMMENTS_ANNOTATION || ouwiki_get_commenting($subwiki->commenting) == OUWIKI_COMMENTS_BOTH) && $annotations && $page != 'history') {
        $orphaned = '';
        foreach ($annotations as $annotation) {
            if ($annotation->orphaned) {
                $orphaned .= ouwiki_setup_hidden_annotation($annotation);
            }
        }
        $result = $orphaned !== '' ? $result . '<h3>' . get_string('orphanedannotations', 'ouwiki') . '</h3>' . $orphaned : $result;
    }
    return array($result, $annotations);
}