/** * Obtains a search document relating to a particular blog post. * * @param object $post Post object. Required fields: id (optionally also * groupid, userid save a db query) * @param object $cm Course-module object. Required fields: id, course * @return ousearch_doument */ function oublog_get_search_document($post, $cm) { // Set up 'search document' to refer to this post $doc = new ousearch_document(); $doc->init_module_instance('oublog', $cm); if (!isset($post->userid) || !isset($post->groupid)) { global $CFG; $results = get_record_sql("\nSELECT\n p.groupid,i.userid\nFROM\n{$CFG->prefix}oublog_posts p\n INNER JOIN {$CFG->prefix}oublog_instances i ON p.oubloginstancesid=i.id\nWHERE\n p.id={$post->id}"); if (!$results) { error("Can't find details for blog post {$post->id}"); } $post->userid = $results->userid; $post->groupid = $results->groupid; } if ($post->groupid) { $doc->set_group_id($post->groupid); } $doc->set_user_id($post->userid); $doc->set_int_refs($post->id); return $doc; }
/** * Update all wiki documents for ousearch. * @param bool $feedback If true, prints feedback as HTML list items * @param int $courseid If specified, restricts to particular courseid */ function ouwiki_ousearch_update_all($feedback = false, $courseid = 0) { global $CFG; // Get list of all wikis. We need the coursemodule data plus // the type of subwikis $coursecriteria = $courseid === 0 ? '' : 'cm.course=' . $courseid . ' AND'; $coursemodules = get_records_sql("\nSELECT\n cm.id,cm.course,cm.instance,w.subwikis\nFROM\n {$CFG->prefix}modules m\n INNER JOIN {$CFG->prefix}course_modules cm ON cm.module=m.id\n INNER JOIN {$CFG->prefix}ouwiki w ON cm.instance=w.id\nWHERE\n {$coursecriteria}\n m.name='ouwiki'"); if (!$coursemodules) { return; } if ($feedback) { print '<li><strong>' . count($coursemodules) . '</strong> wikis to process.</li>'; $dotcount = 0; } $count = 0; foreach ($coursemodules as $coursemodule) { // This condition is needed because if somebody creates some stuff // then changes the wiki type, it actually keeps the old bits // in the database. Maybe it shouldn't, not sure. switch ($coursemodule->subwikis) { case OUWIKI_SUBWIKIS_SINGLE: $where = "sw.userid IS NULL AND sw.groupid IS NULL"; break; case OUWIKI_SUBWIKIS_GROUPS: $where = "sw.userid IS NULL AND sw.groupid IS NOT NULL"; break; case OUWIKI_SUBWIKIS_INDIVIDUAL: $where = "sw.userid IS NOT NULL AND sw.groupid IS NULL"; break; } // Get all pages in that wiki $rs = get_recordset_sql("\nSELECT\n p.id,p.title,v.xhtml,v.timecreated,sw.groupid,sw.userid\nFROM\n {$CFG->prefix}ouwiki_subwikis sw\n INNER JOIN {$CFG->prefix}ouwiki_pages p ON p.subwikiid=sw.id\n INNER JOIN {$CFG->prefix}ouwiki_versions v ON v.id=p.currentversionid\nWHERE\n sw.wikiid={$coursemodule->instance} AND {$where}"); while ($page = rs_fetch_next_record($rs)) { // Update the page for search $doc = new ousearch_document(); $doc->init_module_instance('ouwiki', $coursemodule); if ($page->groupid) { $doc->set_group_id($page->groupid); } if ($page->title) { $doc->set_string_ref($page->title); } if ($page->userid) { $doc->set_user_id($page->userid); } $title = $page->title ? $page->title : ''; if (!$doc->update($title, $page->xhtml, $page->timecreated)) { ouwiki_error('Failed to update database record for page ID ' . $page->id); } } rs_close($rs); $count++; if ($feedback) { if ($dotcount == 0) { print '<li>'; } print '.'; $dotcount++; if ($dotcount == 20 || $count == count($coursemodules)) { print 'done ' . $count . '</li>'; $dotcount = 0; } flush(); } } }
/** * Saves a new version of the given named page within a subwiki. Can create * a new page or just add a new version to an existing one. In case of * failure, ends up calling error() rather than returning something. * @param object $course Course object * @param object $cm Course-module object * @param object $ouwiki OU wiki object * @param object $subwiki Subwiki object * @param string $pagename Name of page (NO SLASHES) * @param string $content XHTML Content (NO SLASHES) * @param int $changestart For section changes. Start position of change. (-1 if not section change) * @param int $changesize Size of changed section. * @param int $changeprevsize Previous size of changed section * @param bool $nouser If true, creates as system */ function ouwiki_save_new_version($course, $cm, $ouwiki, $subwiki, $pagename, $content, $changestart = -1, $changesize = -1, $changeprevsize = -1, $nouser = false) { $tw = new transaction_wrapper(); // Find page if it exists $pageversion = ouwiki_get_current_page($subwiki, $pagename, OUWIKI_GETPAGE_CREATE); // Analyse content for HTML headings that don't already have an ID. // These are all assigned unique, fairly short IDs. // Get number of version [guarantees in-page uniqueness of generated IDs] $versionnumber = count_records('ouwiki_versions', 'pageid', $pageversion->pageid); // Remove any spaces from annotation tags that were added for editing or by users // and remove any duplicate annotation tags $pattern = '~<span\\b.id=\\"annotation(.+?)\\">.*?</span>~'; $replace = '<span id="annotation$1"></span>'; $content = preg_replace($pattern, $replace, $content); unset($pattern, $replace, $used); // Get rid of any heading tags that only contain whitespace $emptypatterns = array(); for ($i = 1; $i <= 6; $i++) { $emptypatterns[] = '~<h' . $i . '[^>]*>\\s*(<br[^>]*>\\s*)*</h' . $i . '>~'; } $content = preg_replace($emptypatterns, '', $content); // List all headings that already have IDs, to check for duplicates $matches = array(); preg_match_all('|<h[1-9] id="ouw_s(.*?)">(.*?)</h[1-9]>|', $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); // Organise list by ID $byid = array(); foreach ($matches as $index => $data) { $id = $data[1][0]; if (!array_key_exists($id, $byid)) { $byid[$id] = array(); } $byid[$id][] = $index; } // Handle any duplicates $deletebits = array(); foreach ($byid as $id => $duplicates) { if (count($duplicates) > 1) { // We have a duplicate. By default, keep the first one $keep = $duplicates[0]; // See if there is a title entry in the database for it $knowntitle = get_field('ouwiki_sections', 'title', 'xhtmlid', addslashes($id), 'pageid', $pageversion->pageid); if ($knowntitle) { foreach ($duplicates as $duplicate) { $title = ouwiki_get_section_title(null, null, $matches[$duplicate][2][0]); if ($title === $knowntitle) { $keep = $duplicate; break; } } } foreach ($duplicates as $duplicate) { if ($duplicate !== $keep) { $deletebits[] = (object) array('startbyte' => $matches[$duplicate][1][1] - 10, 'bytes' => strlen($matches[$duplicate][1][0]) + 11); } } } } // Were there any? if (count($deletebits) > 0) { // Sort in reverse order of starting position usort($deletebits, 'ouwiki_internal_sort_deletions'); // Delete each bit foreach ($deletebits as $deletebit) { $content = substr($content, 0, $deletebit->startbyte) . substr($content, $deletebit->startbyte + $deletebit->bytes); } } // Replace existing empty headings with an ID including version count plus another index global $ouwiki_count; // Nasty but I can't think of a better way! $ouwiki_count = 0; global $ouwiki_internal_re; $ouwiki_internal_re->version = $versionnumber; $ouwiki_internal_re->count = 0; $sizebefore = strlen($content); $content = preg_replace_callback('/<h([1-9])>/', 'ouwiki_internal_re_headings', $content); $sizeafter = strlen($content); // Replace wiki links to [[Start page]] with the correct (non // language-specific) format [[]] $regex = str_replace('.*?', preg_quote(get_string('startpage', 'ouwiki')), OUWIKI_LINKS_SQUAREBRACKETS) . 'ui'; $content = preg_replace($regex, '[[]]', $content); // Create version $version = new StdClass(); $version->pageid = $pageversion->pageid; $version->xhtml = addslashes($content); $version->timecreated = time(); if (!$nouser) { global $USER; $version->userid = $USER->id; } if ($changestart != -1) { $version->changestart = $changestart; // In tracking the new size, account for any added headings etc $version->changesize = $changesize + ($sizeafter - $sizebefore); $version->changeprevsize = $changeprevsize; } if (!($versionid = insert_record('ouwiki_versions', $version))) { $tw->rollback(); ouwiki_dberror(); } // Update latest version if (!set_field('ouwiki_pages', 'currentversionid', $versionid, 'id', $pageversion->pageid)) { $tw->rollback(); ouwiki_dberror(); } // Analyse for links $wikilinks = array(); $externallinks = array(); // Wiki links: ordinary [[links]] $matches = array(); preg_match_all(OUWIKI_LINKS_SQUAREBRACKETS, $content, $matches, PREG_PATTERN_ORDER); foreach ($matches[1] as $match) { // Convert to page name (this also removes HTML tags etc) $wikilinks[] = ouwiki_get_wiki_link_details($match)->page; } // Note that we used to support CamelCase links but have removed support because: // 1. Confusing: students type JavaScript or MySpace and don't expect it to become a link // 2. Not accessible: screenreaders cannot cope with run-together words, and // dyslexic students can have difficulty reading them // External links preg_match_all('/<a [^>]*href=(?:(?:\'(.*?)\')|(?:"(.*?))")/', $content, $matches, PREG_PATTERN_ORDER); foreach ($matches[1] as $match) { if ($match) { $externallinks[] = html_entity_decode($match); } } foreach ($matches[2] as $match) { if ($match) { $externallinks[] = html_entity_decode($match); } } // Add link records $link = new StdClass(); $link->fromversionid = $versionid; foreach ($wikilinks as $targetpage) { if (!empty($targetpage)) { $pagerecord = get_record_select('ouwiki_pages', "subwikiid='{$subwiki->id}' AND UPPER(title)=UPPER('" . addslashes($targetpage) . "')"); if ($pagerecord) { $pageid = $pagerecord->id; } else { $pageid = false; } } else { $pageid = get_field_select('ouwiki_pages', 'id', "subwikiid={$subwiki->id} AND title IS NULL"); } if ($pageid) { $link->topageid = $pageid; $link->tomissingpage = null; } else { $link->topageid = null; $link->tomissingpage = addslashes(strtoupper($targetpage)); } if (!($link->id = insert_record('ouwiki_links', $link))) { $tw->rollback(); ouwiki_dberror(); } } $link->topageid = null; $link->tomissingpage = null; $tl = textlib_get_instance(); foreach ($externallinks as $url) { // Restrict length of URL if ($tl->strlen($url) > 255) { $url = $tl->substr($url, 0, 255); } $link->tourl = addslashes($url); if (!($link->id = insert_record('ouwiki_links', $link))) { $tw->rollback(); ouwiki_dberror(); } } // Inform search, if installed if (ouwiki_search_installed()) { $doc = new ousearch_document(); $doc->init_module_instance('ouwiki', $cm); if ($subwiki->groupid) { $doc->set_group_id($subwiki->groupid); } $doc->set_string_ref($pageversion->title === '' ? null : $pageversion->title); if ($subwiki->userid) { $doc->set_user_id($subwiki->userid); } $title = is_null($pageversion->title) ? '' : $pageversion->title; if (!$doc->update($title, $content)) { $tw->rollback(); ouwiki_dberror(); } } // Inform completion system, if available if (class_exists('ouflags')) { if (completion_is_enabled($course, $cm) && ($ouwiki->completionedits || $ouwiki->completionpages)) { completion_update_state($course, $cm, COMPLETION_COMPLETE); } } $tw->commit(); }
$start = $pos; // Set up document $document = new ousearch_document(); $document->init_test('test2'); // Refs define document and place in it $document->set_string_ref($filename); $document->set_int_refs($start, $doclines); // Type (group.user) $type = rand(0, 99); if ($type < 50) { // 50% None $type_none++; } else { if ($type < 90) { // 40% Group $document->set_group_id($groups[rand(0, count($groups) - 1)]); $type_group++; } else { // 10% User $document->set_user_id($users[rand(0, count($users) - 1)]); $type_user++; } } // Update (create) document $title = trim($lines[$pos++]); $content = ''; for ($i = 1; $i < $doclines; $i++) { $content .= htmlspecialchars($lines[$pos++]); } $before = microtime(true); $document->update($title, $content);
/** * Obtains search document representing this post. * @return ousearch_document Document object */ function search_get_document() { $doc = new ousearch_document(); $doc->init_module_instance('forumng', $this->get_forum()->get_course_module()); if ($groupid = $this->discussion->get_group_id()) { $doc->set_group_id($groupid); } $doc->set_int_refs($this->get_id()); return $doc; }