See Release Notes
Long Term Support Release
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Search area for mod_wiki collaborative pages. 19 * 20 * @package mod_wiki 21 * @copyright 2016 Eric Merrill {@link http://www.merrilldigital.com} 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace mod_wiki\search; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 require_once($CFG->dirroot . '/mod/wiki/locallib.php'); 30 31 /** 32 * Search area for mod_wiki collaborative pages. 33 * 34 * @package mod_wiki 35 * @copyright 2016 Eric Merrill {@link http://www.merrilldigital.com} 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 */ 38 class collaborative_page extends \core_search\base_mod { 39 /** 40 * @var array Cache of wiki records. 41 */ 42 protected $wikiscache = array(); 43 44 /** 45 * Returns a recordset with all required page information. 46 * 47 * @param int $modifiedfrom 48 * @param \context|null $context Optional context to restrict scope of returned results 49 * @return moodle_recordset|null Recordset (or null if no results) 50 */ 51 public function get_document_recordset($modifiedfrom = 0, \context $context = null) { 52 global $DB; 53 54 list ($contextjoin, $contextparams) = $this->get_context_restriction_sql( 55 $context, 'wiki', 'w'); 56 if ($contextjoin === null) { 57 return null; 58 } 59 60 $sql = "SELECT p.*, w.id AS wikiid, w.course AS courseid, s.groupid AS groupid 61 FROM {wiki_pages} p 62 JOIN {wiki_subwikis} s ON s.id = p.subwikiid 63 JOIN {wiki} w ON w.id = s.wikiid 64 $contextjoin 65 WHERE p.timemodified >= ? 66 AND w.wikimode = ? 67 ORDER BY p.timemodified ASC"; 68 return $DB->get_recordset_sql($sql, array_merge($contextparams, 69 [$modifiedfrom, 'collaborative'])); 70 } 71 72 /** 73 * Returns the document for a particular page. 74 * 75 * @param \stdClass $record A record containing, at least, the indexed document id and a modified timestamp 76 * @param array $options Options for document creation 77 * @return \core_search\document 78 */ 79 public function get_document($record, $options = array()) { 80 try { 81 $cm = $this->get_cm('wiki', $record->wikiid, $record->courseid); 82 $context = \context_module::instance($cm->id); 83 } catch (\dml_missing_record_exception $ex) { 84 // Notify it as we run here as admin, we should see everything. 85 debugging('Error retrieving ' . $this->areaid . ' ' . $record->id . ' document, not all required data is available: ' . 86 $ex->getMessage(), DEBUG_DEVELOPER); 87 return false; 88 } catch (\dml_exception $ex) { 89 // Notify it as we run here as admin, we should see everything. 90 debugging('Error retrieving ' . $this->areaid . ' ' . $record->id . ' document: ' . $ex->getMessage(), DEBUG_DEVELOPER); 91 return false; 92 } 93 94 // Make a page object without extra fields. 95 $page = clone $record; 96 unset($page->courseid); 97 unset($page->wikiid); 98 99 // Conversion based wiki_print_page_content(). 100 // Check if we have passed the cache time. 101 if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) { 102 $content = wiki_refresh_cachedcontent($page); 103 $page = $content['page']; 104 } 105 // Convert to text. 106 $content = content_to_text($page->cachedcontent, FORMAT_MOODLE); 107 108 // Prepare associative array with data from DB. 109 $doc = \core_search\document_factory::instance($record->id, $this->componentname, $this->areaname); 110 $doc->set('title', content_to_text($record->title, false)); 111 $doc->set('content', $content); 112 $doc->set('contextid', $context->id); 113 $doc->set('courseid', $record->courseid); 114 if ($record->groupid > 0) { 115 $doc->set('groupid', $record->groupid); 116 } 117 $doc->set('owneruserid', \core_search\manager::NO_OWNER_ID); 118 $doc->set('modified', $record->timemodified); 119 120 // Check if this document should be considered new. 121 if (isset($options['lastindexedtime']) && ($options['lastindexedtime'] < $record->timecreated)) { 122 // If the document was created after the last index time, it must be new. 123 $doc->set_is_new(true); 124 } 125 126 return $doc; 127 } 128 129 /** 130 * Can the current user see the document. 131 * 132 * @param int $id The internal search area entity id. 133 * @return bool True if the user can see it, false otherwise 134 */ 135 public function check_access($id) { 136 global $DB; 137 138 try { 139 $page = $DB->get_record('wiki_pages', array('id' => $id), '*', MUST_EXIST); 140 if (!isset($this->wikiscache[$page->subwikiid])) { 141 $sql = 'SELECT w.* 142 FROM {wiki_subwikis} s 143 JOIN {wiki} w ON w.id = s.wikiid 144 WHERE s.id = ?'; 145 $this->wikiscache[$page->subwikiid] = $DB->get_record_sql($sql, array('id' => $page->subwikiid), MUST_EXIST); 146 } 147 $wiki = $this->wikiscache[$page->subwikiid]; 148 $cminfo = $this->get_cm('wiki', $wiki->id, $wiki->course); 149 } catch (\dml_missing_record_exception $ex) { 150 return \core_search\manager::ACCESS_DELETED; 151 } catch (\dml_exception $ex) { 152 return \core_search\manager::ACCESS_DENIED; 153 } 154 155 // Recheck uservisible although it should have already been checked in core_search. 156 if ($cminfo->uservisible === false) { 157 return \core_search\manager::ACCESS_DENIED; 158 } 159 160 $context = \context_module::instance($cminfo->id); 161 162 if (!has_capability('mod/wiki:viewpage', $context)) { 163 return \core_search\manager::ACCESS_DENIED; 164 } 165 166 return \core_search\manager::ACCESS_GRANTED; 167 } 168 169 /** 170 * Returns a url to the page. 171 * 172 * @param \core_search\document $doc 173 * @return \moodle_url 174 */ 175 public function get_doc_url(\core_search\document $doc) { 176 $params = array('pageid' => $doc->get('itemid')); 177 return new \moodle_url('/mod/wiki/view.php', $params); 178 } 179 180 /** 181 * Returns a url to the wiki. 182 * 183 * @param \core_search\document $doc 184 * @return \moodle_url 185 */ 186 public function get_context_url(\core_search\document $doc) { 187 $contextmodule = \context::instance_by_id($doc->get('contextid')); 188 return new \moodle_url('/mod/wiki/view.php', array('id' => $contextmodule->instanceid)); 189 } 190 191 /** 192 * Returns true if this area uses file indexing. 193 * 194 * @return bool 195 */ 196 public function uses_file_indexing() { 197 return true; 198 } 199 200 /** 201 * Return the context info required to index files for 202 * this search area. 203 * 204 * @return array 205 */ 206 public function get_search_fileareas() { 207 $fileareas = array('attachments'); // Filearea. 208 209 return $fileareas; 210 } 211 212 /** 213 * Confirms that data entries support group restrictions. 214 * 215 * @return bool True 216 */ 217 public function supports_group_restriction() { 218 return true; 219 } 220 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body