|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00026 require_once($CFG->libdir . '/completionlib.php'); 00027 00028 define("GLOSSARY_SHOW_ALL_CATEGORIES", 0); 00029 define("GLOSSARY_SHOW_NOT_CATEGORISED", -1); 00030 00031 define("GLOSSARY_NO_VIEW", -1); 00032 define("GLOSSARY_STANDARD_VIEW", 0); 00033 define("GLOSSARY_CATEGORY_VIEW", 1); 00034 define("GLOSSARY_DATE_VIEW", 2); 00035 define("GLOSSARY_AUTHOR_VIEW", 3); 00036 define("GLOSSARY_ADDENTRY_VIEW", 4); 00037 define("GLOSSARY_IMPORT_VIEW", 5); 00038 define("GLOSSARY_EXPORT_VIEW", 6); 00039 define("GLOSSARY_APPROVAL_VIEW", 7); 00040 00042 00047 function glossary_add_instance($glossary) { 00048 global $DB; 00053 00054 if (empty($glossary->ratingtime) or empty($glossary->assessed)) { 00055 $glossary->assesstimestart = 0; 00056 $glossary->assesstimefinish = 0; 00057 } 00058 00059 if (empty($glossary->globalglossary) ) { 00060 $glossary->globalglossary = 0; 00061 } 00062 00063 if (!has_capability('mod/glossary:manageentries', get_context_instance(CONTEXT_SYSTEM))) { 00064 $glossary->globalglossary = 0; 00065 } 00066 00067 $glossary->timecreated = time(); 00068 $glossary->timemodified = $glossary->timecreated; 00069 00070 //Check displayformat is a valid one 00071 $formats = get_list_of_plugins('mod/glossary/formats','TEMPLATE'); 00072 if (!in_array($glossary->displayformat, $formats)) { 00073 print_error('unknowformat', '', '', $glossary->displayformat); 00074 } 00075 00076 $returnid = $DB->insert_record("glossary", $glossary); 00077 $glossary->id = $returnid; 00078 glossary_grade_item_update($glossary); 00079 00080 return $returnid; 00081 } 00082 00093 function glossary_update_instance($glossary) { 00094 global $CFG, $DB; 00095 00096 if (empty($glossary->globalglossary)) { 00097 $glossary->globalglossary = 0; 00098 } 00099 00100 if (!has_capability('mod/glossary:manageentries', get_context_instance(CONTEXT_SYSTEM))) { 00101 // keep previous 00102 unset($glossary->globalglossary); 00103 } 00104 00105 $glossary->timemodified = time(); 00106 $glossary->id = $glossary->instance; 00107 00108 if (empty($glossary->ratingtime) or empty($glossary->assessed)) { 00109 $glossary->assesstimestart = 0; 00110 $glossary->assesstimefinish = 0; 00111 } 00112 00113 //Check displayformat is a valid one 00114 $formats = get_list_of_plugins('mod/glossary/formats','TEMPLATE'); 00115 if (!in_array($glossary->displayformat, $formats)) { 00116 print_error('unknowformat', '', '', $glossary->displayformat); 00117 } 00118 00119 $DB->update_record("glossary", $glossary); 00120 if ($glossary->defaultapproval) { 00121 $DB->execute("UPDATE {glossary_entries} SET approved = 1 where approved <> 1 and glossaryid = ?", array($glossary->id)); 00122 } 00123 glossary_grade_item_update($glossary); 00124 00125 return true; 00126 } 00127 00137 function glossary_delete_instance($id) { 00138 global $DB, $CFG; 00139 00140 if (!$glossary = $DB->get_record('glossary', array('id'=>$id))) { 00141 return false; 00142 } 00143 00144 if (!$cm = get_coursemodule_from_instance('glossary', $id)) { 00145 return false; 00146 } 00147 00148 if (!$context = get_context_instance(CONTEXT_MODULE, $cm->id)) { 00149 return false; 00150 } 00151 00152 $fs = get_file_storage(); 00153 00154 if ($glossary->mainglossary) { 00155 // unexport entries 00156 $sql = "SELECT ge.id, ge.sourceglossaryid, cm.id AS sourcecmid 00157 FROM {glossary_entries} ge 00158 JOIN {modules} m ON m.name = 'glossary' 00159 JOIN {course_modules} cm ON (cm.module = m.id AND cm.instance = ge.sourceglossaryid) 00160 WHERE ge.glossaryid = ? AND ge.sourceglossaryid > 0"; 00161 00162 if ($exported = $DB->get_records_sql($sql, array($id))) { 00163 foreach ($exported as $entry) { 00164 $entry->glossaryid = $entry->sourceglossaryid; 00165 $entry->sourceglossaryid = 0; 00166 $newcontext = get_context_instance(CONTEXT_MODULE, $entry->sourcecmid); 00167 if ($oldfiles = $fs->get_area_files($context->id, 'mod_glossary', 'attachment', $entry->id)) { 00168 foreach ($oldfiles as $oldfile) { 00169 $file_record = new stdClass(); 00170 $file_record->contextid = $newcontext->id; 00171 $fs->create_file_from_storedfile($file_record, $oldfile); 00172 } 00173 $fs->delete_area_files($context->id, 'mod_glossary', 'attachment', $entry->id); 00174 $entry->attachment = '1'; 00175 } else { 00176 $entry->attachment = '0'; 00177 } 00178 $DB->update_record('glossary_entries', $entry); 00179 } 00180 } 00181 } else { 00182 // move exported entries to main glossary 00183 $sql = "UPDATE {glossary_entries} 00184 SET sourceglossaryid = 0 00185 WHERE sourceglossaryid = ?"; 00186 $DB->execute($sql, array($id)); 00187 } 00188 00189 // Delete any dependent records 00190 $entry_select = "SELECT id FROM {glossary_entries} WHERE glossaryid = ?"; 00191 $DB->delete_records_select('comments', "contextid=? AND commentarea=? AND itemid IN ($entry_select)", array($id, 'glossary_entry', $context->id)); 00192 $DB->delete_records_select('glossary_alias', "entryid IN ($entry_select)", array($id)); 00193 00194 $category_select = "SELECT id FROM {glossary_categories} WHERE glossaryid = ?"; 00195 $DB->delete_records_select('glossary_entries_categories', "categoryid IN ($category_select)", array($id)); 00196 $DB->delete_records('glossary_categories', array('glossaryid'=>$id)); 00197 $DB->delete_records('glossary_entries', array('glossaryid'=>$id)); 00198 00199 // delete all files 00200 $fs->delete_area_files($context->id); 00201 00202 glossary_grade_item_delete($glossary); 00203 00204 return $DB->delete_records('glossary', array('id'=>$id)); 00205 } 00206 00220 function glossary_user_outline($course, $user, $mod, $glossary) { 00221 global $CFG; 00222 00223 require_once("$CFG->libdir/gradelib.php"); 00224 $grades = grade_get_grades($course->id, 'mod', 'glossary', $glossary->id, $user->id); 00225 if (empty($grades->items[0]->grades)) { 00226 $grade = false; 00227 } else { 00228 $grade = reset($grades->items[0]->grades); 00229 } 00230 00231 if ($entries = glossary_get_user_entries($glossary->id, $user->id)) { 00232 $result = new stdClass(); 00233 $result->info = count($entries) . ' ' . get_string("entries", "glossary"); 00234 00235 $lastentry = array_pop($entries); 00236 $result->time = $lastentry->timemodified; 00237 00238 if ($grade) { 00239 $result->info .= ', ' . get_string('grade') . ': ' . $grade->str_long_grade; 00240 } 00241 return $result; 00242 } else if ($grade) { 00243 $result = new stdClass(); 00244 $result->info = get_string('grade') . ': ' . $grade->str_long_grade; 00245 00246 //datesubmitted == time created. dategraded == time modified or time overridden 00247 //if grade was last modified by the user themselves use date graded. Otherwise use date submitted 00248 //TODO: move this copied & pasted code somewhere in the grades API. See MDL-26704 00249 if ($grade->usermodified == $user->id || empty($grade->datesubmitted)) { 00250 $result->time = $grade->dategraded; 00251 } else { 00252 $result->time = $grade->datesubmitted; 00253 } 00254 00255 return $result; 00256 } 00257 return NULL; 00258 } 00259 00266 function glossary_get_user_entries($glossaryid, $userid) { 00268 global $DB; 00269 00270 return $DB->get_records_sql("SELECT e.*, u.firstname, u.lastname, u.email, u.picture 00271 FROM {glossary} g, {glossary_entries} e, {user} u 00272 WHERE g.id = ? 00273 AND e.glossaryid = g.id 00274 AND e.userid = ? 00275 AND e.userid = u.id 00276 ORDER BY e.timemodified ASC", array($glossaryid, $userid)); 00277 } 00278 00289 function glossary_user_complete($course, $user, $mod, $glossary) { 00290 global $CFG, $OUTPUT; 00291 require_once("$CFG->libdir/gradelib.php"); 00292 00293 $grades = grade_get_grades($course->id, 'mod', 'glossary', $glossary->id, $user->id); 00294 if (!empty($grades->items[0]->grades)) { 00295 $grade = reset($grades->items[0]->grades); 00296 echo $OUTPUT->container(get_string('grade').': '.$grade->str_long_grade); 00297 if ($grade->str_feedback) { 00298 echo $OUTPUT->container(get_string('feedback').': '.$grade->str_feedback); 00299 } 00300 } 00301 00302 if ($entries = glossary_get_user_entries($glossary->id, $user->id)) { 00303 echo '<table width="95%" border="0"><tr><td>'; 00304 foreach ($entries as $entry) { 00305 $cm = get_coursemodule_from_instance("glossary", $glossary->id, $course->id); 00306 glossary_print_entry($course, $cm, $glossary, $entry,"","",0); 00307 echo '<p>'; 00308 } 00309 echo '</td></tr></table>'; 00310 } 00311 } 00325 function glossary_print_recent_activity($course, $viewfullnames, $timestart) { 00326 global $CFG, $USER, $DB, $OUTPUT; 00327 00328 //TODO: use timestamp in approved field instead of changing timemodified when approving in 2.0 00329 if (!defined('GLOSSARY_RECENT_ACTIVITY_LIMIT')) { 00330 define('GLOSSARY_RECENT_ACTIVITY_LIMIT', 50); 00331 } 00332 00333 $modinfo = get_fast_modinfo($course); 00334 $ids = array(); 00335 00336 foreach ($modinfo->cms as $cm) { 00337 if ($cm->modname != 'glossary') { 00338 continue; 00339 } 00340 if (!$cm->uservisible) { 00341 continue; 00342 } 00343 $ids[$cm->instance] = $cm->id; 00344 } 00345 00346 if (!$ids) { 00347 return false; 00348 } 00349 00350 // generate list of approval capabilities for all glossaries in the course. 00351 $approvals = array(); 00352 foreach ($ids as $glinstanceid => $glcmid) { 00353 $context = get_context_instance(CONTEXT_MODULE, $glcmid); 00354 // get records glossary entries that are approved if user has no capability to approve entries. 00355 if (has_capability('mod/glossary:approve', $context)) { 00356 $approvals[] = ' ge.glossaryid = :glsid'.$glinstanceid.' '; 00357 } else { 00358 $approvals[] = ' (ge.approved = 1 AND ge.glossaryid = :glsid'.$glinstanceid.') '; 00359 } 00360 $params['glsid'.$glinstanceid] = $glinstanceid; 00361 } 00362 00363 $selectsql = 'SELECT ge.id, ge.concept, ge.approved, ge.timemodified, ge.glossaryid, 00364 '.user_picture::fields('u',null,'userid'); 00365 $countsql = 'SELECT COUNT(*)'; 00366 00367 $joins = array(' FROM {glossary_entries} ge '); 00368 $joins[] = 'JOIN {user} u ON u.id = ge.userid '; 00369 $fromsql = implode($joins, "\n"); 00370 00371 $params['timestart'] = $timestart; 00372 $clausesql = ' WHERE ge.timemodified > :timestart AND ('; 00373 $approvalsql = implode($approvals, ' OR '); 00374 00375 $ordersql = ') ORDER BY ge.timemodified ASC'; 00376 00377 $entries = $DB->get_records_sql($selectsql.$fromsql.$clausesql.$approvalsql.$ordersql, $params, 0, (GLOSSARY_RECENT_ACTIVITY_LIMIT+1)); 00378 00379 if (empty($entries)) { 00380 return false; 00381 } 00382 00383 echo $OUTPUT->heading(get_string('newentries', 'glossary').':'); 00384 00385 $strftimerecent = get_string('strftimerecent'); 00386 $entrycount = 0; 00387 foreach ($entries as $entry) { 00388 if ($entrycount < GLOSSARY_RECENT_ACTIVITY_LIMIT) { 00389 if ($entry->approved) { 00390 $dimmed = ''; 00391 $urlparams = array('g' => $entry->glossaryid, 'mode' => 'entry', 'hook' => $entry->id); 00392 } else { 00393 $dimmed = ' dimmed_text'; 00394 $urlparams = array('id' => $ids[$entry->glossaryid], 'mode' => 'approval', 'hook' => format_text($entry->concept, true)); 00395 } 00396 $link = new moodle_url($CFG->wwwroot.'/mod/glossary/view.php' , $urlparams); 00397 echo '<div class="head'.$dimmed.'">'; 00398 echo '<div class="date">'.userdate($entry->timemodified, $strftimerecent).'</div>'; 00399 echo '<div class="name">'.fullname($entry, $viewfullnames).'</div>'; 00400 echo '</div>'; 00401 echo '<div class="info"><a href="'.$link.'">'.format_text($entry->concept, true).'</a></div>'; 00402 $entrycount += 1; 00403 } else { 00404 $numnewentries = $DB->count_records_sql($countsql.$joins[0].$clausesql.$approvalsql.')', $params); 00405 echo '<div class="head"><div class="activityhead">'.get_string('andmorenewentries', 'glossary', $numnewentries - GLOSSARY_RECENT_ACTIVITY_LIMIT).'</div></div>'; 00406 break; 00407 } 00408 } 00409 00410 return true; 00411 } 00412 00417 function glossary_log_info($log) { 00418 global $DB; 00419 00420 return $DB->get_record_sql("SELECT e.*, u.firstname, u.lastname 00421 FROM {glossary_entries} e, {user} u 00422 WHERE e.id = ? AND u.id = ?", array($log->info, $log->userid)); 00423 } 00424 00431 function glossary_cron () { 00432 return true; 00433 } 00434 00443 function glossary_get_user_grades($glossary, $userid=0) { 00444 global $CFG; 00445 00446 require_once($CFG->dirroot.'/rating/lib.php'); 00447 00448 $ratingoptions = new stdClass; 00449 00450 //need these to work backwards to get a context id. Is there a better way to get contextid from a module instance? 00451 $ratingoptions->modulename = 'glossary'; 00452 $ratingoptions->moduleid = $glossary->id; 00453 $ratingoptions->component = 'mod_glossary'; 00454 $ratingoptions->ratingarea = 'entry'; 00455 00456 $ratingoptions->userid = $userid; 00457 $ratingoptions->aggregationmethod = $glossary->assessed; 00458 $ratingoptions->scaleid = $glossary->scale; 00459 $ratingoptions->itemtable = 'glossary_entries'; 00460 $ratingoptions->itemtableusercolumn = 'userid'; 00461 00462 $rm = new rating_manager(); 00463 return $rm->get_user_grades($ratingoptions); 00464 } 00465 00474 function glossary_rating_permissions($contextid, $component, $ratingarea) { 00475 if ($component != 'mod_glossary' || $ratingarea != 'entry') { 00476 // We don't know about this component/ratingarea so just return null to get the 00477 // default restrictive permissions. 00478 return null; 00479 } 00480 $context = get_context_instance_by_id($contextid); 00481 return array( 00482 'view' => has_capability('mod/glossary:viewrating', $context), 00483 'viewany' => has_capability('mod/glossary:viewanyrating', $context), 00484 'viewall' => has_capability('mod/glossary:viewallratings', $context), 00485 'rate' => has_capability('mod/glossary:rate', $context) 00486 ); 00487 } 00488 00502 function glossary_rating_validate($params) { 00503 global $DB, $USER; 00504 00505 // Check the component is mod_forum 00506 if ($params['component'] != 'mod_glossary') { 00507 throw new rating_exception('invalidcomponent'); 00508 } 00509 00510 // Check the ratingarea is post (the only rating area in forum) 00511 if ($params['ratingarea'] != 'entry') { 00512 throw new rating_exception('invalidratingarea'); 00513 } 00514 00515 // Check the rateduserid is not the current user .. you can't rate your own posts 00516 if ($params['rateduserid'] == $USER->id) { 00517 throw new rating_exception('nopermissiontorate'); 00518 } 00519 00520 $glossarysql = "SELECT g.id as glossaryid, g.scale, g.course, e.userid as userid, e.approved, e.timecreated, g.assesstimestart, g.assesstimefinish 00521 FROM {glossary_entries} e 00522 JOIN {glossary} g ON e.glossaryid = g.id 00523 WHERE e.id = :itemid"; 00524 $glossaryparams = array('itemid' => $params['itemid']); 00525 $info = $DB->get_record_sql($glossarysql, $glossaryparams); 00526 if (!$info) { 00527 //item doesn't exist 00528 throw new rating_exception('invaliditemid'); 00529 } 00530 00531 if ($info->scale != $params['scaleid']) { 00532 //the scale being submitted doesnt match the one in the database 00533 throw new rating_exception('invalidscaleid'); 00534 } 00535 00536 //check that the submitted rating is valid for the scale 00537 00538 // lower limit 00539 if ($params['rating'] < 0 && $params['rating'] != RATING_UNSET_RATING) { 00540 throw new rating_exception('invalidnum'); 00541 } 00542 00543 // upper limit 00544 if ($info->scale < 0) { 00545 //its a custom scale 00546 $scalerecord = $DB->get_record('scale', array('id' => -$info->scale)); 00547 if ($scalerecord) { 00548 $scalearray = explode(',', $scalerecord->scale); 00549 if ($params['rating'] > count($scalearray)) { 00550 throw new rating_exception('invalidnum'); 00551 } 00552 } else { 00553 throw new rating_exception('invalidscaleid'); 00554 } 00555 } else if ($params['rating'] > $info->scale) { 00556 //if its numeric and submitted rating is above maximum 00557 throw new rating_exception('invalidnum'); 00558 } 00559 00560 if (!$info->approved) { 00561 //item isnt approved 00562 throw new rating_exception('nopermissiontorate'); 00563 } 00564 00565 //check the item we're rating was created in the assessable time window 00566 if (!empty($info->assesstimestart) && !empty($info->assesstimefinish)) { 00567 if ($info->timecreated < $info->assesstimestart || $info->timecreated > $info->assesstimefinish) { 00568 throw new rating_exception('notavailable'); 00569 } 00570 } 00571 00572 $cm = get_coursemodule_from_instance('glossary', $info->glossaryid, $info->course, false, MUST_EXIST); 00573 $context = get_context_instance(CONTEXT_MODULE, $cm->id, MUST_EXIST); 00574 00575 // if the supplied context doesnt match the item's context 00576 if ($context->id != $params['context']->id) { 00577 throw new rating_exception('invalidcontext'); 00578 } 00579 00580 return true; 00581 } 00582 00591 function glossary_update_grades($glossary=null, $userid=0, $nullifnone=true) { 00592 global $CFG, $DB; 00593 require_once($CFG->libdir.'/gradelib.php'); 00594 00595 if (!$glossary->assessed) { 00596 glossary_grade_item_update($glossary); 00597 00598 } else if ($grades = glossary_get_user_grades($glossary, $userid)) { 00599 glossary_grade_item_update($glossary, $grades); 00600 00601 } else if ($userid and $nullifnone) { 00602 $grade = new stdClass(); 00603 $grade->userid = $userid; 00604 $grade->rawgrade = NULL; 00605 glossary_grade_item_update($glossary, $grade); 00606 00607 } else { 00608 glossary_grade_item_update($glossary); 00609 } 00610 } 00611 00617 function glossary_upgrade_grades() { 00618 global $DB; 00619 00620 $sql = "SELECT COUNT('x') 00621 FROM {glossary} g, {course_modules} cm, {modules} m 00622 WHERE m.name='glossary' AND m.id=cm.module AND cm.instance=g.id"; 00623 $count = $DB->count_records_sql($sql); 00624 00625 $sql = "SELECT g.*, cm.idnumber AS cmidnumber, g.course AS courseid 00626 FROM {glossary} g, {course_modules} cm, {modules} m 00627 WHERE m.name='glossary' AND m.id=cm.module AND cm.instance=g.id"; 00628 $rs = $DB->get_recordset_sql($sql); 00629 if ($rs->valid()) { 00630 $pbar = new progress_bar('glossaryupgradegrades', 500, true); 00631 $i=0; 00632 foreach ($rs as $glossary) { 00633 $i++; 00634 upgrade_set_timeout(60*5); // set up timeout, may also abort execution 00635 glossary_update_grades($glossary, 0, false); 00636 $pbar->update($i, $count, "Updating Glossary grades ($i/$count)."); 00637 } 00638 } 00639 $rs->close(); 00640 } 00641 00650 function glossary_grade_item_update($glossary, $grades=NULL) { 00651 global $CFG; 00652 require_once($CFG->libdir.'/gradelib.php'); 00653 00654 $params = array('itemname'=>$glossary->name, 'idnumber'=>$glossary->cmidnumber); 00655 00656 if (!$glossary->assessed or $glossary->scale == 0) { 00657 $params['gradetype'] = GRADE_TYPE_NONE; 00658 00659 } else if ($glossary->scale > 0) { 00660 $params['gradetype'] = GRADE_TYPE_VALUE; 00661 $params['grademax'] = $glossary->scale; 00662 $params['grademin'] = 0; 00663 00664 } else if ($glossary->scale < 0) { 00665 $params['gradetype'] = GRADE_TYPE_SCALE; 00666 $params['scaleid'] = -$glossary->scale; 00667 } 00668 00669 if ($grades === 'reset') { 00670 $params['reset'] = true; 00671 $grades = NULL; 00672 } 00673 00674 return grade_update('mod/glossary', $glossary->course, 'mod', 'glossary', $glossary->id, 0, $grades, $params); 00675 } 00676 00683 function glossary_grade_item_delete($glossary) { 00684 global $CFG; 00685 require_once($CFG->libdir.'/gradelib.php'); 00686 00687 return grade_update('mod/glossary', $glossary->course, 'mod', 'glossary', $glossary->id, 0, NULL, array('deleted'=>1)); 00688 } 00689 00699 function glossary_get_participants($glossaryid) { 00700 global $DB; 00701 00702 //Get students 00703 $students = $DB->get_records_sql("SELECT DISTINCT u.id, u.id 00704 FROM {user} u, {glossary_entries} g 00705 WHERE g.glossaryid = ? AND u.id = g.userid", array($glossaryid)); 00706 00707 //Return students array (it contains an array of unique users) 00708 return $students; 00709 } 00710 00717 function glossary_scale_used ($glossaryid,$scaleid) { 00718 //This function returns if a scale is being used by one glossary 00719 global $DB; 00720 00721 $return = false; 00722 00723 $rec = $DB->get_record("glossary", array("id"=>$glossaryid, "scale"=>-$scaleid)); 00724 00725 if (!empty($rec) && !empty($scaleid)) { 00726 $return = true; 00727 } 00728 00729 return $return; 00730 } 00731 00741 function glossary_scale_used_anywhere($scaleid) { 00742 global $DB; 00743 00744 if ($scaleid and $DB->record_exists('glossary', array('scale'=>-$scaleid))) { 00745 return true; 00746 } else { 00747 return false; 00748 } 00749 } 00750 00754 00765 function glossary_get_available_formats() { 00766 global $CFG, $DB; 00767 00768 //Get available formats (plugin) and insert (if necessary) them into glossary_formats 00769 $formats = get_list_of_plugins('mod/glossary/formats', 'TEMPLATE'); 00770 $pluginformats = array(); 00771 foreach ($formats as $format) { 00772 //If the format file exists 00773 if (file_exists($CFG->dirroot.'/mod/glossary/formats/'.$format.'/'.$format.'_format.php')) { 00774 include_once($CFG->dirroot.'/mod/glossary/formats/'.$format.'/'.$format.'_format.php'); 00775 //If the function exists 00776 if (function_exists('glossary_show_entry_'.$format)) { 00777 //Acummulate it as a valid format 00778 $pluginformats[] = $format; 00779 //If the format doesn't exist in the table 00780 if (!$rec = $DB->get_record('glossary_formats', array('name'=>$format))) { 00781 //Insert the record in glossary_formats 00782 $gf = new stdClass(); 00783 $gf->name = $format; 00784 $gf->popupformatname = $format; 00785 $gf->visible = 1; 00786 $DB->insert_record("glossary_formats",$gf); 00787 } 00788 } 00789 } 00790 } 00791 00792 //Delete non_existent formats from glossary_formats table 00793 $formats = $DB->get_records("glossary_formats"); 00794 foreach ($formats as $format) { 00795 $todelete = false; 00796 //If the format in DB isn't a valid previously detected format then delete the record 00797 if (!in_array($format->name,$pluginformats)) { 00798 $todelete = true; 00799 } 00800 00801 if ($todelete) { 00802 //Delete the format 00803 $DB->delete_records('glossary_formats', array('name'=>$format->name)); 00804 //Reasign existing glossaries to default (dictionary) format 00805 if ($glossaries = $DB->get_records('glossary', array('displayformat'=>$format->name))) { 00806 foreach($glossaries as $glossary) { 00807 $DB->set_field('glossary','displayformat','dictionary', array('id'=>$glossary->id)); 00808 } 00809 } 00810 } 00811 } 00812 00813 //Now everything is ready in glossary_formats table 00814 $formats = $DB->get_records("glossary_formats"); 00815 00816 return $formats; 00817 } 00818 00824 function glossary_debug($debug,$text,$br=1) { 00825 if ( $debug ) { 00826 echo '<font color="red">' . $text . '</font>'; 00827 if ( $br ) { 00828 echo '<br />'; 00829 } 00830 } 00831 } 00832 00841 function glossary_get_entries($glossaryid, $entrylist, $pivot = "") { 00842 global $DB; 00843 if ($pivot) { 00844 $pivot .= ","; 00845 } 00846 00847 return $DB->get_records_sql("SELECT $pivot id,userid,concept,definition,format 00848 FROM {glossary_entries} 00849 WHERE glossaryid = ? 00850 AND id IN ($entrylist)", array($glossaryid)); 00851 } 00852 00860 function glossary_get_entries_search($concept, $courseid) { 00861 global $CFG, $DB; 00862 00863 //Check if the user is an admin 00864 $bypassadmin = 1; //This means NO (by default) 00865 if (has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_SYSTEM))) { 00866 $bypassadmin = 0; //This means YES 00867 } 00868 00869 //Check if the user is a teacher 00870 $bypassteacher = 1; //This means NO (by default) 00871 if (has_capability('mod/glossary:manageentries', get_context_instance(CONTEXT_COURSE, $courseid))) { 00872 $bypassteacher = 0; //This means YES 00873 } 00874 00875 $conceptlower = moodle_strtolower(trim($concept)); 00876 00877 $params = array('courseid1'=>$courseid, 'courseid2'=>$courseid, 'conceptlower'=>$conceptlower, 'concept'=>$concept); 00878 00879 return $DB->get_records_sql("SELECT e.*, g.name as glossaryname, cm.id as cmid, cm.course as courseid 00880 FROM {glossary_entries} e, {glossary} g, 00881 {course_modules} cm, {modules} m 00882 WHERE m.name = 'glossary' AND 00883 cm.module = m.id AND 00884 (cm.visible = 1 OR cm.visible = $bypassadmin OR 00885 (cm.course = :courseid1 AND cm.visible = $bypassteacher)) AND 00886 g.id = cm.instance AND 00887 e.glossaryid = g.id AND 00888 ( (e.casesensitive != 0 AND LOWER(concept) = :conceptlower) OR 00889 (e.casesensitive = 0 and concept = :concept)) AND 00890 (g.course = :courseid2 OR g.globalglossary = 1) AND 00891 e.usedynalink != 0 AND 00892 g.usedynalink != 0", $params); 00893 } 00894 00909 function glossary_print_entry($course, $cm, $glossary, $entry, $mode='',$hook='',$printicons = 1, $displayformat = -1, $printview = false) { 00910 global $USER, $CFG; 00911 $return = false; 00912 if ( $displayformat < 0 ) { 00913 $displayformat = $glossary->displayformat; 00914 } 00915 if ($entry->approved or ($USER->id == $entry->userid) or ($mode == 'approval' and !$entry->approved) ) { 00916 $formatfile = $CFG->dirroot.'/mod/glossary/formats/'.$displayformat.'/'.$displayformat.'_format.php'; 00917 if ($printview) { 00918 $functionname = 'glossary_print_entry_'.$displayformat; 00919 } else { 00920 $functionname = 'glossary_show_entry_'.$displayformat; 00921 } 00922 00923 if (file_exists($formatfile)) { 00924 include_once($formatfile); 00925 if (function_exists($functionname)) { 00926 $return = $functionname($course, $cm, $glossary, $entry,$mode,$hook,$printicons); 00927 } else if ($printview) { 00928 //If the glossary_print_entry_XXXX function doesn't exist, print default (old) print format 00929 $return = glossary_print_entry_default($entry, $glossary, $cm); 00930 } 00931 } 00932 } 00933 return $return; 00934 } 00935 00944 function glossary_print_entry_default ($entry, $glossary, $cm) { 00945 global $CFG; 00946 00947 require_once($CFG->libdir . '/filelib.php'); 00948 00949 echo '<h3>'. strip_tags($entry->concept) . ': </h3>'; 00950 00951 $definition = $entry->definition; 00952 00953 $definition = '<span class="nolink">' . strip_tags($definition) . '</span>'; 00954 00955 $context = get_context_instance(CONTEXT_MODULE, $cm->id); 00956 $definition = file_rewrite_pluginfile_urls($definition, 'pluginfile.php', $context->id, 'mod_glossary', 'entry', $entry->id); 00957 00958 $options = new stdClass(); 00959 $options->para = false; 00960 $options->trusted = $entry->definitiontrust; 00961 $options->context = $context; 00962 $options->overflowdiv = true; 00963 $definition = format_text($definition, $entry->definitionformat, $options); 00964 echo ($definition); 00965 echo '<br /><br />'; 00966 } 00967 00972 function glossary_print_entry_concept($entry, $return=false) { 00973 global $OUTPUT; 00974 $options = new stdClass(); 00975 $options->para = false; 00976 $text = format_text($OUTPUT->heading('<span class="nolink">' . $entry->concept . '</span>', 3, 'nolink'), FORMAT_MOODLE, $options); 00977 if (!empty($entry->highlight)) { 00978 $text = highlight($entry->highlight, $text); 00979 } 00980 00981 if ($return) { 00982 return $text; 00983 } else { 00984 echo $text; 00985 } 00986 } 00987 00995 function glossary_print_entry_definition($entry, $glossary, $cm) { 00996 global $DB, $GLOSSARY_EXCLUDECONCEPTS; 00997 00998 $definition = $entry->definition; 00999 01000 //Calculate all the strings to be no-linked 01001 //First, the concept 01002 $GLOSSARY_EXCLUDECONCEPTS = array($entry->concept); 01003 //Now the aliases 01004 if ( $aliases = $DB->get_records('glossary_alias', array('entryid'=>$entry->id))) { 01005 foreach ($aliases as $alias) { 01006 $GLOSSARY_EXCLUDECONCEPTS[]=trim($alias->alias); 01007 } 01008 } 01009 01010 $context = get_context_instance(CONTEXT_MODULE, $cm->id); 01011 $definition = file_rewrite_pluginfile_urls($definition, 'pluginfile.php', $context->id, 'mod_glossary', 'entry', $entry->id); 01012 01013 $options = new stdClass(); 01014 $options->para = false; 01015 $options->trusted = $entry->definitiontrust; 01016 $options->context = $context; 01017 $options->overflowdiv = true; 01018 $text = format_text($definition, $entry->definitionformat, $options); 01019 01020 // Stop excluding concepts from autolinking 01021 unset($GLOSSARY_EXCLUDECONCEPTS); 01022 01023 if (!empty($entry->highlight)) { 01024 $text = highlight($entry->highlight, $text); 01025 } 01026 if (isset($entry->footer)) { // Unparsed footer info 01027 $text .= $entry->footer; 01028 } 01029 echo $text; 01030 } 01031 01044 function glossary_print_entry_aliases($course, $cm, $glossary, $entry,$mode='',$hook='', $type = 'print') { 01045 global $DB; 01046 01047 $return = ''; 01048 if ( $aliases = $DB->get_records('glossary_alias', array('entryid'=>$entry->id))) { 01049 foreach ($aliases as $alias) { 01050 if (trim($alias->alias)) { 01051 if ($return == '') { 01052 $return = '<select style="font-size:8pt">'; 01053 } 01054 $return .= "<option>$alias->alias</option>"; 01055 } 01056 } 01057 if ($return != '') { 01058 $return .= '</select>'; 01059 } 01060 } 01061 if ($type == 'print') { 01062 echo $return; 01063 } else { 01064 return $return; 01065 } 01066 } 01067 01082 function glossary_print_entry_icons($course, $cm, $glossary, $entry, $mode='',$hook='', $type = 'print') { 01083 global $USER, $CFG, $DB, $OUTPUT; 01084 01085 $context = get_context_instance(CONTEXT_MODULE, $cm->id); 01086 01087 $output = false; //To decide if we must really return text in "return". Activate when needed only! 01088 $importedentry = ($entry->sourceglossaryid == $glossary->id); 01089 $ismainglossary = $glossary->mainglossary; 01090 01091 01092 $return = '<span class="commands">'; 01093 // Differentiate links for each entry. 01094 $altsuffix = ': '.strip_tags(format_text($entry->concept)); 01095 01096 if (!$entry->approved) { 01097 $output = true; 01098 $return .= get_string('entryishidden','glossary'); 01099 } 01100 01101 $iscurrentuser = ($entry->userid == $USER->id); 01102 01103 if (has_capability('mod/glossary:manageentries', $context) or (isloggedin() and has_capability('mod/glossary:write', $context) and $iscurrentuser)) { 01104 // only teachers can export entries so check it out 01105 if (has_capability('mod/glossary:export', $context) and !$ismainglossary and !$importedentry) { 01106 $mainglossary = $DB->get_record('glossary', array('mainglossary'=>1,'course'=>$course->id)); 01107 if ( $mainglossary ) { // if there is a main glossary defined, allow to export the current entry 01108 $output = true; 01109 $return .= ' <a title="'.get_string('exporttomainglossary','glossary') . '" href="exportentry.php?id='.$entry->id.'&prevmode='.$mode.'&hook='.urlencode($hook).'"><img src="'.$OUTPUT->pix_url('export', 'glossary').'" class="iconsmall" alt="'.get_string('exporttomainglossary','glossary').$altsuffix.'" /></a>'; 01110 } 01111 } 01112 01113 if ( $entry->sourceglossaryid ) { 01114 $icon = $OUTPUT->pix_url('minus', 'glossary'); // graphical metaphor (minus) for deleting an imported entry 01115 } else { 01116 $icon = $OUTPUT->pix_url('t/delete'); 01117 } 01118 01119 //Decide if an entry is editable: 01120 // -It isn't a imported entry (so nobody can edit a imported (from secondary to main) entry)) and 01121 // -The user is teacher or he is a student with time permissions (edit period or editalways defined). 01122 $ineditperiod = ((time() - $entry->timecreated < $CFG->maxeditingtime) || $glossary->editalways); 01123 if ( !$importedentry and (has_capability('mod/glossary:manageentries', $context) or ($entry->userid == $USER->id and ($ineditperiod and has_capability('mod/glossary:write', $context))))) { 01124 $output = true; 01125 $return .= " <a title=\"" . get_string("delete") . "\" href=\"deleteentry.php?id=$cm->id&mode=delete&entry=$entry->id&prevmode=$mode&hook=".urlencode($hook)."\"><img src=\""; 01126 $return .= $icon; 01127 $return .= "\" class=\"iconsmall\" alt=\"" . get_string("delete") .$altsuffix."\" /></a> "; 01128 01129 $return .= " <a title=\"" . get_string("edit") . "\" href=\"edit.php?cmid=$cm->id&id=$entry->id&mode=$mode&hook=".urlencode($hook)."\"><img src=\"" . $OUTPUT->pix_url('t/edit') . "\" class=\"iconsmall\" alt=\"" . get_string("edit") .$altsuffix. "\" /></a>"; 01130 } elseif ( $importedentry ) { 01131 $return .= " <font size=\"-1\">" . get_string("exportedentry","glossary") . "</font>"; 01132 } 01133 } 01134 if (!empty($CFG->enableportfolios) && (has_capability('mod/glossary:exportentry', $context) || ($iscurrentuser && has_capability('mod/glossary:exportownentry', $context)))) { 01135 require_once($CFG->libdir . '/portfoliolib.php'); 01136 $button = new portfolio_add_button(); 01137 $button->set_callback_options('glossary_entry_portfolio_caller', array('id' => $cm->id, 'entryid' => $entry->id), '/mod/glossary/locallib.php'); 01138 01139 $filecontext = $context; 01140 if ($entry->sourceglossaryid == $cm->instance) { 01141 if ($maincm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) { 01142 $filecontext = get_context_instance(CONTEXT_MODULE, $maincm->id); 01143 } 01144 } 01145 $fs = get_file_storage(); 01146 if ($files = $fs->get_area_files($filecontext->id, 'mod_glossary', 'attachment', $entry->id, "timemodified", false)) { 01147 $button->set_formats(PORTFOLIO_FORMAT_RICHHTML); 01148 } else { 01149 $button->set_formats(PORTFOLIO_FORMAT_PLAINHTML); 01150 } 01151 01152 $return .= $button->to_html(PORTFOLIO_ADD_ICON_LINK); 01153 } 01154 $return .= " "; // just to make up a little the output in Mozilla ;) 01155 01156 $return .= '</span>'; 01157 01158 if (!empty($CFG->usecomments) && has_capability('mod/glossary:comment', $context) and $glossary->allowcomments) { 01159 require_once($CFG->dirroot . '/comment/lib.php'); 01160 $cmt = new stdClass(); 01161 $cmt->component = 'mod_glossary'; 01162 $cmt->context = $context; 01163 $cmt->course = $course; 01164 $cmt->cm = $cm; 01165 $cmt->area = 'glossary_entry'; 01166 $cmt->itemid = $entry->id; 01167 $cmt->showcount = true; 01168 $comment = new comment($cmt); 01169 $return .= '<div>'.$comment->output(true).'</div>'; 01170 $output = true; 01171 } 01172 01173 //If we haven't calculated any REAL thing, delete result ($return) 01174 if (!$output) { 01175 $return = ''; 01176 } 01177 //Print or get 01178 if ($type == 'print') { 01179 echo $return; 01180 } else { 01181 return $return; 01182 } 01183 } 01184 01196 function glossary_print_entry_lower_section($course, $cm, $glossary, $entry, $mode, $hook, $printicons, $aliases=true) { 01197 if ($aliases) { 01198 $aliases = glossary_print_entry_aliases($course, $cm, $glossary, $entry, $mode, $hook,'html'); 01199 } 01200 $icons = ''; 01201 if ($printicons) { 01202 $icons = glossary_print_entry_icons($course, $cm, $glossary, $entry, $mode, $hook,'html'); 01203 } 01204 if ($aliases || $icons || !empty($entry->rating)) { 01205 echo '<table>'; 01206 if ( $aliases ) { 01207 echo '<tr valign="top"><td class="aliases">' . 01208 get_string('aliases','glossary').': '.$aliases . '</td></tr>'; 01209 } 01210 if ($icons) { 01211 echo '<tr valign="top"><td class="icons">'.$icons.'</td></tr>'; 01212 } 01213 if (!empty($entry->rating)) { 01214 echo '<tr valign="top"><td class="ratings">'; 01215 glossary_print_entry_ratings($course, $entry); 01216 echo '</td></tr>'; 01217 } 01218 echo '</table>'; 01219 } 01220 } 01221 01225 function glossary_print_entry_attachment($entry, $cm, $format=NULL, $align="right", $insidetable=true) { 01229 if ($entry->attachment) { 01230 if ($insidetable) { 01231 echo "<table border=\"0\" width=\"100%\" align=\"$align\"><tr><td align=\"$align\" nowrap=\"nowrap\">\n"; 01232 } 01233 echo glossary_print_attachments($entry, $cm, $format, $align); 01234 if ($insidetable) { 01235 echo "</td></tr></table>\n"; 01236 } 01237 } 01238 } 01239 01248 function glossary_print_entry_approval($cm, $entry, $mode, $align="right", $insidetable=true) { 01249 global $CFG, $OUTPUT; 01250 01251 if ($mode == 'approval' and !$entry->approved) { 01252 if ($insidetable) { 01253 echo '<table class="glossaryapproval" align="'.$align.'"><tr><td align="'.$align.'">'; 01254 } 01255 echo '<a title="'.get_string('approve','glossary').'" href="approve.php?eid='.$entry->id.'&mode='.$mode.'&sesskey='.sesskey().'"><img align="'.$align.'" src="'.$OUTPUT->pix_url('i/approve') . '" style="border:0px; width:34px; height:34px" alt="'.get_string('approve','glossary').'" /></a>'; 01256 if ($insidetable) { 01257 echo '</td></tr></table>'; 01258 } 01259 } 01260 } 01261 01275 function glossary_search($course, $searchterms, $extended = 0, $glossary = NULL) { 01276 global $CFG, $DB; 01277 01278 if ( !$glossary ) { 01279 if ( $glossaries = $DB->get_records("glossary", array("course"=>$course->id)) ) { 01280 $glos = ""; 01281 foreach ( $glossaries as $glossary ) { 01282 $glos .= "$glossary->id,"; 01283 } 01284 $glos = substr($glos,0,-1); 01285 } 01286 } else { 01287 $glos = $glossary->id; 01288 } 01289 01290 if (!has_capability('mod/glossary:manageentries', get_context_instance(CONTEXT_COURSE, $glossary->course))) { 01291 $glossarymodule = $DB->get_record("modules", array("name"=>"glossary")); 01292 $onlyvisible = " AND g.id = cm.instance AND cm.visible = 1 AND cm.module = $glossarymodule->id"; 01293 $onlyvisibletable = ", {course_modules} cm"; 01294 } else { 01295 01296 $onlyvisible = ""; 01297 $onlyvisibletable = ""; 01298 } 01299 01300 if ($DB->sql_regex_supported()) { 01301 $REGEXP = $DB->sql_regex(true); 01302 $NOTREGEXP = $DB->sql_regex(false); 01303 } 01304 01305 $searchcond = array(); 01306 $params = array(); 01307 $i = 0; 01308 01309 $concat = $DB->sql_concat('e.concept', "' '", 'e.definition'); 01310 01311 01312 foreach ($searchterms as $searchterm) { 01313 $i++; 01314 01315 $NOT = false; 01316 01317 01320 if (!$DB->sql_regex_supported()) { 01321 if (substr($searchterm, 0, 1) == '-') { 01322 $NOT = true; 01323 } 01324 $searchterm = trim($searchterm, '+-'); 01325 } 01326 01327 // TODO: +- may not work for non latin languages 01328 01329 if (substr($searchterm,0,1) == '+') { 01330 $searchterm = trim($searchterm, '+-'); 01331 $searchterm = preg_quote($searchterm, '|'); 01332 $searchcond[] = "$concat $REGEXP :ss$i"; 01333 $params['ss'.$i] = "(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)"; 01334 01335 } else if (substr($searchterm,0,1) == "-") { 01336 $searchterm = trim($searchterm, '+-'); 01337 $searchterm = preg_quote($searchterm, '|'); 01338 $searchcond[] = "$concat $NOTREGEXP :ss$i"; 01339 $params['ss'.$i] = "(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)"; 01340 01341 } else { 01342 $searchcond[] = $DB->sql_like($concat, ":ss$i", false, true, $NOT); 01343 $params['ss'.$i] = "%$searchterm%"; 01344 } 01345 } 01346 01347 if (empty($searchcond)) { 01348 $totalcount = 0; 01349 return array(); 01350 } 01351 01352 $searchcond = implode(" AND ", $searchcond); 01353 01354 $sql = "SELECT e.* 01355 FROM {glossary_entries} e, {glossary} g $onlyvisibletable 01356 WHERE $searchcond 01357 AND (e.glossaryid = g.id or e.sourceglossaryid = g.id) $onlyvisible 01358 AND g.id IN ($glos) AND e.approved <> 0"; 01359 01360 return $DB->get_records_sql($sql, $params); 01361 } 01362 01370 function glossary_search_entries($searchterms, $glossary, $extended) { 01371 global $DB; 01372 01373 $course = $DB->get_record("course", array("id"=>$glossary->course)); 01374 return glossary_search($course,$searchterms,$extended,$glossary); 01375 } 01376 01391 function glossary_print_attachments($entry, $cm, $type=NULL, $align="left") { 01392 global $CFG, $DB, $OUTPUT; 01393 01394 if (!$context = get_context_instance(CONTEXT_MODULE, $cm->id)) { 01395 return ''; 01396 } 01397 01398 if ($entry->sourceglossaryid == $cm->instance) { 01399 if (!$maincm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) { 01400 return ''; 01401 } 01402 $filecontext = get_context_instance(CONTEXT_MODULE, $maincm->id); 01403 01404 } else { 01405 $filecontext = $context; 01406 } 01407 01408 $strattachment = get_string('attachment', 'glossary'); 01409 01410 $fs = get_file_storage(); 01411 01412 $imagereturn = ''; 01413 $output = ''; 01414 01415 if ($files = $fs->get_area_files($filecontext->id, 'mod_glossary', 'attachment', $entry->id, "timemodified", false)) { 01416 foreach ($files as $file) { 01417 $filename = $file->get_filename(); 01418 $mimetype = $file->get_mimetype(); 01419 $iconimage = '<img src="'.$OUTPUT->pix_url(file_mimetype_icon($mimetype)).'" class="icon" alt="'.$mimetype.'" />'; 01420 $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$context->id.'/mod_glossary/attachment/'.$entry->id.'/'.$filename); 01421 01422 if ($type == 'html') { 01423 $output .= "<a href=\"$path\">$iconimage</a> "; 01424 $output .= "<a href=\"$path\">".s($filename)."</a>"; 01425 $output .= "<br />"; 01426 01427 } else if ($type == 'text') { 01428 $output .= "$strattachment ".s($filename).":\n$path\n"; 01429 01430 } else { 01431 if (in_array($mimetype, array('image/gif', 'image/jpeg', 'image/png'))) { 01432 // Image attachments don't get printed as links 01433 $imagereturn .= "<br /><img src=\"$path\" alt=\"\" />"; 01434 } else { 01435 $output .= "<a href=\"$path\">$iconimage</a> "; 01436 $output .= format_text("<a href=\"$path\">".s($filename)."</a>", FORMAT_HTML, array('context'=>$context)); 01437 $output .= '<br />'; 01438 } 01439 } 01440 } 01441 } 01442 01443 if ($type) { 01444 return $output; 01445 } else { 01446 echo $output; 01447 return $imagereturn; 01448 } 01449 } 01450 01459 function glossary_get_file_areas($course, $cm, $context) { 01460 $areas = array(); 01461 return $areas; 01462 } 01463 01475 function glossary_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { 01476 global $CFG, $DB; 01477 01478 if ($context->contextlevel != CONTEXT_MODULE) { 01479 return false; 01480 } 01481 01482 require_course_login($course, true, $cm); 01483 01484 if ($filearea === 'attachment' or $filearea === 'entry') { 01485 $entryid = (int)array_shift($args); 01486 01487 require_course_login($course, true, $cm); 01488 01489 if (!$entry = $DB->get_record('glossary_entries', array('id'=>$entryid))) { 01490 return false; 01491 } 01492 01493 if (!$glossary = $DB->get_record('glossary', array('id'=>$cm->instance))) { 01494 return false; 01495 } 01496 01497 if ($glossary->defaultapproval and !$entry->approved and !has_capability('mod/glossary:approve', $context)) { 01498 return false; 01499 } 01500 01501 // this trickery here is because we need to support source glossary access 01502 01503 if ($entry->glossaryid == $cm->instance) { 01504 $filecontext = $context; 01505 01506 } else if ($entry->sourceglossaryid == $cm->instance) { 01507 if (!$maincm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) { 01508 return false; 01509 } 01510 $filecontext = get_context_instance(CONTEXT_MODULE, $maincm->id); 01511 01512 } else { 01513 return false; 01514 } 01515 01516 $relativepath = implode('/', $args); 01517 $fullpath = "/$filecontext->id/mod_glossary/$filearea/$entryid/$relativepath"; 01518 01519 $fs = get_file_storage(); 01520 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { 01521 return false; 01522 } 01523 01524 // finally send the file 01525 send_stored_file($file, 0, 0, true); // download MUST be forced - security! 01526 01527 } else if ($filearea === 'export') { 01528 require_login($course, false, $cm); 01529 require_capability('mod/glossary:export', $context); 01530 01531 if (!$glossary = $DB->get_record('glossary', array('id'=>$cm->instance))) { 01532 return false; 01533 } 01534 01535 $cat = array_shift($args); 01536 $cat = clean_param($cat, PARAM_ALPHANUM); 01537 01538 $filename = clean_filename(strip_tags(format_string($glossary->name)).'.xml'); 01539 $content = glossary_generate_export_file($glossary, NULL, $cat); 01540 01541 send_file($content, $filename, 0, 0, true, true); 01542 } 01543 01544 return false; 01545 } 01546 01550 function glossary_print_tabbed_table_end() { 01551 echo "</div></div>"; 01552 } 01553 01562 function glossary_print_approval_menu($cm, $glossary,$mode, $hook, $sortkey = '', $sortorder = '') { 01563 if ($glossary->showalphabet) { 01564 echo '<div class="glossaryexplain">' . get_string("explainalphabet","glossary") . '</div><br />'; 01565 } 01566 glossary_print_special_links($cm, $glossary, $mode, $hook); 01567 01568 glossary_print_alphabet_links($cm, $glossary, $mode, $hook,$sortkey, $sortorder); 01569 01570 glossary_print_all_links($cm, $glossary, $mode, $hook); 01571 01572 glossary_print_sorting_links($cm, $mode, 'CREATION', 'asc'); 01573 } 01581 function glossary_print_import_menu($cm, $glossary, $mode, $hook, $sortkey='', $sortorder = '') { 01582 echo '<div class="glossaryexplain">' . get_string("explainimport","glossary") . '</div>'; 01583 } 01584 01592 function glossary_print_export_menu($cm, $glossary, $mode, $hook, $sortkey='', $sortorder = '') { 01593 echo '<div class="glossaryexplain">' . get_string("explainexport","glossary") . '</div>'; 01594 } 01602 function glossary_print_alphabet_menu($cm, $glossary, $mode, $hook, $sortkey='', $sortorder = '') { 01603 if ( $mode != 'date' ) { 01604 if ($glossary->showalphabet) { 01605 echo '<div class="glossaryexplain">' . get_string("explainalphabet","glossary") . '</div><br />'; 01606 } 01607 01608 glossary_print_special_links($cm, $glossary, $mode, $hook); 01609 01610 glossary_print_alphabet_links($cm, $glossary, $mode, $hook, $sortkey, $sortorder); 01611 01612 glossary_print_all_links($cm, $glossary, $mode, $hook); 01613 } else { 01614 glossary_print_sorting_links($cm, $mode, $sortkey,$sortorder); 01615 } 01616 } 01617 01625 function glossary_print_author_menu($cm, $glossary,$mode, $hook, $sortkey = '', $sortorder = '') { 01626 if ($glossary->showalphabet) { 01627 echo '<div class="glossaryexplain">' . get_string("explainalphabet","glossary") . '</div><br />'; 01628 } 01629 01630 glossary_print_alphabet_links($cm, $glossary, $mode, $hook, $sortkey, $sortorder); 01631 glossary_print_all_links($cm, $glossary, $mode, $hook); 01632 glossary_print_sorting_links($cm, $mode, $sortkey,$sortorder); 01633 } 01634 01643 function glossary_print_categories_menu($cm, $glossary, $hook, $category) { 01644 global $CFG, $DB, $OUTPUT; 01645 01646 $context = get_context_instance(CONTEXT_MODULE, $cm->id); 01647 01648 // Prepare format_string/text options 01649 $fmtoptions = array( 01650 'context' => $context); 01651 01652 echo '<table border="0" width="100%">'; 01653 echo '<tr>'; 01654 01655 echo '<td align="center" style="width:20%">'; 01656 if (has_capability('mod/glossary:managecategories', $context)) { 01657 $options['id'] = $cm->id; 01658 $options['mode'] = 'cat'; 01659 $options['hook'] = $hook; 01660 echo $OUTPUT->single_button(new moodle_url("editcategories.php", $options), get_string("editcategories","glossary"), "get"); 01661 } 01662 echo '</td>'; 01663 01664 echo '<td align="center" style="width:60%">'; 01665 echo '<b>'; 01666 01667 $menu = array(); 01668 $menu[GLOSSARY_SHOW_ALL_CATEGORIES] = get_string("allcategories","glossary"); 01669 $menu[GLOSSARY_SHOW_NOT_CATEGORISED] = get_string("notcategorised","glossary"); 01670 01671 $categories = $DB->get_records("glossary_categories", array("glossaryid"=>$glossary->id), "name ASC"); 01672 $selected = ''; 01673 if ( $categories ) { 01674 foreach ($categories as $currentcategory) { 01675 $url = $currentcategory->id; 01676 if ( $category ) { 01677 if ($currentcategory->id == $category->id) { 01678 $selected = $url; 01679 } 01680 } 01681 $menu[$url] = format_string($currentcategory->name, true, $fmtoptions); 01682 } 01683 } 01684 if ( !$selected ) { 01685 $selected = GLOSSARY_SHOW_NOT_CATEGORISED; 01686 } 01687 01688 if ( $category ) { 01689 echo format_string($category->name, true, $fmtoptions); 01690 } else { 01691 if ( $hook == GLOSSARY_SHOW_NOT_CATEGORISED ) { 01692 01693 echo get_string("entrieswithoutcategory","glossary"); 01694 $selected = GLOSSARY_SHOW_NOT_CATEGORISED; 01695 01696 } elseif ( $hook == GLOSSARY_SHOW_ALL_CATEGORIES ) { 01697 01698 echo get_string("allcategories","glossary"); 01699 $selected = GLOSSARY_SHOW_ALL_CATEGORIES; 01700 01701 } 01702 } 01703 echo '</b></td>'; 01704 echo '<td align="center" style="width:20%">'; 01705 01706 $select = new single_select(new moodle_url("/mod/glossary/view.php", array('id'=>$cm->id, 'mode'=>'cat')), 'hook', $menu, $selected, null, "catmenu"); 01707 echo $OUTPUT->render($select); 01708 01709 echo '</td>'; 01710 echo '</tr>'; 01711 01712 echo '</table>'; 01713 } 01714 01722 function glossary_print_all_links($cm, $glossary, $mode, $hook) { 01723 global $CFG; 01724 if ( $glossary->showall) { 01725 $strallentries = get_string("allentries", "glossary"); 01726 if ( $hook == 'ALL' ) { 01727 echo "<b>$strallentries</b>"; 01728 } else { 01729 $strexplainall = strip_tags(get_string("explainall","glossary")); 01730 echo "<a title=\"$strexplainall\" href=\"$CFG->wwwroot/mod/glossary/view.php?id=$cm->id&mode=$mode&hook=ALL\">$strallentries</a>"; 01731 } 01732 } 01733 } 01734 01742 function glossary_print_special_links($cm, $glossary, $mode, $hook) { 01743 global $CFG; 01744 if ( $glossary->showspecial) { 01745 $strspecial = get_string("special", "glossary"); 01746 if ( $hook == 'SPECIAL' ) { 01747 echo "<b>$strspecial</b> | "; 01748 } else { 01749 $strexplainspecial = strip_tags(get_string("explainspecial","glossary")); 01750 echo "<a title=\"$strexplainspecial\" href=\"$CFG->wwwroot/mod/glossary/view.php?id=$cm->id&mode=$mode&hook=SPECIAL\">$strspecial</a> | "; 01751 } 01752 } 01753 } 01754 01763 function glossary_print_alphabet_links($cm, $glossary, $mode, $hook, $sortkey, $sortorder) { 01764 global $CFG; 01765 if ( $glossary->showalphabet) { 01766 $alphabet = explode(",", get_string('alphabet', 'langconfig')); 01767 for ($i = 0; $i < count($alphabet); $i++) { 01768 if ( $hook == $alphabet[$i] and $hook) { 01769 echo "<b>$alphabet[$i]</b>"; 01770 } else { 01771 echo "<a href=\"$CFG->wwwroot/mod/glossary/view.php?id=$cm->id&mode=$mode&hook=".urlencode($alphabet[$i])."&sortkey=$sortkey&sortorder=$sortorder\">$alphabet[$i]</a>"; 01772 } 01773 echo ' | '; 01774 } 01775 } 01776 } 01777 01785 function glossary_print_sorting_links($cm, $mode, $sortkey = '',$sortorder = '') { 01786 global $CFG, $OUTPUT; 01787 01788 $asc = get_string("ascending","glossary"); 01789 $desc = get_string("descending","glossary"); 01790 $bopen = '<b>'; 01791 $bclose = '</b>'; 01792 01793 $neworder = ''; 01794 $currentorder = ''; 01795 $currentsort = ''; 01796 if ( $sortorder ) { 01797 if ( $sortorder == 'asc' ) { 01798 $currentorder = $asc; 01799 $neworder = '&sortorder=desc'; 01800 $newordertitle = get_string('changeto', 'glossary', $desc); 01801 } else { 01802 $currentorder = $desc; 01803 $neworder = '&sortorder=asc'; 01804 $newordertitle = get_string('changeto', 'glossary', $asc); 01805 } 01806 $icon = " <img src=\"".$OUTPUT->pix_url($sortorder, 'glossary')."\" class=\"icon\" alt=\"$newordertitle\" />"; 01807 } else { 01808 if ( $sortkey != 'CREATION' and $sortkey != 'UPDATE' and 01809 $sortkey != 'FIRSTNAME' and $sortkey != 'LASTNAME' ) { 01810 $icon = ""; 01811 $newordertitle = $asc; 01812 } else { 01813 $newordertitle = $desc; 01814 $neworder = '&sortorder=desc'; 01815 $icon = ' <img src="'.$OUTPUT->pix_url('asc', 'glossary').'" class="icon" alt="'.$newordertitle.'" />'; 01816 } 01817 } 01818 $ficon = ''; 01819 $fneworder = ''; 01820 $fbtag = ''; 01821 $fendbtag = ''; 01822 01823 $sicon = ''; 01824 $sneworder = ''; 01825 01826 $sbtag = ''; 01827 $fbtag = ''; 01828 $fendbtag = ''; 01829 $sendbtag = ''; 01830 01831 $sendbtag = ''; 01832 01833 if ( $sortkey == 'CREATION' or $sortkey == 'FIRSTNAME' ) { 01834 $ficon = $icon; 01835 $fneworder = $neworder; 01836 $fordertitle = $newordertitle; 01837 $sordertitle = $asc; 01838 $fbtag = $bopen; 01839 $fendbtag = $bclose; 01840 } elseif ($sortkey == 'UPDATE' or $sortkey == 'LASTNAME') { 01841 $sicon = $icon; 01842 $sneworder = $neworder; 01843 $fordertitle = $asc; 01844 $sordertitle = $newordertitle; 01845 $sbtag = $bopen; 01846 $sendbtag = $bclose; 01847 } else { 01848 $fordertitle = $asc; 01849 $sordertitle = $asc; 01850 } 01851 01852 if ( $sortkey == 'CREATION' or $sortkey == 'UPDATE' ) { 01853 $forder = 'CREATION'; 01854 $sorder = 'UPDATE'; 01855 $fsort = get_string("sortbycreation", "glossary"); 01856 $ssort = get_string("sortbylastupdate", "glossary"); 01857 01858 $currentsort = $fsort; 01859 if ($sortkey == 'UPDATE') { 01860 $currentsort = $ssort; 01861 } 01862 $sort = get_string("sortchronogically", "glossary"); 01863 } elseif ( $sortkey == 'FIRSTNAME' or $sortkey == 'LASTNAME') { 01864 $forder = 'FIRSTNAME'; 01865 $sorder = 'LASTNAME'; 01866 $fsort = get_string("firstname"); 01867 $ssort = get_string("lastname"); 01868 01869 $currentsort = $fsort; 01870 if ($sortkey == 'LASTNAME') { 01871 $currentsort = $ssort; 01872 } 01873 $sort = get_string("sortby", "glossary"); 01874 } 01875 $current = '<span class="accesshide">'.get_string('current', 'glossary', "$currentsort $currentorder").'</span>'; 01876 echo "<br />$current $sort: $sbtag<a title=\"$ssort $sordertitle\" href=\"$CFG->wwwroot/mod/glossary/view.php?id=$cm->id&sortkey=$sorder$sneworder&mode=$mode\">$ssort$sicon</a>$sendbtag | ". 01877 "$fbtag<a title=\"$fsort $fordertitle\" href=\"$CFG->wwwroot/mod/glossary/view.php?id=$cm->id&sortkey=$forder$fneworder&mode=$mode\">$fsort$ficon</a>$fendbtag<br />"; 01878 } 01879 01886 function glossary_sort_entries ( $entry0, $entry1 ) { 01887 01888 if ( moodle_strtolower(ltrim($entry0->concept)) < moodle_strtolower(ltrim($entry1->concept)) ) { 01889 return -1; 01890 } elseif ( moodle_strtolower(ltrim($entry0->concept)) > moodle_strtolower(ltrim($entry1->concept)) ) { 01891 return 1; 01892 } else { 01893 return 0; 01894 } 01895 } 01896 01897 01906 function glossary_print_entry_ratings($course, $entry) { 01907 global $OUTPUT; 01908 if( !empty($entry->rating) ){ 01909 echo $OUTPUT->render($entry->rating); 01910 } 01911 } 01912 01922 function glossary_print_dynaentry($courseid, $entries, $displayformat = -1) { 01923 global $USER,$CFG, $DB; 01924 01925 echo '<div class="boxaligncenter">'; 01926 echo '<table class="glossarypopup" cellspacing="0"><tr>'; 01927 echo '<td>'; 01928 if ( $entries ) { 01929 foreach ( $entries as $entry ) { 01930 if (! $glossary = $DB->get_record('glossary', array('id'=>$entry->glossaryid))) { 01931 print_error('invalidid', 'glossary'); 01932 } 01933 if (! $course = $DB->get_record('course', array('id'=>$glossary->course))) { 01934 print_error('coursemisconf'); 01935 } 01936 if (!$cm = get_coursemodule_from_instance('glossary', $entry->glossaryid, $glossary->course) ) { 01937 print_error('invalidid', 'glossary'); 01938 } 01939 01940 //If displayformat is present, override glossary->displayformat 01941 if ($displayformat < 0) { 01942 $dp = $glossary->displayformat; 01943 } else { 01944 $dp = $displayformat; 01945 } 01946 01947 //Get popupformatname 01948 $format = $DB->get_record('glossary_formats', array('name'=>$dp)); 01949 $displayformat = $format->popupformatname; 01950 01951 //Check displayformat variable and set to default if necessary 01952 if (!$displayformat) { 01953 $displayformat = 'dictionary'; 01954 } 01955 01956 $formatfile = $CFG->dirroot.'/mod/glossary/formats/'.$displayformat.'/'.$displayformat.'_format.php'; 01957 $functionname = 'glossary_show_entry_'.$displayformat; 01958 01959 if (file_exists($formatfile)) { 01960 include_once($formatfile); 01961 if (function_exists($functionname)) { 01962 $functionname($course, $cm, $glossary, $entry,'','','',''); 01963 } 01964 } 01965 } 01966 } 01967 echo '</td>'; 01968 echo '</tr></table></div>'; 01969 } 01970 01979 function glossary_generate_export_csv($entries, $aliases, $categories) { 01980 global $CFG; 01981 $csv = ''; 01982 $delimiter = ''; 01983 require_once($CFG->libdir . '/csvlib.class.php'); 01984 $delimiter = csv_import_reader::get_delimiter('comma'); 01985 $csventries = array(0 => array(get_string('concept', 'glossary'), get_string('definition', 'glossary'))); 01986 $csvaliases = array(0 => array()); 01987 $csvcategories = array(0 => array()); 01988 $aliascount = 0; 01989 $categorycount = 0; 01990 01991 foreach ($entries as $entry) { 01992 $thisaliasesentry = array(); 01993 $thiscategoriesentry = array(); 01994 $thiscsventry = array($entry->concept, nl2br($entry->definition)); 01995 01996 if (array_key_exists($entry->id, $aliases) && is_array($aliases[$entry->id])) { 01997 $thiscount = count($aliases[$entry->id]); 01998 if ($thiscount > $aliascount) { 01999 $aliascount = $thiscount; 02000 } 02001 foreach ($aliases[$entry->id] as $alias) { 02002 $thisaliasesentry[] = trim($alias); 02003 } 02004 } 02005 if (array_key_exists($entry->id, $categories) && is_array($categories[$entry->id])) { 02006 $thiscount = count($categories[$entry->id]); 02007 if ($thiscount > $categorycount) { 02008 $categorycount = $thiscount; 02009 } 02010 foreach ($categories[$entry->id] as $catentry) { 02011 $thiscategoriesentry[] = trim($catentry); 02012 } 02013 } 02014 $csventries[$entry->id] = $thiscsventry; 02015 $csvaliases[$entry->id] = $thisaliasesentry; 02016 $csvcategories[$entry->id] = $thiscategoriesentry; 02017 02018 } 02019 $returnstr = ''; 02020 foreach ($csventries as $id => $row) { 02021 $aliasstr = ''; 02022 $categorystr = ''; 02023 if ($id == 0) { 02024 $aliasstr = get_string('alias', 'glossary'); 02025 $categorystr = get_string('category', 'glossary'); 02026 } 02027 $row = array_merge($row, array_pad($csvaliases[$id], $aliascount, $aliasstr), array_pad($csvcategories[$id], $categorycount, $categorystr)); 02028 $returnstr .= '"' . implode('"' . $delimiter . '"', $row) . '"' . "\n"; 02029 } 02030 return $returnstr; 02031 } 02032 02040 function glossary_generate_export_file($glossary, $ignored = "", $hook = 0) { 02041 global $CFG, $DB; 02042 02043 $co = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 02044 02045 $co .= glossary_start_tag("GLOSSARY",0,true); 02046 $co .= glossary_start_tag("INFO",1,true); 02047 $co .= glossary_full_tag("NAME",2,false,$glossary->name); 02048 $co .= glossary_full_tag("INTRO",2,false,$glossary->intro); 02049 $co .= glossary_full_tag("INTROFORMAT",2,false,$glossary->introformat); 02050 $co .= glossary_full_tag("ALLOWDUPLICATEDENTRIES",2,false,$glossary->allowduplicatedentries); 02051 $co .= glossary_full_tag("DISPLAYFORMAT",2,false,$glossary->displayformat); 02052 $co .= glossary_full_tag("SHOWSPECIAL",2,false,$glossary->showspecial); 02053 $co .= glossary_full_tag("SHOWALPHABET",2,false,$glossary->showalphabet); 02054 $co .= glossary_full_tag("SHOWALL",2,false,$glossary->showall); 02055 $co .= glossary_full_tag("ALLOWCOMMENTS",2,false,$glossary->allowcomments); 02056 $co .= glossary_full_tag("USEDYNALINK",2,false,$glossary->usedynalink); 02057 $co .= glossary_full_tag("DEFAULTAPPROVAL",2,false,$glossary->defaultapproval); 02058 $co .= glossary_full_tag("GLOBALGLOSSARY",2,false,$glossary->globalglossary); 02059 $co .= glossary_full_tag("ENTBYPAGE",2,false,$glossary->entbypage); 02060 02061 if ( $entries = $DB->get_records("glossary_entries", array("glossaryid"=>$glossary->id))) { 02062 $co .= glossary_start_tag("ENTRIES",2,true); 02063 foreach ($entries as $entry) { 02064 $permissiongranted = 1; 02065 if ( $hook ) { 02066 switch ( $hook ) { 02067 case "ALL": 02068 case "SPECIAL": 02069 break; 02070 default: 02071 $permissiongranted = ($entry->concept[ strlen($hook)-1 ] == $hook); 02072 break; 02073 } 02074 } 02075 if ( $hook ) { 02076 switch ( $hook ) { 02077 case GLOSSARY_SHOW_ALL_CATEGORIES: 02078 break; 02079 case GLOSSARY_SHOW_NOT_CATEGORISED: 02080 $permissiongranted = !$DB->record_exists("glossary_entries_categories", array("entryid"=>$entry->id)); 02081 break; 02082 default: 02083 $permissiongranted = $DB->record_exists("glossary_entries_categories", array("entryid"=>$entry->id, "categoryid"=>$hook)); 02084 break; 02085 } 02086 } 02087 if ( $entry->approved and $permissiongranted ) { 02088 $co .= glossary_start_tag("ENTRY",3,true); 02089 $co .= glossary_full_tag("CONCEPT",4,false,trim($entry->concept)); 02090 $co .= glossary_full_tag("DEFINITION",4,false,$entry->definition); 02091 $co .= glossary_full_tag("FORMAT",4,false,$entry->definitionformat); // note: use old name for BC reasons 02092 $co .= glossary_full_tag("USEDYNALINK",4,false,$entry->usedynalink); 02093 $co .= glossary_full_tag("CASESENSITIVE",4,false,$entry->casesensitive); 02094 $co .= glossary_full_tag("FULLMATCH",4,false,$entry->fullmatch); 02095 $co .= glossary_full_tag("TEACHERENTRY",4,false,$entry->teacherentry); 02096 02097 if ( $aliases = $DB->get_records("glossary_alias", array("entryid"=>$entry->id))) { 02098 $co .= glossary_start_tag("ALIASES",4,true); 02099 foreach ($aliases as $alias) { 02100 $co .= glossary_start_tag("ALIAS",5,true); 02101 $co .= glossary_full_tag("NAME",6,false,trim($alias->alias)); 02102 $co .= glossary_end_tag("ALIAS",5,true); 02103 } 02104 $co .= glossary_end_tag("ALIASES",4,true); 02105 } 02106 if ( $catentries = $DB->get_records("glossary_entries_categories", array("entryid"=>$entry->id))) { 02107 $co .= glossary_start_tag("CATEGORIES",4,true); 02108 foreach ($catentries as $catentry) { 02109 $category = $DB->get_record("glossary_categories", array("id"=>$catentry->categoryid)); 02110 02111 $co .= glossary_start_tag("CATEGORY",5,true); 02112 $co .= glossary_full_tag("NAME",6,false,$category->name); 02113 $co .= glossary_full_tag("USEDYNALINK",6,false,$category->usedynalink); 02114 $co .= glossary_end_tag("CATEGORY",5,true); 02115 } 02116 $co .= glossary_end_tag("CATEGORIES",4,true); 02117 } 02118 02119 $co .= glossary_end_tag("ENTRY",3,true); 02120 } 02121 } 02122 $co .= glossary_end_tag("ENTRIES",2,true); 02123 02124 } 02125 02126 02127 $co .= glossary_end_tag("INFO",1,true); 02128 $co .= glossary_end_tag("GLOSSARY",0,true); 02129 02130 return $co; 02131 } 02134 02142 function glossary_read_imported_file($file_content) { 02143 require_once "../../lib/xmlize.php"; 02144 global $CFG; 02145 02146 return xmlize($file_content, 0); 02147 } 02148 02157 function glossary_start_tag($tag,$level=0,$endline=false) { 02158 if ($endline) { 02159 $endchar = "\n"; 02160 } else { 02161 $endchar = ""; 02162 } 02163 return str_repeat(" ",$level*2)."<".strtoupper($tag).">".$endchar; 02164 } 02165 02173 function glossary_end_tag($tag,$level=0,$endline=true) { 02174 if ($endline) { 02175 $endchar = "\n"; 02176 } else { 02177 $endchar = ""; 02178 } 02179 return str_repeat(" ",$level*2)."</".strtoupper($tag).">".$endchar; 02180 } 02181 02192 function glossary_full_tag($tag,$level=0,$endline=true,$content) { 02193 global $CFG; 02194 02195 $st = glossary_start_tag($tag,$level,$endline); 02196 $co = preg_replace("/\r\n|\r/", "\n", s($content)); 02197 $et = glossary_end_tag($tag,0,true); 02198 return $st.$co.$et; 02199 } 02200 02209 function glossary_count_unrated_entries($glossaryid, $userid) { 02210 global $DB; 02211 02212 $sql = "SELECT COUNT('x') as num 02213 FROM {glossary_entries} 02214 WHERE glossaryid = :glossaryid AND 02215 userid <> :userid"; 02216 $params = array('glossaryid' => $glossaryid, 'userid' => $userid); 02217 $entries = $DB->count_records_sql($sql, $params); 02218 02219 if ($entries) { 02220 // We need to get the contextid for the glossaryid we have been given. 02221 $sql = "SELECT ctx.id 02222 FROM {context} ctx 02223 JOIN {course_modules} cm ON cm.id = ctx.instanceid 02224 JOIN {modules} m ON m.id = cm.module 02225 JOIN {glossary} g ON g.id = cm.instance 02226 WHERE ctx.contextlevel = :contextlevel AND 02227 m.name = 'glossary' AND 02228 g.id = :glossaryid"; 02229 $contextid = $DB->get_field_sql($sql, array('glossaryid' => $glossaryid, 'contextlevel' => CONTEXT_MODULE)); 02230 02231 // Now we need to count the ratings that this user has made 02232 $sql = "SELECT COUNT('x') AS num 02233 FROM {glossary_entries} e 02234 JOIN {rating} r ON r.itemid = e.id 02235 WHERE e.glossaryid = :glossaryid AND 02236 r.userid = :userid AND 02237 r.component = 'mod_glossary' AND 02238 r.ratingarea = 'entry' AND 02239 r.contextid = :contextid"; 02240 $params = array('glossaryid' => $glossaryid, 'userid' => $userid, 'contextid' => $contextid); 02241 $rated = $DB->count_records_sql($sql, $params); 02242 if ($rated) { 02243 // The number or enties minus the number or rated entries equals the number of unrated 02244 // entries 02245 if ($entries > $rated) { 02246 return $entries - $rated; 02247 } else { 02248 return 0; // Just in case there was a counting error 02249 } 02250 } else { 02251 return (int)$entries; 02252 } 02253 } else { 02254 return 0; 02255 } 02256 } 02257 02279 function glossary_get_paging_bar($totalcount, $page, $perpage, $baseurl, $maxpageallowed=99999, $maxdisplay=20, $separator=" ", $specialtext="", $specialvalue=-1, $previousandnext = true) { 02280 02281 $code = ''; 02282 02283 $showspecial = false; 02284 $specialselected = false; 02285 02286 //Check if we have to show the special link 02287 if (!empty($specialtext)) { 02288 $showspecial = true; 02289 } 02290 //Check if we are with the special link selected 02291 if ($showspecial && $page == $specialvalue) { 02292 $specialselected = true; 02293 } 02294 02295 //If there are results (more than 1 page) 02296 if ($totalcount > $perpage) { 02297 $code .= "<div style=\"text-align:center\">"; 02298 $code .= "<p>".get_string("page").":"; 02299 02300 $maxpage = (int)(($totalcount-1)/$perpage); 02301 02302 //Lower and upper limit of page 02303 if ($page < 0) { 02304 $page = 0; 02305 } 02306 if ($page > $maxpageallowed) { 02307 $page = $maxpageallowed; 02308 } 02309 if ($page > $maxpage) { 02310 $page = $maxpage; 02311 } 02312 02313 //Calculate the window of pages 02314 $pagefrom = $page - ((int)($maxdisplay / 2)); 02315 if ($pagefrom < 0) { 02316 $pagefrom = 0; 02317 } 02318 $pageto = $pagefrom + $maxdisplay - 1; 02319 if ($pageto > $maxpageallowed) { 02320 $pageto = $maxpageallowed; 02321 } 02322 if ($pageto > $maxpage) { 02323 $pageto = $maxpage; 02324 } 02325 02326 //Some movements can be necessary if don't see enought pages 02327 if ($pageto - $pagefrom < $maxdisplay - 1) { 02328 if ($pageto - $maxdisplay + 1 > 0) { 02329 $pagefrom = $pageto - $maxdisplay + 1; 02330 } 02331 } 02332 02333 //Calculate first and last if necessary 02334 $firstpagecode = ''; 02335 $lastpagecode = ''; 02336 if ($pagefrom > 0) { 02337 $firstpagecode = "$separator<a href=\"{$baseurl}page=0\">1</a>"; 02338 if ($pagefrom > 1) { 02339 $firstpagecode .= "$separator..."; 02340 } 02341 } 02342 if ($pageto < $maxpage) { 02343 if ($pageto < $maxpage -1) { 02344 $lastpagecode = "$separator..."; 02345 } 02346 $lastpagecode .= "$separator<a href=\"{$baseurl}page=$maxpage\">".($maxpage+1)."</a>"; 02347 } 02348 02349 //Previous 02350 if ($page > 0 && $previousandnext) { 02351 $pagenum = $page - 1; 02352 $code .= " (<a href=\"{$baseurl}page=$pagenum\">".get_string("previous")."</a>) "; 02353 } 02354 02355 //Add first 02356 $code .= $firstpagecode; 02357 02358 $pagenum = $pagefrom; 02359 02360 //List of maxdisplay pages 02361 while ($pagenum <= $pageto) { 02362 $pagetoshow = $pagenum +1; 02363 if ($pagenum == $page && !$specialselected) { 02364 $code .= "$separator<b>$pagetoshow</b>"; 02365 } else { 02366 $code .= "$separator<a href=\"{$baseurl}page=$pagenum\">$pagetoshow</a>"; 02367 } 02368 $pagenum++; 02369 } 02370 02371 //Add last 02372 $code .= $lastpagecode; 02373 02374 //Next 02375 if ($page < $maxpage && $page < $maxpageallowed && $previousandnext) { 02376 $pagenum = $page + 1; 02377 $code .= "$separator(<a href=\"{$baseurl}page=$pagenum\">".get_string("next")."</a>)"; 02378 } 02379 02380 //Add special 02381 if ($showspecial) { 02382 $code .= '<br />'; 02383 if ($specialselected) { 02384 $code .= "<b>$specialtext</b>"; 02385 } else { 02386 $code .= "$separator<a href=\"{$baseurl}page=$specialvalue\">$specialtext</a>"; 02387 } 02388 } 02389 02390 //End html 02391 $code .= "</p>"; 02392 $code .= "</div>"; 02393 } 02394 02395 return $code; 02396 } 02400 function glossary_get_view_actions() { 02401 return array('view','view all','view entry'); 02402 } 02406 function glossary_get_post_actions() { 02407 return array('add category','add entry','approve entry','delete category','delete entry','edit category','update entry'); 02408 } 02409 02410 02416 function glossary_reset_course_form_definition(&$mform) { 02417 $mform->addElement('header', 'glossaryheader', get_string('modulenameplural', 'glossary')); 02418 $mform->addElement('checkbox', 'reset_glossary_all', get_string('resetglossariesall','glossary')); 02419 02420 $mform->addElement('select', 'reset_glossary_types', get_string('resetglossaries', 'glossary'), 02421 array('main'=>get_string('mainglossary', 'glossary'), 'secondary'=>get_string('secondaryglossary', 'glossary')), array('multiple' => 'multiple')); 02422 $mform->setAdvanced('reset_glossary_types'); 02423 $mform->disabledIf('reset_glossary_types', 'reset_glossary_all', 'checked'); 02424 02425 $mform->addElement('checkbox', 'reset_glossary_notenrolled', get_string('deletenotenrolled', 'glossary')); 02426 $mform->disabledIf('reset_glossary_notenrolled', 'reset_glossary_all', 'checked'); 02427 02428 $mform->addElement('checkbox', 'reset_glossary_ratings', get_string('deleteallratings')); 02429 $mform->disabledIf('reset_glossary_ratings', 'reset_glossary_all', 'checked'); 02430 02431 $mform->addElement('checkbox', 'reset_glossary_comments', get_string('deleteallcomments')); 02432 $mform->disabledIf('reset_glossary_comments', 'reset_glossary_all', 'checked'); 02433 } 02434 02439 function glossary_reset_course_form_defaults($course) { 02440 return array('reset_glossary_all'=>0, 'reset_glossary_ratings'=>1, 'reset_glossary_comments'=>1, 'reset_glossary_notenrolled'=>0); 02441 } 02442 02450 function glossary_reset_gradebook($courseid, $type='') { 02451 global $DB; 02452 02453 switch ($type) { 02454 case 'main' : $type = "AND g.mainglossary=1"; break; 02455 case 'secondary' : $type = "AND g.mainglossary=0"; break; 02456 default : $type = ""; //all 02457 } 02458 02459 $sql = "SELECT g.*, cm.idnumber as cmidnumber, g.course as courseid 02460 FROM {glossary} g, {course_modules} cm, {modules} m 02461 WHERE m.name='glossary' AND m.id=cm.module AND cm.instance=g.id AND g.course=? $type"; 02462 02463 if ($glossarys = $DB->get_records_sql($sql, array($courseid))) { 02464 foreach ($glossarys as $glossary) { 02465 glossary_grade_item_update($glossary, 'reset'); 02466 } 02467 } 02468 } 02477 function glossary_reset_userdata($data) { 02478 global $CFG, $DB; 02479 require_once($CFG->dirroot.'/rating/lib.php'); 02480 02481 $componentstr = get_string('modulenameplural', 'glossary'); 02482 $status = array(); 02483 02484 $allentriessql = "SELECT e.id 02485 FROM {glossary_entries} e 02486 JOIN {glossary} g ON e.glossaryid = g.id 02487 WHERE g.course = ?"; 02488 02489 $allglossariessql = "SELECT g.id 02490 FROM {glossary} g 02491 WHERE g.course = ?"; 02492 02493 $params = array($data->courseid); 02494 02495 $fs = get_file_storage(); 02496 02497 $rm = new rating_manager(); 02498 $ratingdeloptions = new stdClass; 02499 $ratingdeloptions->component = 'mod_glossary'; 02500 $ratingdeloptions->ratingarea = 'entry'; 02501 02502 // delete entries if requested 02503 if (!empty($data->reset_glossary_all) 02504 or (!empty($data->reset_glossary_types) and in_array('main', $data->reset_glossary_types) and in_array('secondary', $data->reset_glossary_types))) { 02505 02506 $params[] = 'glossary_entry'; 02507 $DB->delete_records_select('comments', "itemid IN ($allentriessql) AND commentarea=?", $params); 02508 $DB->delete_records_select('glossary_alias', "entryid IN ($allentriessql)", $params); 02509 $DB->delete_records_select('glossary_entries', "glossaryid IN ($allglossariessql)", $params); 02510 02511 // now get rid of all attachments 02512 if ($glossaries = $DB->get_records_sql($allglossariessql, $params)) { 02513 foreach ($glossaries as $glossaryid=>$unused) { 02514 if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) { 02515 continue; 02516 } 02517 $context = get_context_instance(CONTEXT_MODULE, $cm->id); 02518 $fs->delete_area_files($context->id, 'mod_glossary', 'attachment'); 02519 02520 //delete ratings 02521 $ratingdeloptions->contextid = $context->id; 02522 $rm->delete_ratings($ratingdeloptions); 02523 } 02524 } 02525 02526 // remove all grades from gradebook 02527 if (empty($data->reset_gradebook_grades)) { 02528 glossary_reset_gradebook($data->courseid); 02529 } 02530 02531 $status[] = array('component'=>$componentstr, 'item'=>get_string('resetglossariesall', 'glossary'), 'error'=>false); 02532 02533 } else if (!empty($data->reset_glossary_types)) { 02534 $mainentriessql = "$allentriessql AND g.mainglossary=1"; 02535 $secondaryentriessql = "$allentriessql AND g.mainglossary=0"; 02536 02537 $mainglossariessql = "$allglossariessql AND g.mainglossary=1"; 02538 $secondaryglossariessql = "$allglossariessql AND g.mainglossary=0"; 02539 02540 if (in_array('main', $data->reset_glossary_types)) { 02541 $params[] = 'glossary_entry'; 02542 $DB->delete_records_select('comments', "itemid IN ($mainentriessql) AND commentarea=?", $params); 02543 $DB->delete_records_select('glossary_entries', "glossaryid IN ($mainglossariessql)", $params); 02544 02545 if ($glossaries = $DB->get_records_sql($mainglossariessql, $params)) { 02546 foreach ($glossaries as $glossaryid=>$unused) { 02547 if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) { 02548 continue; 02549 } 02550 $context = get_context_instance(CONTEXT_MODULE, $cm->id); 02551 $fs->delete_area_files($context->id, 'mod_glossary', 'attachment'); 02552 02553 //delete ratings 02554 $ratingdeloptions->contextid = $context->id; 02555 $rm->delete_ratings($ratingdeloptions); 02556 } 02557 } 02558 02559 // remove all grades from gradebook 02560 if (empty($data->reset_gradebook_grades)) { 02561 glossary_reset_gradebook($data->courseid, 'main'); 02562 } 02563 02564 $status[] = array('component'=>$componentstr, 'item'=>get_string('resetglossaries', 'glossary').': '.get_string('mainglossary', 'glossary'), 'error'=>false); 02565 02566 } else if (in_array('secondary', $data->reset_glossary_types)) { 02567 $params[] = 'glossary_entry'; 02568 $DB->delete_records_select('comments', "itemid IN ($secondaryentriessql) AND commentarea=?", $params); 02569 $DB->delete_records_select('glossary_entries', "glossaryid IN ($secondaryglossariessql)", $params); 02570 // remove exported source flag from entries in main glossary 02571 $DB->execute("UPDATE {glossary_entries} 02572 SET sourceglossaryid=0 02573 WHERE glossaryid IN ($mainglossariessql)", $params); 02574 02575 if ($glossaries = $DB->get_records_sql($secondaryglossariessql, $params)) { 02576 foreach ($glossaries as $glossaryid=>$unused) { 02577 if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) { 02578 continue; 02579 } 02580 $context = get_context_instance(CONTEXT_MODULE, $cm->id); 02581 $fs->delete_area_files($context->id, 'mod_glossary', 'attachment'); 02582 02583 //delete ratings 02584 $ratingdeloptions->contextid = $context->id; 02585 $rm->delete_ratings($ratingdeloptions); 02586 } 02587 } 02588 02589 // remove all grades from gradebook 02590 if (empty($data->reset_gradebook_grades)) { 02591 glossary_reset_gradebook($data->courseid, 'secondary'); 02592 } 02593 02594 $status[] = array('component'=>$componentstr, 'item'=>get_string('resetglossaries', 'glossary').': '.get_string('secondaryglossary', 'glossary'), 'error'=>false); 02595 } 02596 } 02597 02598 // remove entries by users not enrolled into course 02599 if (!empty($data->reset_glossary_notenrolled)) { 02600 $entriessql = "SELECT e.id, e.userid, e.glossaryid, u.id AS userexists, u.deleted AS userdeleted 02601 FROM {glossary_entries} e 02602 JOIN {glossary} g ON e.glossaryid = g.id 02603 LEFT JOIN {user} u ON e.userid = u.id 02604 WHERE g.course = ? AND e.userid > 0"; 02605 02606 $course_context = get_context_instance(CONTEXT_COURSE, $data->courseid); 02607 $notenrolled = array(); 02608 $rs = $DB->get_recordset_sql($entriessql, $params); 02609 if ($rs->valid()) { 02610 foreach ($rs as $entry) { 02611 if (array_key_exists($entry->userid, $notenrolled) or !$entry->userexists or $entry->userdeleted 02612 or !is_enrolled($course_context , $entry->userid)) { 02613 $DB->delete_records('comments', array('commentarea'=>'glossary_entry', 'itemid'=>$entry->id)); 02614 $DB->delete_records('glossary_entries', array('id'=>$entry->id)); 02615 02616 if ($cm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) { 02617 $context = get_context_instance(CONTEXT_MODULE, $cm->id); 02618 $fs->delete_area_files($context->id, 'mod_glossary', 'attachment', $entry->id); 02619 02620 //delete ratings 02621 $ratingdeloptions->contextid = $context->id; 02622 $rm->delete_ratings($ratingdeloptions); 02623 } 02624 } 02625 } 02626 $status[] = array('component'=>$componentstr, 'item'=>get_string('deletenotenrolled', 'glossary'), 'error'=>false); 02627 } 02628 $rs->close(); 02629 } 02630 02631 // remove all ratings 02632 if (!empty($data->reset_glossary_ratings)) { 02633 //remove ratings 02634 if ($glossaries = $DB->get_records_sql($allglossariessql, $params)) { 02635 foreach ($glossaries as $glossaryid=>$unused) { 02636 if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) { 02637 continue; 02638 } 02639 $context = get_context_instance(CONTEXT_MODULE, $cm->id); 02640 02641 //delete ratings 02642 $ratingdeloptions->contextid = $context->id; 02643 $rm->delete_ratings($ratingdeloptions); 02644 } 02645 } 02646 02647 // remove all grades from gradebook 02648 if (empty($data->reset_gradebook_grades)) { 02649 glossary_reset_gradebook($data->courseid); 02650 } 02651 $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallratings'), 'error'=>false); 02652 } 02653 02654 // remove comments 02655 if (!empty($data->reset_glossary_comments)) { 02656 $params[] = 'glossary_entry'; 02657 $DB->delete_records_select('comments', "itemid IN ($allentriessql) AND commentarea= ? ", $params); 02658 $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallcomments'), 'error'=>false); 02659 } 02660 02662 if ($data->timeshift) { 02663 shift_course_mod_dates('glossary', array('assesstimestart', 'assesstimefinish'), $data->timeshift, $data->courseid); 02664 $status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false); 02665 } 02666 02667 return $status; 02668 } 02669 02674 function glossary_get_extra_capabilities() { 02675 return array('moodle/site:accessallgroups', 'moodle/site:viewfullnames', 'moodle/site:trustcontent', 'moodle/rating:view', 'moodle/rating:viewany', 'moodle/rating:viewall', 'moodle/rating:rate', 'moodle/comment:view', 'moodle/comment:post', 'moodle/comment:delete'); 02676 } 02677 02682 function glossary_supports($feature) { 02683 switch($feature) { 02684 case FEATURE_GROUPS: return false; 02685 case FEATURE_GROUPINGS: return false; 02686 case FEATURE_GROUPMEMBERSONLY: return true; 02687 case FEATURE_MOD_INTRO: return true; 02688 case FEATURE_COMPLETION_TRACKS_VIEWS: return true; 02689 case FEATURE_COMPLETION_HAS_RULES: return true; 02690 case FEATURE_GRADE_HAS_GRADE: return true; 02691 case FEATURE_GRADE_OUTCOMES: return true; 02692 case FEATURE_RATE: return true; 02693 case FEATURE_BACKUP_MOODLE2: return true; 02694 case FEATURE_SHOW_DESCRIPTION: return true; 02695 02696 default: return null; 02697 } 02698 } 02699 02713 function glossary_get_completion_state($course,$cm,$userid,$type) { 02714 global $CFG, $DB; 02715 02716 // Get glossary details 02717 if (!($glossary=$DB->get_record('glossary',array('id'=>$cm->instance)))) { 02718 throw new Exception("Can't find glossary {$cm->instance}"); 02719 } 02720 02721 $result=$type; // Default return value 02722 02723 if ($glossary->completionentries) { 02724 $value = $glossary->completionentries <= 02725 $DB->count_records('glossary_entries',array('glossaryid'=>$glossary->id, 'userid'=>$userid, 'approved'=>1)); 02726 if ($type == COMPLETION_AND) { 02727 $result = $result && $value; 02728 } else { 02729 $result = $result || $value; 02730 } 02731 } 02732 02733 return $result; 02734 } 02735 02736 function glossary_extend_navigation($navigation, $course, $module, $cm) { 02737 global $CFG; 02738 $navigation->add(get_string('standardview', 'glossary'), new moodle_url('/mod/glossary/view.php', array('id'=>$cm->id, 'mode'=>'letter'))); 02739 $navigation->add(get_string('categoryview', 'glossary'), new moodle_url('/mod/glossary/view.php', array('id'=>$cm->id, 'mode'=>'cat'))); 02740 $navigation->add(get_string('dateview', 'glossary'), new moodle_url('/mod/glossary/view.php', array('id'=>$cm->id, 'mode'=>'date'))); 02741 $navigation->add(get_string('authorview', 'glossary'), new moodle_url('/mod/glossary/view.php', array('id'=>$cm->id, 'mode'=>'author'))); 02742 } 02743 02750 function glossary_extend_settings_navigation(settings_navigation $settings, navigation_node $glossarynode) { 02751 global $PAGE, $DB, $CFG, $USER; 02752 02753 $mode = optional_param('mode', '', PARAM_ALPHA); 02754 $hook = optional_param('hook', 'ALL', PARAM_CLEAN); 02755 02756 if (has_capability('mod/glossary:import', $PAGE->cm->context)) { 02757 $glossarynode->add(get_string('importentries', 'glossary'), new moodle_url('/mod/glossary/import.php', array('id'=>$PAGE->cm->id))); 02758 } 02759 02760 if (has_capability('mod/glossary:export', $PAGE->cm->context)) { 02761 $glossarynode->add(get_string('exportentries', 'glossary'), new moodle_url('/mod/glossary/export.php', array('id'=>$PAGE->cm->id, 'mode'=>$mode, 'hook'=>$hook))); 02762 } 02763 02764 if (has_capability('mod/glossary:approve', $PAGE->cm->context) && ($hiddenentries = $DB->count_records('glossary_entries', array('glossaryid'=>$PAGE->cm->instance, 'approved'=>0)))) { 02765 $glossarynode->add(get_string('waitingapproval', 'glossary'), new moodle_url('/mod/glossary/view.php', array('id'=>$PAGE->cm->id, 'mode'=>'approval'))); 02766 } 02767 02768 if (has_capability('mod/glossary:write', $PAGE->cm->context)) { 02769 $glossarynode->add(get_string('addentry', 'glossary'), new moodle_url('/mod/glossary/edit.php', array('cmid'=>$PAGE->cm->id))); 02770 } 02771 02772 $glossary = $DB->get_record('glossary', array("id" => $PAGE->cm->instance)); 02773 02774 if (!empty($CFG->enablerssfeeds) && !empty($CFG->glossary_enablerssfeeds) && $glossary->rsstype && $glossary->rssarticles && can_access_course($PAGE->course, $USER)) { 02775 require_once("$CFG->libdir/rsslib.php"); 02776 02777 $string = get_string('rsstype','forum'); 02778 02779 $url = new moodle_url(rss_get_url($PAGE->cm->context->id, $USER->id, 'mod_glossary', $glossary->id)); 02780 $glossarynode->add($string, $url, settings_navigation::TYPE_SETTING, null, null, new pix_icon('i/rss', '')); 02781 } 02782 } 02783 02801 function glossary_comment_permissions($comment_param) { 02802 return array('post'=>true, 'view'=>true); 02803 } 02804 02817 function glossary_comment_validate($comment_param) { 02818 global $DB; 02819 // validate comment area 02820 if ($comment_param->commentarea != 'glossary_entry') { 02821 throw new comment_exception('invalidcommentarea'); 02822 } 02823 if (!$record = $DB->get_record('glossary_entries', array('id'=>$comment_param->itemid))) { 02824 throw new comment_exception('invalidcommentitemid'); 02825 } 02826 if (!$glossary = $DB->get_record('glossary', array('id'=>$record->glossaryid))) { 02827 throw new comment_exception('invalidid', 'data'); 02828 } 02829 if (!$course = $DB->get_record('course', array('id'=>$glossary->course))) { 02830 throw new comment_exception('coursemisconf'); 02831 } 02832 if (!$cm = get_coursemodule_from_instance('glossary', $glossary->id, $course->id)) { 02833 throw new comment_exception('invalidcoursemodule'); 02834 } 02835 $context = get_context_instance(CONTEXT_MODULE, $cm->id); 02836 02837 if ($glossary->defaultapproval and !$record->approved and !has_capability('mod/glossary:approve', $context)) { 02838 throw new comment_exception('notapproved', 'glossary'); 02839 } 02840 // validate context id 02841 if ($context->id != $comment_param->context->id) { 02842 throw new comment_exception('invalidcontext'); 02843 } 02844 // validation for comment deletion 02845 if (!empty($comment_param->commentid)) { 02846 if ($comment = $DB->get_record('comments', array('id'=>$comment_param->commentid))) { 02847 if ($comment->commentarea != 'glossary_entry') { 02848 throw new comment_exception('invalidcommentarea'); 02849 } 02850 if ($comment->contextid != $comment_param->context->id) { 02851 throw new comment_exception('invalidcontext'); 02852 } 02853 if ($comment->itemid != $comment_param->itemid) { 02854 throw new comment_exception('invalidcommentitemid'); 02855 } 02856 } else { 02857 throw new comment_exception('invalidcommentid'); 02858 } 02859 } 02860 return true; 02861 } 02862 02869 function glossary_page_type_list($pagetype, $parentcontext, $currentcontext) { 02870 $module_pagetype = array( 02871 'mod-glossary-*'=>get_string('page-mod-glossary-x', 'glossary'), 02872 'mod-glossary-view'=>get_string('page-mod-glossary-view', 'glossary'), 02873 'mod-glossary-edit'=>get_string('page-mod-glossary-edit', 'glossary')); 02874 return $module_pagetype; 02875 }