| 1 | efrain | 1 | <?php
 | 
        
           |  |  | 2 |   | 
        
           |  |  | 3 | // This file is part of Moodle - http://moodle.org/
 | 
        
           |  |  | 4 | //
 | 
        
           |  |  | 5 | // Moodle is free software: you can redistribute it and/or modify
 | 
        
           |  |  | 6 | // it under the terms of the GNU General Public License as published by
 | 
        
           |  |  | 7 | // the Free Software Foundation, either version 3 of the License, or
 | 
        
           |  |  | 8 | // (at your option) any later version.
 | 
        
           |  |  | 9 | //
 | 
        
           |  |  | 10 | // Moodle is distributed in the hope that it will be useful,
 | 
        
           |  |  | 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
        
           |  |  | 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
        
           |  |  | 13 | // GNU General Public License for more details.
 | 
        
           |  |  | 14 | //
 | 
        
           |  |  | 15 | // You should have received a copy of the GNU General Public License
 | 
        
           |  |  | 16 | // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 | 
        
           |  |  | 17 |   | 
        
           |  |  | 18 | /**
 | 
        
           |  |  | 19 |  * Library of functions and constants for module glossary
 | 
        
           |  |  | 20 |  * (replace glossary with the name of your module and delete this line)
 | 
        
           |  |  | 21 |  *
 | 
        
           |  |  | 22 |  * @package   mod_glossary
 | 
        
           |  |  | 23 |  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
 | 
        
           |  |  | 24 |  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 25 |  */
 | 
        
           |  |  | 26 | require_once($CFG->libdir . '/completionlib.php');
 | 
        
           |  |  | 27 |   | 
        
           |  |  | 28 | define("GLOSSARY_SHOW_ALL_CATEGORIES", 0);
 | 
        
           |  |  | 29 | define("GLOSSARY_SHOW_NOT_CATEGORISED", -1);
 | 
        
           |  |  | 30 |   | 
        
           |  |  | 31 | define("GLOSSARY_NO_VIEW", -1);
 | 
        
           |  |  | 32 | define("GLOSSARY_STANDARD_VIEW", 0);
 | 
        
           |  |  | 33 | define("GLOSSARY_CATEGORY_VIEW", 1);
 | 
        
           |  |  | 34 | define("GLOSSARY_DATE_VIEW", 2);
 | 
        
           |  |  | 35 | define("GLOSSARY_AUTHOR_VIEW", 3);
 | 
        
           |  |  | 36 | define("GLOSSARY_ADDENTRY_VIEW", 4);
 | 
        
           |  |  | 37 | define("GLOSSARY_IMPORT_VIEW", 5);
 | 
        
           |  |  | 38 | define("GLOSSARY_EXPORT_VIEW", 6);
 | 
        
           |  |  | 39 | define("GLOSSARY_APPROVAL_VIEW", 7);
 | 
        
           |  |  | 40 |   | 
        
           |  |  | 41 | // Glossary tabs.
 | 
        
           |  |  | 42 | define('GLOSSARY_STANDARD', 'standard');
 | 
        
           |  |  | 43 | define('GLOSSARY_AUTHOR', 'author');
 | 
        
           |  |  | 44 | define('GLOSSARY_CATEGORY', 'category');
 | 
        
           |  |  | 45 | define('GLOSSARY_DATE', 'date');
 | 
        
           |  |  | 46 |   | 
        
           |  |  | 47 | // Glossary displayformats.
 | 
        
           |  |  | 48 | define('GLOSSARY_CONTINUOUS', 'continuous');
 | 
        
           |  |  | 49 | define('GLOSSARY_DICTIONARY', 'dictionary');
 | 
        
           |  |  | 50 | define('GLOSSARY_FULLWITHOUTAUTHOR', 'fullwithoutauthor');
 | 
        
           |  |  | 51 |   | 
        
           |  |  | 52 | /// STANDARD FUNCTIONS ///////////////////////////////////////////////////////////
 | 
        
           |  |  | 53 | /**
 | 
        
           |  |  | 54 |  * @global object
 | 
        
           |  |  | 55 |  * @param object $glossary
 | 
        
           |  |  | 56 |  * @return int
 | 
        
           |  |  | 57 |  */
 | 
        
           |  |  | 58 | function glossary_add_instance($glossary) {
 | 
        
           |  |  | 59 |     global $DB;
 | 
        
           |  |  | 60 | /// Given an object containing all the necessary data,
 | 
        
           |  |  | 61 | /// (defined by the form in mod_form.php) this function
 | 
        
           |  |  | 62 | /// will create a new instance and return the id number
 | 
        
           |  |  | 63 | /// of the new instance.
 | 
        
           |  |  | 64 |   | 
        
           |  |  | 65 |     if (empty($glossary->ratingtime) or empty($glossary->assessed)) {
 | 
        
           |  |  | 66 |         $glossary->assesstimestart  = 0;
 | 
        
           |  |  | 67 |         $glossary->assesstimefinish = 0;
 | 
        
           |  |  | 68 |     }
 | 
        
           |  |  | 69 |   | 
        
           |  |  | 70 |     if (empty($glossary->globalglossary) ) {
 | 
        
           |  |  | 71 |         $glossary->globalglossary = 0;
 | 
        
           |  |  | 72 |     }
 | 
        
           |  |  | 73 |   | 
        
           |  |  | 74 |     if (!has_capability('mod/glossary:manageentries', context_system::instance())) {
 | 
        
           |  |  | 75 |         $glossary->globalglossary = 0;
 | 
        
           |  |  | 76 |     }
 | 
        
           |  |  | 77 |   | 
        
           |  |  | 78 |     $glossary->timecreated  = time();
 | 
        
           |  |  | 79 |     $glossary->timemodified = $glossary->timecreated;
 | 
        
           |  |  | 80 |   | 
        
           |  |  | 81 |     //Check displayformat is a valid one
 | 
        
           |  |  | 82 |     $formats = get_list_of_plugins('mod/glossary/formats','TEMPLATE');
 | 
        
           |  |  | 83 |     if (!in_array($glossary->displayformat, $formats)) {
 | 
        
           |  |  | 84 |         throw new \moodle_exception('unknowformat', '', '', $glossary->displayformat);
 | 
        
           |  |  | 85 |     }
 | 
        
           |  |  | 86 |   | 
        
           |  |  | 87 |     $returnid = $DB->insert_record("glossary", $glossary);
 | 
        
           |  |  | 88 |     $glossary->id = $returnid;
 | 
        
           |  |  | 89 |     glossary_grade_item_update($glossary);
 | 
        
           |  |  | 90 |   | 
        
           |  |  | 91 |     $completiontimeexpected = !empty($glossary->completionexpected) ? $glossary->completionexpected : null;
 | 
        
           |  |  | 92 |     \core_completion\api::update_completion_date_event($glossary->coursemodule,
 | 
        
           |  |  | 93 |         'glossary', $glossary->id, $completiontimeexpected);
 | 
        
           |  |  | 94 |   | 
        
           |  |  | 95 |     return $returnid;
 | 
        
           |  |  | 96 | }
 | 
        
           |  |  | 97 |   | 
        
           |  |  | 98 | /**
 | 
        
           |  |  | 99 |  * Given an object containing all the necessary data,
 | 
        
           |  |  | 100 |  * (defined by the form in mod_form.php) this function
 | 
        
           |  |  | 101 |  * will update an existing instance with new data.
 | 
        
           |  |  | 102 |  *
 | 
        
           |  |  | 103 |  * @global object
 | 
        
           |  |  | 104 |  * @global object
 | 
        
           |  |  | 105 |  * @param object $glossary
 | 
        
           |  |  | 106 |  * @return bool
 | 
        
           |  |  | 107 |  */
 | 
        
           |  |  | 108 | function glossary_update_instance($glossary) {
 | 
        
           |  |  | 109 |     global $CFG, $DB;
 | 
        
           |  |  | 110 |   | 
        
           |  |  | 111 |     if (empty($glossary->globalglossary)) {
 | 
        
           |  |  | 112 |         $glossary->globalglossary = 0;
 | 
        
           |  |  | 113 |     }
 | 
        
           |  |  | 114 |   | 
        
           |  |  | 115 |     if (!has_capability('mod/glossary:manageentries', context_system::instance())) {
 | 
        
           |  |  | 116 |         // keep previous
 | 
        
           |  |  | 117 |         unset($glossary->globalglossary);
 | 
        
           |  |  | 118 |     }
 | 
        
           |  |  | 119 |   | 
        
           |  |  | 120 |     $glossary->timemodified = time();
 | 
        
           |  |  | 121 |     $glossary->id           = $glossary->instance;
 | 
        
           |  |  | 122 |   | 
        
           |  |  | 123 |     if (empty($glossary->ratingtime) or empty($glossary->assessed)) {
 | 
        
           |  |  | 124 |         $glossary->assesstimestart  = 0;
 | 
        
           |  |  | 125 |         $glossary->assesstimefinish = 0;
 | 
        
           |  |  | 126 |     }
 | 
        
           |  |  | 127 |   | 
        
           |  |  | 128 |     //Check displayformat is a valid one
 | 
        
           |  |  | 129 |     $formats = get_list_of_plugins('mod/glossary/formats','TEMPLATE');
 | 
        
           |  |  | 130 |     if (!in_array($glossary->displayformat, $formats)) {
 | 
        
           |  |  | 131 |         throw new \moodle_exception('unknowformat', '', '', $glossary->displayformat);
 | 
        
           |  |  | 132 |     }
 | 
        
           |  |  | 133 |   | 
        
           |  |  | 134 |     $DB->update_record("glossary", $glossary);
 | 
        
           |  |  | 135 |     if ($glossary->defaultapproval) {
 | 
        
           |  |  | 136 |         $DB->execute("UPDATE {glossary_entries} SET approved = 1 where approved <> 1 and glossaryid = ?", array($glossary->id));
 | 
        
           |  |  | 137 |     }
 | 
        
           |  |  | 138 |     glossary_grade_item_update($glossary);
 | 
        
           |  |  | 139 |   | 
        
           |  |  | 140 |     $completiontimeexpected = !empty($glossary->completionexpected) ? $glossary->completionexpected : null;
 | 
        
           |  |  | 141 |     \core_completion\api::update_completion_date_event($glossary->coursemodule,
 | 
        
           |  |  | 142 |         'glossary', $glossary->id, $completiontimeexpected);
 | 
        
           |  |  | 143 |   | 
        
           |  |  | 144 |     return true;
 | 
        
           |  |  | 145 | }
 | 
        
           |  |  | 146 |   | 
        
           |  |  | 147 | /**
 | 
        
           |  |  | 148 |  * Given an ID of an instance of this module,
 | 
        
           |  |  | 149 |  * this function will permanently delete the instance
 | 
        
           |  |  | 150 |  * and any data that depends on it.
 | 
        
           |  |  | 151 |  *
 | 
        
           |  |  | 152 |  * @global object
 | 
        
           |  |  | 153 |  * @param int $id glossary id
 | 
        
           |  |  | 154 |  * @return bool success
 | 
        
           |  |  | 155 |  */
 | 
        
           |  |  | 156 | function glossary_delete_instance($id) {
 | 
        
           |  |  | 157 |     global $DB, $CFG;
 | 
        
           |  |  | 158 |   | 
        
           |  |  | 159 |     if (!$glossary = $DB->get_record('glossary', array('id'=>$id))) {
 | 
        
           |  |  | 160 |         return false;
 | 
        
           |  |  | 161 |     }
 | 
        
           |  |  | 162 |   | 
        
           |  |  | 163 |     if (!$cm = get_coursemodule_from_instance('glossary', $id)) {
 | 
        
           |  |  | 164 |         return false;
 | 
        
           |  |  | 165 |     }
 | 
        
           |  |  | 166 |   | 
        
           |  |  | 167 |     if (!$context = context_module::instance($cm->id, IGNORE_MISSING)) {
 | 
        
           |  |  | 168 |         return false;
 | 
        
           |  |  | 169 |     }
 | 
        
           |  |  | 170 |   | 
        
           |  |  | 171 |     $fs = get_file_storage();
 | 
        
           |  |  | 172 |   | 
        
           |  |  | 173 |     if ($glossary->mainglossary) {
 | 
        
           |  |  | 174 |         // unexport entries
 | 
        
           |  |  | 175 |         $sql = "SELECT ge.id, ge.sourceglossaryid, cm.id AS sourcecmid
 | 
        
           |  |  | 176 |                   FROM {glossary_entries} ge
 | 
        
           |  |  | 177 |                   JOIN {modules} m ON m.name = 'glossary'
 | 
        
           |  |  | 178 |                   JOIN {course_modules} cm ON (cm.module = m.id AND cm.instance = ge.sourceglossaryid)
 | 
        
           |  |  | 179 |                  WHERE ge.glossaryid = ? AND ge.sourceglossaryid > 0";
 | 
        
           |  |  | 180 |   | 
        
           |  |  | 181 |         if ($exported = $DB->get_records_sql($sql, array($id))) {
 | 
        
           |  |  | 182 |             foreach ($exported as $entry) {
 | 
        
           |  |  | 183 |                 $entry->glossaryid = $entry->sourceglossaryid;
 | 
        
           |  |  | 184 |                 $entry->sourceglossaryid = 0;
 | 
        
           |  |  | 185 |                 $newcontext = context_module::instance($entry->sourcecmid);
 | 
        
           |  |  | 186 |                 if ($oldfiles = $fs->get_area_files($context->id, 'mod_glossary', 'attachment', $entry->id)) {
 | 
        
           |  |  | 187 |                     foreach ($oldfiles as $oldfile) {
 | 
        
           |  |  | 188 |                         $file_record = new stdClass();
 | 
        
           |  |  | 189 |                         $file_record->contextid = $newcontext->id;
 | 
        
           |  |  | 190 |                         $fs->create_file_from_storedfile($file_record, $oldfile);
 | 
        
           |  |  | 191 |                     }
 | 
        
           |  |  | 192 |                     $fs->delete_area_files($context->id, 'mod_glossary', 'attachment', $entry->id);
 | 
        
           |  |  | 193 |                     $entry->attachment = '1';
 | 
        
           |  |  | 194 |                 } else {
 | 
        
           |  |  | 195 |                     $entry->attachment = '0';
 | 
        
           |  |  | 196 |                 }
 | 
        
           |  |  | 197 |                 $DB->update_record('glossary_entries', $entry);
 | 
        
           |  |  | 198 |             }
 | 
        
           |  |  | 199 |         }
 | 
        
           |  |  | 200 |     } else {
 | 
        
           |  |  | 201 |         // move exported entries to main glossary
 | 
        
           |  |  | 202 |         $sql = "UPDATE {glossary_entries}
 | 
        
           |  |  | 203 |                    SET sourceglossaryid = 0
 | 
        
           |  |  | 204 |                  WHERE sourceglossaryid = ?";
 | 
        
           |  |  | 205 |         $DB->execute($sql, array($id));
 | 
        
           |  |  | 206 |     }
 | 
        
           |  |  | 207 |   | 
        
           |  |  | 208 |     // Delete any dependent records
 | 
        
           |  |  | 209 |     $entry_select = "SELECT id FROM {glossary_entries} WHERE glossaryid = ?";
 | 
        
           |  |  | 210 |     $DB->delete_records_select('comments', "contextid=? AND commentarea=? AND itemid IN ($entry_select)", array($id, 'glossary_entry', $context->id));
 | 
        
           |  |  | 211 |     $DB->delete_records_select('glossary_alias',    "entryid IN ($entry_select)", array($id));
 | 
        
           |  |  | 212 |   | 
        
           |  |  | 213 |     $category_select = "SELECT id FROM {glossary_categories} WHERE glossaryid = ?";
 | 
        
           |  |  | 214 |     $DB->delete_records_select('glossary_entries_categories', "categoryid IN ($category_select)", array($id));
 | 
        
           |  |  | 215 |     $DB->delete_records('glossary_categories', array('glossaryid'=>$id));
 | 
        
           |  |  | 216 |     $DB->delete_records('glossary_entries', array('glossaryid'=>$id));
 | 
        
           |  |  | 217 |   | 
        
           |  |  | 218 |     // delete all files
 | 
        
           |  |  | 219 |     $fs->delete_area_files($context->id);
 | 
        
           |  |  | 220 |   | 
        
           |  |  | 221 |     glossary_grade_item_delete($glossary);
 | 
        
           |  |  | 222 |   | 
        
           |  |  | 223 |     \core_completion\api::update_completion_date_event($cm->id, 'glossary', $glossary->id, null);
 | 
        
           |  |  | 224 |   | 
        
           |  |  | 225 |     $DB->delete_records('glossary', array('id'=>$id));
 | 
        
           |  |  | 226 |   | 
        
           |  |  | 227 |     // Reset caches.
 | 
        
           |  |  | 228 |     \mod_glossary\local\concept_cache::reset_glossary($glossary);
 | 
        
           |  |  | 229 |   | 
        
           |  |  | 230 |     return true;
 | 
        
           |  |  | 231 | }
 | 
        
           |  |  | 232 |   | 
        
           |  |  | 233 | /**
 | 
        
           |  |  | 234 |  * Return a small object with summary information about what a
 | 
        
           |  |  | 235 |  * user has done with a given particular instance of this module
 | 
        
           |  |  | 236 |  * Used for user activity reports.
 | 
        
           |  |  | 237 |  * $return->time = the time they did it
 | 
        
           |  |  | 238 |  * $return->info = a short text description
 | 
        
           |  |  | 239 |  *
 | 
        
           |  |  | 240 |  * @param object $course
 | 
        
           |  |  | 241 |  * @param object $user
 | 
        
           |  |  | 242 |  * @param object $mod
 | 
        
           |  |  | 243 |  * @param object $glossary
 | 
        
           |  |  | 244 |  * @return object|null
 | 
        
           |  |  | 245 |  */
 | 
        
           |  |  | 246 | function glossary_user_outline($course, $user, $mod, $glossary) {
 | 
        
           |  |  | 247 |     global $CFG;
 | 
        
           |  |  | 248 |   | 
        
           |  |  | 249 |     require_once("$CFG->libdir/gradelib.php");
 | 
        
           |  |  | 250 |     $grades = grade_get_grades($course->id, 'mod', 'glossary', $glossary->id, $user->id);
 | 
        
           |  |  | 251 |     if (empty($grades->items[0]->grades)) {
 | 
        
           |  |  | 252 |         $grade = false;
 | 
        
           |  |  | 253 |     } else {
 | 
        
           |  |  | 254 |         $grade = reset($grades->items[0]->grades);
 | 
        
           |  |  | 255 |     }
 | 
        
           |  |  | 256 |   | 
        
           |  |  | 257 |     if ($entries = glossary_get_user_entries($glossary->id, $user->id)) {
 | 
        
           |  |  | 258 |         $result = new stdClass();
 | 
        
           |  |  | 259 |         $result->info = count($entries) . ' ' . get_string("entries", "glossary");
 | 
        
           |  |  | 260 |   | 
        
           |  |  | 261 |         $lastentry = array_pop($entries);
 | 
        
           |  |  | 262 |         $result->time = $lastentry->timemodified;
 | 
        
           |  |  | 263 |   | 
        
           |  |  | 264 |         if ($grade) {
 | 
        
           |  |  | 265 |             if (!$grade->hidden || has_capability('moodle/grade:viewhidden', context_course::instance($course->id))) {
 | 
        
           |  |  | 266 |                 $result->info .= ', ' . get_string('gradenoun') . ': ' . $grade->str_long_grade;
 | 
        
           |  |  | 267 |             } else {
 | 
        
           |  |  | 268 |                 $result->info = get_string('gradenoun') . ': ' . get_string('hidden', 'grades');
 | 
        
           |  |  | 269 |             }
 | 
        
           |  |  | 270 |         }
 | 
        
           |  |  | 271 |         return $result;
 | 
        
           |  |  | 272 |     } else if ($grade) {
 | 
        
           |  |  | 273 |         $result = (object) [
 | 
        
           |  |  | 274 |             'time' => grade_get_date_for_user_grade($grade, $user),
 | 
        
           |  |  | 275 |         ];
 | 
        
           |  |  | 276 |         if (!$grade->hidden || has_capability('moodle/grade:viewhidden', context_course::instance($course->id))) {
 | 
        
           |  |  | 277 |             $result->info = get_string('gradenoun') . ': ' . $grade->str_long_grade;
 | 
        
           |  |  | 278 |         } else {
 | 
        
           |  |  | 279 |             $result->info = get_string('gradenoun') . ': ' . get_string('hidden', 'grades');
 | 
        
           |  |  | 280 |         }
 | 
        
           |  |  | 281 |   | 
        
           |  |  | 282 |         return $result;
 | 
        
           |  |  | 283 |     }
 | 
        
           |  |  | 284 |     return NULL;
 | 
        
           |  |  | 285 | }
 | 
        
           |  |  | 286 |   | 
        
           |  |  | 287 | /**
 | 
        
           |  |  | 288 |  * @global object
 | 
        
           |  |  | 289 |  * @param int $glossaryid
 | 
        
           |  |  | 290 |  * @param int $userid
 | 
        
           |  |  | 291 |  * @return array
 | 
        
           |  |  | 292 |  */
 | 
        
           |  |  | 293 | function glossary_get_user_entries($glossaryid, $userid) {
 | 
        
           |  |  | 294 | /// Get all the entries for a user in a glossary
 | 
        
           |  |  | 295 |     global $DB;
 | 
        
           |  |  | 296 |   | 
        
           |  |  | 297 |     return $DB->get_records_sql("SELECT e.*, u.firstname, u.lastname, u.email, u.picture
 | 
        
           |  |  | 298 |                                    FROM {glossary} g, {glossary_entries} e, {user} u
 | 
        
           |  |  | 299 |                              WHERE g.id = ?
 | 
        
           |  |  | 300 |                                AND e.glossaryid = g.id
 | 
        
           |  |  | 301 |                                AND e.userid = ?
 | 
        
           |  |  | 302 |                                AND e.userid = u.id
 | 
        
           |  |  | 303 |                           ORDER BY e.timemodified ASC", array($glossaryid, $userid));
 | 
        
           |  |  | 304 | }
 | 
        
           |  |  | 305 |   | 
        
           |  |  | 306 | /**
 | 
        
           |  |  | 307 |  * Print a detailed representation of what a  user has done with
 | 
        
           |  |  | 308 |  * a given particular instance of this module, for user activity reports.
 | 
        
           |  |  | 309 |  *
 | 
        
           |  |  | 310 |  * @global object
 | 
        
           |  |  | 311 |  * @param object $course
 | 
        
           |  |  | 312 |  * @param object $user
 | 
        
           |  |  | 313 |  * @param object $mod
 | 
        
           |  |  | 314 |  * @param object $glossary
 | 
        
           |  |  | 315 |  */
 | 
        
           |  |  | 316 | function glossary_user_complete($course, $user, $mod, $glossary) {
 | 
        
           |  |  | 317 |     global $CFG, $OUTPUT;
 | 
        
           |  |  | 318 |     require_once("$CFG->libdir/gradelib.php");
 | 
        
           |  |  | 319 |   | 
        
           |  |  | 320 |     $grades = grade_get_grades($course->id, 'mod', 'glossary', $glossary->id, $user->id);
 | 
        
           |  |  | 321 |     if (!empty($grades->items[0]->grades)) {
 | 
        
           |  |  | 322 |         $grade = reset($grades->items[0]->grades);
 | 
        
           |  |  | 323 |         if (!$grade->hidden || has_capability('moodle/grade:viewhidden', context_course::instance($course->id))) {
 | 
        
           |  |  | 324 |             echo $OUTPUT->container(get_string('gradenoun') . ': ' . $grade->str_long_grade);
 | 
        
           |  |  | 325 |             if ($grade->str_feedback) {
 | 
        
           |  |  | 326 |                 echo $OUTPUT->container(get_string('feedback').': '.$grade->str_feedback);
 | 
        
           |  |  | 327 |             }
 | 
        
           |  |  | 328 |         } else {
 | 
        
           |  |  | 329 |             echo $OUTPUT->container(get_string('gradenoun') . ': ' . get_string('hidden', 'grades'));
 | 
        
           |  |  | 330 |         }
 | 
        
           |  |  | 331 |     }
 | 
        
           |  |  | 332 |   | 
        
           |  |  | 333 |     if ($entries = glossary_get_user_entries($glossary->id, $user->id)) {
 | 
        
           |  |  | 334 |         echo '<table width="95%" border="0"><tr><td>';
 | 
        
           |  |  | 335 |         foreach ($entries as $entry) {
 | 
        
           |  |  | 336 |             $cm = get_coursemodule_from_instance("glossary", $glossary->id, $course->id);
 | 
        
           |  |  | 337 |             glossary_print_entry($course, $cm, $glossary, $entry,"","",0);
 | 
        
           |  |  | 338 |             echo '<p>';
 | 
        
           |  |  | 339 |         }
 | 
        
           |  |  | 340 |         echo '</td></tr></table>';
 | 
        
           |  |  | 341 |     }
 | 
        
           |  |  | 342 | }
 | 
        
           |  |  | 343 |   | 
        
           |  |  | 344 | /**
 | 
        
           |  |  | 345 |  * Returns all glossary entries since a given time for specified glossary
 | 
        
           |  |  | 346 |  *
 | 
        
           |  |  | 347 |  * @param array $activities sequentially indexed array of objects
 | 
        
           |  |  | 348 |  * @param int   $index
 | 
        
           |  |  | 349 |  * @param int   $timestart
 | 
        
           |  |  | 350 |  * @param int   $courseid
 | 
        
           |  |  | 351 |  * @param int   $cmid
 | 
        
           |  |  | 352 |  * @param int   $userid defaults to 0
 | 
        
           |  |  | 353 |  * @param int   $groupid defaults to 0
 | 
        
           |  |  | 354 |  * @return void adds items into $activities and increases $index
 | 
        
           |  |  | 355 |  */
 | 
        
           |  |  | 356 | function glossary_get_recent_mod_activity(&$activities, &$index, $timestart, $courseid, $cmid, $userid = 0, $groupid = 0) {
 | 
        
           |  |  | 357 |     global $COURSE, $USER, $DB;
 | 
        
           |  |  | 358 |   | 
        
           |  |  | 359 |     if ($COURSE->id == $courseid) {
 | 
        
           |  |  | 360 |         $course = $COURSE;
 | 
        
           |  |  | 361 |     } else {
 | 
        
           |  |  | 362 |         $course = $DB->get_record('course', array('id' => $courseid));
 | 
        
           |  |  | 363 |     }
 | 
        
           |  |  | 364 |   | 
        
           |  |  | 365 |     $modinfo = get_fast_modinfo($course);
 | 
        
           |  |  | 366 |     $cm = $modinfo->cms[$cmid];
 | 
        
           |  |  | 367 |     $context = context_module::instance($cm->id);
 | 
        
           |  |  | 368 |   | 
        
           |  |  | 369 |     if (!$cm->uservisible) {
 | 
        
           |  |  | 370 |         return;
 | 
        
           |  |  | 371 |     }
 | 
        
           |  |  | 372 |   | 
        
           |  |  | 373 |     $viewfullnames = has_capability('moodle/site:viewfullnames', $context);
 | 
        
           |  |  | 374 |     // Groups are not yet supported for glossary. See MDL-10728 .
 | 
        
           |  |  | 375 |     /*
 | 
        
           |  |  | 376 |     $accessallgroups = has_capability('moodle/site:accessallgroups', $context);
 | 
        
           |  |  | 377 |     $groupmode = groups_get_activity_groupmode($cm, $course);
 | 
        
           |  |  | 378 |      */
 | 
        
           |  |  | 379 |   | 
        
           |  |  | 380 |     $params['timestart'] = $timestart;
 | 
        
           |  |  | 381 |   | 
        
           |  |  | 382 |     if ($userid) {
 | 
        
           |  |  | 383 |         $userselect = "AND u.id = :userid";
 | 
        
           |  |  | 384 |         $params['userid'] = $userid;
 | 
        
           |  |  | 385 |     } else {
 | 
        
           |  |  | 386 |         $userselect = '';
 | 
        
           |  |  | 387 |     }
 | 
        
           |  |  | 388 |   | 
        
           |  |  | 389 |     if ($groupid) {
 | 
        
           |  |  | 390 |         $groupselect = 'AND gm.groupid = :groupid';
 | 
        
           |  |  | 391 |         $groupjoin   = 'JOIN {groups_members} gm ON  gm.userid=u.id';
 | 
        
           |  |  | 392 |         $params['groupid'] = $groupid;
 | 
        
           |  |  | 393 |     } else {
 | 
        
           |  |  | 394 |         $groupselect = '';
 | 
        
           |  |  | 395 |         $groupjoin   = '';
 | 
        
           |  |  | 396 |     }
 | 
        
           |  |  | 397 |   | 
        
           |  |  | 398 |     $approvedselect = "";
 | 
        
           |  |  | 399 |     if (!has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 400 |         $approvedselect = " AND ge.approved = 1 ";
 | 
        
           |  |  | 401 |     }
 | 
        
           |  |  | 402 |   | 
        
           |  |  | 403 |     $params['timestart'] = $timestart;
 | 
        
           |  |  | 404 |     $params['glossaryid'] = $cm->instance;
 | 
        
           |  |  | 405 |   | 
        
           |  |  | 406 |     $userfieldsapi = \core_user\fields::for_userpic();
 | 
        
           |  |  | 407 |     $ufields = $userfieldsapi->get_sql('u', false, '', 'userid', false)->selects;
 | 
        
           |  |  | 408 |     $entries = $DB->get_records_sql("
 | 
        
           |  |  | 409 |               SELECT ge.id AS entryid, ge.glossaryid, ge.concept, ge.definition, ge.approved,
 | 
        
           |  |  | 410 |                      ge.timemodified, $ufields
 | 
        
           |  |  | 411 |                 FROM {glossary_entries} ge
 | 
        
           |  |  | 412 |                 JOIN {user} u ON u.id = ge.userid
 | 
        
           |  |  | 413 |                      $groupjoin
 | 
        
           |  |  | 414 |                WHERE ge.timemodified > :timestart
 | 
        
           |  |  | 415 |                  AND ge.glossaryid = :glossaryid
 | 
        
           |  |  | 416 |                      $approvedselect
 | 
        
           |  |  | 417 |                      $userselect
 | 
        
           |  |  | 418 |                      $groupselect
 | 
        
           |  |  | 419 |             ORDER BY ge.timemodified ASC", $params);
 | 
        
           |  |  | 420 |   | 
        
           |  |  | 421 |     if (!$entries) {
 | 
        
           |  |  | 422 |         return;
 | 
        
           |  |  | 423 |     }
 | 
        
           |  |  | 424 |   | 
        
           |  |  | 425 |     foreach ($entries as $entry) {
 | 
        
           |  |  | 426 |         // Groups are not yet supported for glossary. See MDL-10728 .
 | 
        
           |  |  | 427 |         /*
 | 
        
           |  |  | 428 |         $usersgroups = null;
 | 
        
           |  |  | 429 |         if ($entry->userid != $USER->id) {
 | 
        
           |  |  | 430 |             if ($groupmode == SEPARATEGROUPS and !$accessallgroups) {
 | 
        
           |  |  | 431 |                 if (is_null($usersgroups)) {
 | 
        
           |  |  | 432 |                     $usersgroups = groups_get_all_groups($course->id, $entry->userid, $cm->groupingid);
 | 
        
           |  |  | 433 |                     if (is_array($usersgroups)) {
 | 
        
           |  |  | 434 |                         $usersgroups = array_keys($usersgroups);
 | 
        
           |  |  | 435 |                     } else {
 | 
        
           |  |  | 436 |                         $usersgroups = array();
 | 
        
           |  |  | 437 |                     }
 | 
        
           |  |  | 438 |                 }
 | 
        
           |  |  | 439 |                 if (!array_intersect($usersgroups, $modinfo->get_groups($cm->groupingid))) {
 | 
        
           |  |  | 440 |                     continue;
 | 
        
           |  |  | 441 |                 }
 | 
        
           |  |  | 442 |             }
 | 
        
           |  |  | 443 |         }
 | 
        
           |  |  | 444 |          */
 | 
        
           |  |  | 445 |   | 
        
           |  |  | 446 |         $tmpactivity                       = new stdClass();
 | 
        
           |  |  | 447 |         $tmpactivity->user                 = user_picture::unalias($entry, null, 'userid');
 | 
        
           |  |  | 448 |         $tmpactivity->user->fullname       = fullname($tmpactivity->user, $viewfullnames);
 | 
        
           |  |  | 449 |         $tmpactivity->type                 = 'glossary';
 | 
        
           |  |  | 450 |         $tmpactivity->cmid                 = $cm->id;
 | 
        
           |  |  | 451 |         $tmpactivity->glossaryid           = $entry->glossaryid;
 | 
        
           |  |  | 452 |         $tmpactivity->name                 = format_string($cm->name, true);
 | 
        
           |  |  | 453 |         $tmpactivity->sectionnum           = $cm->sectionnum;
 | 
        
           |  |  | 454 |         $tmpactivity->timestamp            = $entry->timemodified;
 | 
        
           |  |  | 455 |         $tmpactivity->content              = new stdClass();
 | 
        
           |  |  | 456 |         $tmpactivity->content->entryid     = $entry->entryid;
 | 
        
           |  |  | 457 |         $tmpactivity->content->concept     = $entry->concept;
 | 
        
           |  |  | 458 |         $tmpactivity->content->definition  = $entry->definition;
 | 
        
           |  |  | 459 |         $tmpactivity->content->approved    = $entry->approved;
 | 
        
           |  |  | 460 |   | 
        
           |  |  | 461 |         $activities[$index++] = $tmpactivity;
 | 
        
           |  |  | 462 |     }
 | 
        
           |  |  | 463 |   | 
        
           |  |  | 464 |     return true;
 | 
        
           |  |  | 465 | }
 | 
        
           |  |  | 466 |   | 
        
           |  |  | 467 | /**
 | 
        
           |  |  | 468 |  * Outputs the glossary entry indicated by $activity
 | 
        
           |  |  | 469 |  *
 | 
        
           |  |  | 470 |  * @param object $activity      the activity object the glossary resides in
 | 
        
           |  |  | 471 |  * @param int    $courseid      the id of the course the glossary resides in
 | 
        
           |  |  | 472 |  * @param bool   $detail        not used, but required for compatibilty with other modules
 | 
        
           |  |  | 473 |  * @param int    $modnames      not used, but required for compatibilty with other modules
 | 
        
           |  |  | 474 |  * @param bool   $viewfullnames not used, but required for compatibilty with other modules
 | 
        
           |  |  | 475 |  * @return void
 | 
        
           |  |  | 476 |  */
 | 
        
           |  |  | 477 | function glossary_print_recent_mod_activity($activity, $courseid, $detail, $modnames, $viewfullnames) {
 | 
        
           |  |  | 478 |     global $OUTPUT;
 | 
        
           |  |  | 479 |   | 
        
           |  |  | 480 |     echo html_writer::start_tag('div', array('class'=>'glossary-activity clearfix'));
 | 
        
           |  |  | 481 |     if (!empty($activity->user)) {
 | 
        
           |  |  | 482 |         echo html_writer::tag('div', $OUTPUT->user_picture($activity->user, array('courseid'=>$courseid)),
 | 
        
           |  |  | 483 |             array('class' => 'glossary-activity-picture'));
 | 
        
           |  |  | 484 |     }
 | 
        
           |  |  | 485 |   | 
        
           |  |  | 486 |     echo html_writer::start_tag('div', array('class'=>'glossary-activity-content'));
 | 
        
           |  |  | 487 |     echo html_writer::start_tag('div', array('class'=>'glossary-activity-entry'));
 | 
        
           |  |  | 488 |   | 
        
           |  |  | 489 |     if (isset($activity->content->approved) && !$activity->content->approved) {
 | 
        
           |  |  | 490 |         $urlparams = array('g' => $activity->glossaryid, 'mode' => 'approval', 'hook' => $activity->content->concept);
 | 
        
           |  |  | 491 |         $class = array('class' => 'dimmed_text');
 | 
        
           |  |  | 492 |     } else {
 | 
        
           |  |  | 493 |         $urlparams = array('g' => $activity->glossaryid, 'mode' => 'entry', 'hook' => $activity->content->entryid);
 | 
        
           |  |  | 494 |         $class = array();
 | 
        
           |  |  | 495 |     }
 | 
        
           |  |  | 496 |     echo html_writer::link(new moodle_url('/mod/glossary/view.php', $urlparams),
 | 
        
           |  |  | 497 |             strip_tags($activity->content->concept), $class);
 | 
        
           |  |  | 498 |     echo html_writer::end_tag('div');
 | 
        
           |  |  | 499 |   | 
        
           |  |  | 500 |     $url = new moodle_url('/user/view.php', array('course'=>$courseid, 'id'=>$activity->user->id));
 | 
        
           |  |  | 501 |     $name = $activity->user->fullname;
 | 
        
           |  |  | 502 |     $link = html_writer::link($url, $name, $class);
 | 
        
           |  |  | 503 |   | 
        
           |  |  | 504 |     echo html_writer::start_tag('div', array('class'=>'user'));
 | 
        
           |  |  | 505 |     echo $link .' - '. userdate($activity->timestamp);
 | 
        
           |  |  | 506 |     echo html_writer::end_tag('div');
 | 
        
           |  |  | 507 |   | 
        
           |  |  | 508 |     echo html_writer::end_tag('div');
 | 
        
           |  |  | 509 |   | 
        
           |  |  | 510 |     echo html_writer::end_tag('div');
 | 
        
           |  |  | 511 |     return;
 | 
        
           |  |  | 512 | }
 | 
        
           |  |  | 513 | /**
 | 
        
           |  |  | 514 |  * Given a course and a time, this module should find recent activity
 | 
        
           |  |  | 515 |  * that has occurred in glossary activities and print it out.
 | 
        
           |  |  | 516 |  * Return true if there was output, or false is there was none.
 | 
        
           |  |  | 517 |  *
 | 
        
           |  |  | 518 |  * @global object
 | 
        
           |  |  | 519 |  * @global object
 | 
        
           |  |  | 520 |  * @global object
 | 
        
           |  |  | 521 |  * @param object $course
 | 
        
           |  |  | 522 |  * @param object $viewfullnames
 | 
        
           |  |  | 523 |  * @param int $timestart
 | 
        
           |  |  | 524 |  * @return bool
 | 
        
           |  |  | 525 |  */
 | 
        
           |  |  | 526 | function glossary_print_recent_activity($course, $viewfullnames, $timestart) {
 | 
        
           |  |  | 527 |     global $CFG, $USER, $DB, $OUTPUT, $PAGE;
 | 
        
           |  |  | 528 |   | 
        
           |  |  | 529 |     //TODO: use timestamp in approved field instead of changing timemodified when approving in 2.0
 | 
        
           |  |  | 530 |     if (!defined('GLOSSARY_RECENT_ACTIVITY_LIMIT')) {
 | 
        
           |  |  | 531 |         define('GLOSSARY_RECENT_ACTIVITY_LIMIT', 50);
 | 
        
           |  |  | 532 |     }
 | 
        
           |  |  | 533 |     $modinfo = get_fast_modinfo($course);
 | 
        
           |  |  | 534 |     $ids = array();
 | 
        
           |  |  | 535 |   | 
        
           |  |  | 536 |     foreach ($modinfo->cms as $cm) {
 | 
        
           |  |  | 537 |         if ($cm->modname != 'glossary') {
 | 
        
           |  |  | 538 |             continue;
 | 
        
           |  |  | 539 |         }
 | 
        
           |  |  | 540 |         if (!$cm->uservisible) {
 | 
        
           |  |  | 541 |             continue;
 | 
        
           |  |  | 542 |         }
 | 
        
           |  |  | 543 |         $ids[$cm->instance] = $cm->id;
 | 
        
           |  |  | 544 |     }
 | 
        
           |  |  | 545 |   | 
        
           |  |  | 546 |     if (!$ids) {
 | 
        
           |  |  | 547 |         return false;
 | 
        
           |  |  | 548 |     }
 | 
        
           |  |  | 549 |   | 
        
           |  |  | 550 |     // generate list of approval capabilities for all glossaries in the course.
 | 
        
           |  |  | 551 |     $approvals = array();
 | 
        
           |  |  | 552 |     foreach ($ids as $glinstanceid => $glcmid) {
 | 
        
           |  |  | 553 |         $context = context_module::instance($glcmid);
 | 
        
           |  |  | 554 |         if (has_capability('mod/glossary:view', $context)) {
 | 
        
           |  |  | 555 |             // get records glossary entries that are approved if user has no capability to approve entries.
 | 
        
           |  |  | 556 |             if (has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 557 |                 $approvals[] = ' ge.glossaryid = :glsid'.$glinstanceid.' ';
 | 
        
           |  |  | 558 |             } else {
 | 
        
           |  |  | 559 |                 $approvals[] = ' (ge.approved = 1 AND ge.glossaryid = :glsid'.$glinstanceid.') ';
 | 
        
           |  |  | 560 |             }
 | 
        
           |  |  | 561 |             $params['glsid'.$glinstanceid] = $glinstanceid;
 | 
        
           |  |  | 562 |         }
 | 
        
           |  |  | 563 |     }
 | 
        
           |  |  | 564 |   | 
        
           |  |  | 565 |     if (count($approvals) == 0) {
 | 
        
           |  |  | 566 |         return false;
 | 
        
           |  |  | 567 |     }
 | 
        
           |  |  | 568 |     $userfieldsapi = \core_user\fields::for_userpic();
 | 
        
           |  |  | 569 |     $userfields = $userfieldsapi->get_sql('u', false, '', 'userid', false)->selects;
 | 
        
           |  |  | 570 |     $selectsql = 'SELECT ge.id, ge.concept, ge.approved, ge.timemodified, ge.glossaryid,
 | 
        
           |  |  | 571 |             ' . $userfields;
 | 
        
           |  |  | 572 |     $countsql = 'SELECT COUNT(*)';
 | 
        
           |  |  | 573 |   | 
        
           |  |  | 574 |     $joins = array(' FROM {glossary_entries} ge ');
 | 
        
           |  |  | 575 |     $joins[] = 'JOIN {user} u ON u.id = ge.userid ';
 | 
        
           |  |  | 576 |     $fromsql = implode("\n", $joins);
 | 
        
           |  |  | 577 |   | 
        
           |  |  | 578 |     $params['timestart'] = $timestart;
 | 
        
           |  |  | 579 |     $clausesql = ' WHERE ge.timemodified > :timestart ';
 | 
        
           |  |  | 580 |   | 
        
           |  |  | 581 |     if (count($approvals) > 0) {
 | 
        
           |  |  | 582 |         $approvalsql = 'AND ('. implode(' OR ', $approvals) .') ';
 | 
        
           |  |  | 583 |     } else {
 | 
        
           |  |  | 584 |         $approvalsql = '';
 | 
        
           |  |  | 585 |     }
 | 
        
           |  |  | 586 |     $ordersql = 'ORDER BY ge.timemodified ASC';
 | 
        
           |  |  | 587 |     $entries = $DB->get_records_sql($selectsql.$fromsql.$clausesql.$approvalsql.$ordersql, $params, 0, (GLOSSARY_RECENT_ACTIVITY_LIMIT+1));
 | 
        
           |  |  | 588 |   | 
        
           |  |  | 589 |     if (empty($entries)) {
 | 
        
           |  |  | 590 |         return false;
 | 
        
           |  |  | 591 |     }
 | 
        
           |  |  | 592 |   | 
        
           |  |  | 593 |     echo $OUTPUT->heading(get_string('newentries', 'glossary') . ':', 6);
 | 
        
           |  |  | 594 |     $strftimerecent = get_string('strftimerecent');
 | 
        
           |  |  | 595 |     $entrycount = 0;
 | 
        
           |  |  | 596 |     foreach ($entries as $entry) {
 | 
        
           |  |  | 597 |         if ($entrycount < GLOSSARY_RECENT_ACTIVITY_LIMIT) {
 | 
        
           |  |  | 598 |             if ($entry->approved) {
 | 
        
           |  |  | 599 |                 $dimmed = '';
 | 
        
           |  |  | 600 |                 $urlparams = array('g' => $entry->glossaryid, 'mode' => 'entry', 'hook' => $entry->id);
 | 
        
           |  |  | 601 |             } else {
 | 
        
           |  |  | 602 |                 $dimmed = ' dimmed_text';
 | 
        
           |  |  | 603 |                 $urlparams = array('id' => $ids[$entry->glossaryid], 'mode' => 'approval', 'hook' => format_text($entry->concept, true));
 | 
        
           |  |  | 604 |             }
 | 
        
           |  |  | 605 |             $link = new moodle_url($CFG->wwwroot.'/mod/glossary/view.php' , $urlparams);
 | 
        
           |  |  | 606 |             echo '<div class="head'.$dimmed.'">';
 | 
        
           |  |  | 607 |             echo '<div class="date">'.userdate($entry->timemodified, $strftimerecent).'</div>';
 | 
        
           |  |  | 608 |             echo '<div class="name">'.fullname($entry, $viewfullnames).'</div>';
 | 
        
           |  |  | 609 |             echo '</div>';
 | 
        
           |  |  | 610 |             echo '<div class="info"><a href="'.$link.'">'.format_string($entry->concept, true).'</a></div>';
 | 
        
           |  |  | 611 |             $entrycount += 1;
 | 
        
           |  |  | 612 |         } else {
 | 
        
           |  |  | 613 |             $numnewentries = $DB->count_records_sql($countsql.$joins[0].$clausesql.$approvalsql, $params);
 | 
        
           |  |  | 614 |             echo '<div class="head"><div class="activityhead">'.get_string('andmorenewentries', 'glossary', $numnewentries - GLOSSARY_RECENT_ACTIVITY_LIMIT).'</div></div>';
 | 
        
           |  |  | 615 |             break;
 | 
        
           |  |  | 616 |         }
 | 
        
           |  |  | 617 |     }
 | 
        
           |  |  | 618 |   | 
        
           |  |  | 619 |     return true;
 | 
        
           |  |  | 620 | }
 | 
        
           |  |  | 621 |   | 
        
           |  |  | 622 | /**
 | 
        
           |  |  | 623 |  * @global object
 | 
        
           |  |  | 624 |  * @param object $log
 | 
        
           |  |  | 625 |  */
 | 
        
           |  |  | 626 | function glossary_log_info($log) {
 | 
        
           |  |  | 627 |     global $DB;
 | 
        
           |  |  | 628 |   | 
        
           |  |  | 629 |     return $DB->get_record_sql("SELECT e.*, u.firstname, u.lastname
 | 
        
           |  |  | 630 |                                   FROM {glossary_entries} e, {user} u
 | 
        
           |  |  | 631 |                                  WHERE e.id = ? AND u.id = ?", array($log->info, $log->userid));
 | 
        
           |  |  | 632 | }
 | 
        
           |  |  | 633 |   | 
        
           |  |  | 634 | /**
 | 
        
           |  |  | 635 |  * Function to be run periodically according to the moodle cron
 | 
        
           |  |  | 636 |  * This function searches for things that need to be done, such
 | 
        
           |  |  | 637 |  * as sending out mail, toggling flags etc ...
 | 
        
           |  |  | 638 |  * @return bool
 | 
        
           |  |  | 639 |  */
 | 
        
           |  |  | 640 | function glossary_cron () {
 | 
        
           |  |  | 641 |     return true;
 | 
        
           |  |  | 642 | }
 | 
        
           |  |  | 643 |   | 
        
           |  |  | 644 | /**
 | 
        
           |  |  | 645 |  * Return grade for given user or all users.
 | 
        
           |  |  | 646 |  *
 | 
        
           |  |  | 647 |  * @param stdClass $glossary A glossary instance
 | 
        
           |  |  | 648 |  * @param int $userid Optional user id, 0 means all users
 | 
        
           |  |  | 649 |  * @return array An array of grades, false if none
 | 
        
           |  |  | 650 |  */
 | 
        
           |  |  | 651 | function glossary_get_user_grades($glossary, $userid=0) {
 | 
        
           |  |  | 652 |     global $CFG;
 | 
        
           |  |  | 653 |   | 
        
           |  |  | 654 |     require_once($CFG->dirroot.'/rating/lib.php');
 | 
        
           |  |  | 655 |   | 
        
           |  |  | 656 |     $ratingoptions = new stdClass;
 | 
        
           |  |  | 657 |   | 
        
           |  |  | 658 |     //need these to work backwards to get a context id. Is there a better way to get contextid from a module instance?
 | 
        
           |  |  | 659 |     $ratingoptions->modulename = 'glossary';
 | 
        
           |  |  | 660 |     $ratingoptions->moduleid   = $glossary->id;
 | 
        
           |  |  | 661 |     $ratingoptions->component  = 'mod_glossary';
 | 
        
           |  |  | 662 |     $ratingoptions->ratingarea = 'entry';
 | 
        
           |  |  | 663 |   | 
        
           |  |  | 664 |     $ratingoptions->userid = $userid;
 | 
        
           |  |  | 665 |     $ratingoptions->aggregationmethod = $glossary->assessed;
 | 
        
           |  |  | 666 |     $ratingoptions->scaleid = $glossary->scale;
 | 
        
           |  |  | 667 |     $ratingoptions->itemtable = 'glossary_entries';
 | 
        
           |  |  | 668 |     $ratingoptions->itemtableusercolumn = 'userid';
 | 
        
           |  |  | 669 |   | 
        
           |  |  | 670 |     $rm = new rating_manager();
 | 
        
           |  |  | 671 |     return $rm->get_user_grades($ratingoptions);
 | 
        
           |  |  | 672 | }
 | 
        
           |  |  | 673 |   | 
        
           |  |  | 674 | /**
 | 
        
           |  |  | 675 |  * Return rating related permissions
 | 
        
           |  |  | 676 |  *
 | 
        
           |  |  | 677 |  * @param int $contextid the context id
 | 
        
           |  |  | 678 |  * @param string $component The component we want to get permissions for
 | 
        
           |  |  | 679 |  * @param string $ratingarea The ratingarea that we want to get permissions for
 | 
        
           |  |  | 680 |  * @return array an associative array of the user's rating permissions
 | 
        
           |  |  | 681 |  */
 | 
        
           |  |  | 682 | function glossary_rating_permissions($contextid, $component, $ratingarea) {
 | 
        
           |  |  | 683 |     if ($component != 'mod_glossary' || $ratingarea != 'entry') {
 | 
        
           |  |  | 684 |         // We don't know about this component/ratingarea so just return null to get the
 | 
        
           |  |  | 685 |         // default restrictive permissions.
 | 
        
           |  |  | 686 |         return null;
 | 
        
           |  |  | 687 |     }
 | 
        
           |  |  | 688 |     $context = context::instance_by_id($contextid);
 | 
        
           |  |  | 689 |     return array(
 | 
        
           |  |  | 690 |         'view'    => has_capability('mod/glossary:viewrating', $context),
 | 
        
           |  |  | 691 |         'viewany' => has_capability('mod/glossary:viewanyrating', $context),
 | 
        
           |  |  | 692 |         'viewall' => has_capability('mod/glossary:viewallratings', $context),
 | 
        
           |  |  | 693 |         'rate'    => has_capability('mod/glossary:rate', $context)
 | 
        
           |  |  | 694 |     );
 | 
        
           |  |  | 695 | }
 | 
        
           |  |  | 696 |   | 
        
           |  |  | 697 | /**
 | 
        
           |  |  | 698 |  * Validates a submitted rating
 | 
        
           |  |  | 699 |  * @param array $params submitted data
 | 
        
           |  |  | 700 |  *            context => object the context in which the rated items exists [required]
 | 
        
           |  |  | 701 |  *            component => The component for this module - should always be mod_forum [required]
 | 
        
           |  |  | 702 |  *            ratingarea => object the context in which the rated items exists [required]
 | 
        
           |  |  | 703 |  *            itemid => int the ID of the object being rated [required]
 | 
        
           |  |  | 704 |  *            scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required]
 | 
        
           |  |  | 705 |  *            rating => int the submitted rating
 | 
        
           |  |  | 706 |  *            rateduserid => int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]
 | 
        
           |  |  | 707 |  *            aggregation => int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [optional]
 | 
        
           |  |  | 708 |  * @return boolean true if the rating is valid. Will throw rating_exception if not
 | 
        
           |  |  | 709 |  */
 | 
        
           |  |  | 710 | function glossary_rating_validate($params) {
 | 
        
           |  |  | 711 |     global $DB, $USER;
 | 
        
           |  |  | 712 |   | 
        
           |  |  | 713 |     // Check the component is mod_forum
 | 
        
           |  |  | 714 |     if ($params['component'] != 'mod_glossary') {
 | 
        
           |  |  | 715 |         throw new rating_exception('invalidcomponent');
 | 
        
           |  |  | 716 |     }
 | 
        
           |  |  | 717 |   | 
        
           |  |  | 718 |     // Check the ratingarea is post (the only rating area in forum)
 | 
        
           |  |  | 719 |     if ($params['ratingarea'] != 'entry') {
 | 
        
           |  |  | 720 |         throw new rating_exception('invalidratingarea');
 | 
        
           |  |  | 721 |     }
 | 
        
           |  |  | 722 |   | 
        
           |  |  | 723 |     // Check the rateduserid is not the current user .. you can't rate your own posts
 | 
        
           |  |  | 724 |     if ($params['rateduserid'] == $USER->id) {
 | 
        
           |  |  | 725 |         throw new rating_exception('nopermissiontorate');
 | 
        
           |  |  | 726 |     }
 | 
        
           |  |  | 727 |   | 
        
           |  |  | 728 |     $glossarysql = "SELECT g.id as glossaryid, g.scale, g.course, e.userid as userid, e.approved, e.timecreated, g.assesstimestart, g.assesstimefinish
 | 
        
           |  |  | 729 |                       FROM {glossary_entries} e
 | 
        
           |  |  | 730 |                       JOIN {glossary} g ON e.glossaryid = g.id
 | 
        
           |  |  | 731 |                      WHERE e.id = :itemid";
 | 
        
           |  |  | 732 |     $glossaryparams = array('itemid' => $params['itemid']);
 | 
        
           |  |  | 733 |     $info = $DB->get_record_sql($glossarysql, $glossaryparams);
 | 
        
           |  |  | 734 |     if (!$info) {
 | 
        
           |  |  | 735 |         //item doesn't exist
 | 
        
           |  |  | 736 |         throw new rating_exception('invaliditemid');
 | 
        
           |  |  | 737 |     }
 | 
        
           |  |  | 738 |   | 
        
           |  |  | 739 |     if ($info->scale != $params['scaleid']) {
 | 
        
           |  |  | 740 |         //the scale being submitted doesnt match the one in the database
 | 
        
           |  |  | 741 |         throw new rating_exception('invalidscaleid');
 | 
        
           |  |  | 742 |     }
 | 
        
           |  |  | 743 |   | 
        
           |  |  | 744 |     //check that the submitted rating is valid for the scale
 | 
        
           |  |  | 745 |   | 
        
           |  |  | 746 |     // lower limit
 | 
        
           |  |  | 747 |     if ($params['rating'] < 0  && $params['rating'] != RATING_UNSET_RATING) {
 | 
        
           |  |  | 748 |         throw new rating_exception('invalidnum');
 | 
        
           |  |  | 749 |     }
 | 
        
           |  |  | 750 |   | 
        
           |  |  | 751 |     // upper limit
 | 
        
           |  |  | 752 |     if ($info->scale < 0) {
 | 
        
           |  |  | 753 |         //its a custom scale
 | 
        
           |  |  | 754 |         $scalerecord = $DB->get_record('scale', array('id' => -$info->scale));
 | 
        
           |  |  | 755 |         if ($scalerecord) {
 | 
        
           |  |  | 756 |             $scalearray = explode(',', $scalerecord->scale);
 | 
        
           |  |  | 757 |             if ($params['rating'] > count($scalearray)) {
 | 
        
           |  |  | 758 |                 throw new rating_exception('invalidnum');
 | 
        
           |  |  | 759 |             }
 | 
        
           |  |  | 760 |         } else {
 | 
        
           |  |  | 761 |             throw new rating_exception('invalidscaleid');
 | 
        
           |  |  | 762 |         }
 | 
        
           |  |  | 763 |     } else if ($params['rating'] > $info->scale) {
 | 
        
           |  |  | 764 |         //if its numeric and submitted rating is above maximum
 | 
        
           |  |  | 765 |         throw new rating_exception('invalidnum');
 | 
        
           |  |  | 766 |     }
 | 
        
           |  |  | 767 |   | 
        
           |  |  | 768 |     //check the item we're rating was created in the assessable time window
 | 
        
           |  |  | 769 |     if (!empty($info->assesstimestart) && !empty($info->assesstimefinish)) {
 | 
        
           |  |  | 770 |         if ($info->timecreated < $info->assesstimestart || $info->timecreated > $info->assesstimefinish) {
 | 
        
           |  |  | 771 |             throw new rating_exception('notavailable');
 | 
        
           |  |  | 772 |         }
 | 
        
           |  |  | 773 |     }
 | 
        
           |  |  | 774 |   | 
        
           |  |  | 775 |     $cm = get_coursemodule_from_instance('glossary', $info->glossaryid, $info->course, false, MUST_EXIST);
 | 
        
           |  |  | 776 |     $context = context_module::instance($cm->id, MUST_EXIST);
 | 
        
           |  |  | 777 |   | 
        
           |  |  | 778 |     // if the supplied context doesnt match the item's context
 | 
        
           |  |  | 779 |     if ($context->id != $params['context']->id) {
 | 
        
           |  |  | 780 |         throw new rating_exception('invalidcontext');
 | 
        
           |  |  | 781 |     }
 | 
        
           |  |  | 782 |   | 
        
           |  |  | 783 |     return true;
 | 
        
           |  |  | 784 | }
 | 
        
           |  |  | 785 |   | 
        
           |  |  | 786 | /**
 | 
        
           |  |  | 787 |  * Update activity grades
 | 
        
           |  |  | 788 |  *
 | 
        
           |  |  | 789 |  * @category grade
 | 
        
           |  |  | 790 |  * @param stdClass $glossary Null means all glossaries (with extra cmidnumber property)
 | 
        
           |  |  | 791 |  * @param int $userid specific user only, 0 means all
 | 
        
           |  |  | 792 |  * @param bool $nullifnone If true and the user has no grade then a grade item with rawgrade == null will be inserted
 | 
        
           |  |  | 793 |  */
 | 
        
           |  |  | 794 | function glossary_update_grades($glossary=null, $userid=0, $nullifnone=true) {
 | 
        
           |  |  | 795 |     global $CFG, $DB;
 | 
        
           |  |  | 796 |     require_once($CFG->libdir.'/gradelib.php');
 | 
        
           |  |  | 797 |   | 
        
           |  |  | 798 |     if (!$glossary->assessed) {
 | 
        
           |  |  | 799 |         glossary_grade_item_update($glossary);
 | 
        
           |  |  | 800 |   | 
        
           |  |  | 801 |     } else if ($grades = glossary_get_user_grades($glossary, $userid)) {
 | 
        
           |  |  | 802 |         glossary_grade_item_update($glossary, $grades);
 | 
        
           |  |  | 803 |   | 
        
           |  |  | 804 |     } else if ($userid and $nullifnone) {
 | 
        
           |  |  | 805 |         $grade = new stdClass();
 | 
        
           |  |  | 806 |         $grade->userid   = $userid;
 | 
        
           |  |  | 807 |         $grade->rawgrade = NULL;
 | 
        
           |  |  | 808 |         glossary_grade_item_update($glossary, $grade);
 | 
        
           |  |  | 809 |   | 
        
           |  |  | 810 |     } else {
 | 
        
           |  |  | 811 |         glossary_grade_item_update($glossary);
 | 
        
           |  |  | 812 |     }
 | 
        
           |  |  | 813 | }
 | 
        
           |  |  | 814 |   | 
        
           |  |  | 815 | /**
 | 
        
           |  |  | 816 |  * Create/update grade item for given glossary
 | 
        
           |  |  | 817 |  *
 | 
        
           |  |  | 818 |  * @category grade
 | 
        
           |  |  | 819 |  * @param stdClass $glossary object with extra cmidnumber
 | 
        
           |  |  | 820 |  * @param mixed $grades Optional array/object of grade(s); 'reset' means reset grades in gradebook
 | 
        
           |  |  | 821 |  * @return int, 0 if ok, error code otherwise
 | 
        
           |  |  | 822 |  */
 | 
        
           |  |  | 823 | function glossary_grade_item_update($glossary, $grades=NULL) {
 | 
        
           |  |  | 824 |     global $CFG;
 | 
        
           |  |  | 825 |     require_once($CFG->libdir.'/gradelib.php');
 | 
        
           |  |  | 826 |   | 
        
           |  |  | 827 |     $params = array('itemname'=>$glossary->name, 'idnumber'=>$glossary->cmidnumber);
 | 
        
           |  |  | 828 |   | 
        
           |  |  | 829 |     if (!$glossary->assessed or $glossary->scale == 0) {
 | 
        
           |  |  | 830 |         $params['gradetype'] = GRADE_TYPE_NONE;
 | 
        
           |  |  | 831 |   | 
        
           |  |  | 832 |     } else if ($glossary->scale > 0) {
 | 
        
           |  |  | 833 |         $params['gradetype'] = GRADE_TYPE_VALUE;
 | 
        
           |  |  | 834 |         $params['grademax']  = $glossary->scale;
 | 
        
           |  |  | 835 |         $params['grademin']  = 0;
 | 
        
           |  |  | 836 |   | 
        
           |  |  | 837 |     } else if ($glossary->scale < 0) {
 | 
        
           |  |  | 838 |         $params['gradetype'] = GRADE_TYPE_SCALE;
 | 
        
           |  |  | 839 |         $params['scaleid']   = -$glossary->scale;
 | 
        
           |  |  | 840 |     }
 | 
        
           |  |  | 841 |   | 
        
           |  |  | 842 |     if ($grades  === 'reset') {
 | 
        
           |  |  | 843 |         $params['reset'] = true;
 | 
        
           |  |  | 844 |         $grades = NULL;
 | 
        
           |  |  | 845 |     }
 | 
        
           |  |  | 846 |   | 
        
           |  |  | 847 |     return grade_update('mod/glossary', $glossary->course, 'mod', 'glossary', $glossary->id, 0, $grades, $params);
 | 
        
           |  |  | 848 | }
 | 
        
           |  |  | 849 |   | 
        
           |  |  | 850 | /**
 | 
        
           |  |  | 851 |  * Delete grade item for given glossary
 | 
        
           |  |  | 852 |  *
 | 
        
           |  |  | 853 |  * @category grade
 | 
        
           |  |  | 854 |  * @param object $glossary object
 | 
        
           |  |  | 855 |  */
 | 
        
           |  |  | 856 | function glossary_grade_item_delete($glossary) {
 | 
        
           |  |  | 857 |     global $CFG;
 | 
        
           |  |  | 858 |     require_once($CFG->libdir.'/gradelib.php');
 | 
        
           |  |  | 859 |   | 
        
           |  |  | 860 |     return grade_update('mod/glossary', $glossary->course, 'mod', 'glossary', $glossary->id, 0, NULL, array('deleted'=>1));
 | 
        
           |  |  | 861 | }
 | 
        
           |  |  | 862 |   | 
        
           |  |  | 863 | /**
 | 
        
           |  |  | 864 |  * Checks if scale is being used by any instance of glossary
 | 
        
           |  |  | 865 |  *
 | 
        
           |  |  | 866 |  * This is used to find out if scale used anywhere
 | 
        
           |  |  | 867 |  *
 | 
        
           |  |  | 868 |  * @global object
 | 
        
           |  |  | 869 |  * @param int $scaleid
 | 
        
           |  |  | 870 |  * @return boolean True if the scale is used by any glossary
 | 
        
           |  |  | 871 |  */
 | 
        
           |  |  | 872 | function glossary_scale_used_anywhere($scaleid) {
 | 
        
           |  |  | 873 |     global $DB;
 | 
        
           |  |  | 874 |   | 
        
           |  |  | 875 |     if ($scaleid and $DB->record_exists_select('glossary', "scale = ? and assessed > 0", [-$scaleid])) {
 | 
        
           |  |  | 876 |         return true;
 | 
        
           |  |  | 877 |     } else {
 | 
        
           |  |  | 878 |         return false;
 | 
        
           |  |  | 879 |     }
 | 
        
           |  |  | 880 | }
 | 
        
           |  |  | 881 |   | 
        
           |  |  | 882 | //////////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 883 | /// Any other glossary functions go here.  Each of them must have a name that
 | 
        
           |  |  | 884 | /// starts with glossary_
 | 
        
           |  |  | 885 |   | 
        
           |  |  | 886 | /**
 | 
        
           |  |  | 887 |  * This function return an array of valid glossary_formats records
 | 
        
           |  |  | 888 |  * Everytime it's called, every existing format is checked, new formats
 | 
        
           |  |  | 889 |  * are included if detected and old formats are deleted and any glossary
 | 
        
           |  |  | 890 |  * using an invalid format is updated to the default (dictionary).
 | 
        
           |  |  | 891 |  *
 | 
        
           |  |  | 892 |  * @global object
 | 
        
           |  |  | 893 |  * @global object
 | 
        
           |  |  | 894 |  * @return array
 | 
        
           |  |  | 895 |  */
 | 
        
           |  |  | 896 | function glossary_get_available_formats() {
 | 
        
           |  |  | 897 |     global $CFG, $DB;
 | 
        
           |  |  | 898 |   | 
        
           |  |  | 899 |     // Get available formats (plugin) and insert them (if necessary) into glossary_formats.
 | 
        
           |  |  | 900 |     $formats = get_list_of_plugins('mod/glossary/formats', 'TEMPLATE');
 | 
        
           |  |  | 901 |     $pluginformats = array();
 | 
        
           |  |  | 902 |     $formatrecords = $DB->get_records("glossary_formats");
 | 
        
           |  |  | 903 |   | 
        
           |  |  | 904 |     foreach ($formats as $format) {
 | 
        
           |  |  | 905 |         // If the format file exists.
 | 
        
           |  |  | 906 |         if (file_exists($CFG->dirroot.'/mod/glossary/formats/'.$format.'/'.$format.'_format.php')) {
 | 
        
           |  |  | 907 |             include_once($CFG->dirroot.'/mod/glossary/formats/'.$format.'/'.$format.'_format.php');
 | 
        
           |  |  | 908 |             //If the function exists
 | 
        
           |  |  | 909 |             if (function_exists('glossary_show_entry_'.$format)) {
 | 
        
           |  |  | 910 |                 // Acummulate it as a valid format.
 | 
        
           |  |  | 911 |                 $pluginformats[] = $format;
 | 
        
           |  |  | 912 |   | 
        
           |  |  | 913 |                 // Check if the format exists in the table.
 | 
        
           |  |  | 914 |                 $rec = null;
 | 
        
           |  |  | 915 |                 foreach ($formatrecords as $record) {
 | 
        
           |  |  | 916 |                     if ($record->name == $format) {
 | 
        
           |  |  | 917 |                         $rec = $record;
 | 
        
           |  |  | 918 |                         break;
 | 
        
           |  |  | 919 |                     }
 | 
        
           |  |  | 920 |                 }
 | 
        
           |  |  | 921 |   | 
        
           |  |  | 922 |                 if (!$rec) {
 | 
        
           |  |  | 923 |                     // Insert the record in glossary_formats.
 | 
        
           |  |  | 924 |                     $gf = new stdClass();
 | 
        
           |  |  | 925 |                     $gf->name = $format;
 | 
        
           |  |  | 926 |                     $gf->popupformatname = $format;
 | 
        
           |  |  | 927 |                     $gf->visible = 1;
 | 
        
           |  |  | 928 |                     $id = $DB->insert_record('glossary_formats', $gf);
 | 
        
           |  |  | 929 |                     $rec = $DB->get_record('glossary_formats', array('id' => $id));
 | 
        
           |  |  | 930 |                     array_push($formatrecords, $rec);
 | 
        
           |  |  | 931 |                 }
 | 
        
           |  |  | 932 |   | 
        
           |  |  | 933 |                 if (empty($rec->showtabs)) {
 | 
        
           |  |  | 934 |                     glossary_set_default_visible_tabs($rec);
 | 
        
           |  |  | 935 |                 }
 | 
        
           |  |  | 936 |             }
 | 
        
           |  |  | 937 |         }
 | 
        
           |  |  | 938 |     }
 | 
        
           |  |  | 939 |   | 
        
           |  |  | 940 |     // Delete non_existent formats from glossary_formats table.
 | 
        
           |  |  | 941 |     foreach ($formatrecords as $record) {
 | 
        
           |  |  | 942 |         $todelete = false;
 | 
        
           |  |  | 943 |         // If the format in DB isn't a valid previously detected format then delete the record.
 | 
        
           |  |  | 944 |         if (!in_array($record->name, $pluginformats)) {
 | 
        
           |  |  | 945 |             $todelete = true;
 | 
        
           |  |  | 946 |         }
 | 
        
           |  |  | 947 |   | 
        
           |  |  | 948 |         if ($todelete) {
 | 
        
           |  |  | 949 |             // Delete the format.
 | 
        
           |  |  | 950 |             $DB->delete_records('glossary_formats', array('id' => $record->id));
 | 
        
           |  |  | 951 |             unset($formatrecords[$record->id]);
 | 
        
           |  |  | 952 |   | 
        
           |  |  | 953 |             // Reassign existing glossaries to default (dictionary) format.
 | 
        
           |  |  | 954 |             if ($glossaries = $DB->get_records('glossary', array('displayformat' => $record->name))) {
 | 
        
           |  |  | 955 |                 foreach($glossaries as $glossary) {
 | 
        
           |  |  | 956 |                     $DB->set_field('glossary', 'displayformat', 'dictionary', array('id' => $glossary->id));
 | 
        
           |  |  | 957 |                 }
 | 
        
           |  |  | 958 |             }
 | 
        
           |  |  | 959 |         }
 | 
        
           |  |  | 960 |     }
 | 
        
           |  |  | 961 |   | 
        
           |  |  | 962 |     return $formatrecords;
 | 
        
           |  |  | 963 | }
 | 
        
           |  |  | 964 |   | 
        
           |  |  | 965 | /**
 | 
        
           |  |  | 966 |  * @param bool $debug
 | 
        
           |  |  | 967 |  * @param string $text
 | 
        
           |  |  | 968 |  * @param int $br
 | 
        
           |  |  | 969 |  */
 | 
        
           |  |  | 970 | function glossary_debug($debug,$text,$br=1) {
 | 
        
           |  |  | 971 |     if ( $debug ) {
 | 
        
           |  |  | 972 |         echo '<font color="red">' . $text . '</font>';
 | 
        
           |  |  | 973 |         if ( $br ) {
 | 
        
           |  |  | 974 |             echo '<br />';
 | 
        
           |  |  | 975 |         }
 | 
        
           |  |  | 976 |     }
 | 
        
           |  |  | 977 | }
 | 
        
           |  |  | 978 |   | 
        
           |  |  | 979 | /**
 | 
        
           |  |  | 980 |  *
 | 
        
           |  |  | 981 |  * @global object
 | 
        
           |  |  | 982 |  * @param int $glossaryid
 | 
        
           |  |  | 983 |  * @param string $entrylist
 | 
        
           |  |  | 984 |  * @param string $pivot
 | 
        
           |  |  | 985 |  * @return array
 | 
        
           |  |  | 986 |  */
 | 
        
           |  |  | 987 | function glossary_get_entries($glossaryid, $entrylist, $pivot = "") {
 | 
        
           |  |  | 988 |     global $DB;
 | 
        
           |  |  | 989 |     if ($pivot) {
 | 
        
           |  |  | 990 |        $pivot .= ",";
 | 
        
           |  |  | 991 |     }
 | 
        
           |  |  | 992 |   | 
        
           |  |  | 993 |     return $DB->get_records_sql("SELECT $pivot id,userid,concept,definition,format
 | 
        
           |  |  | 994 |                                    FROM {glossary_entries}
 | 
        
           |  |  | 995 |                                   WHERE glossaryid = ?
 | 
        
           |  |  | 996 |                                         AND id IN ($entrylist)", array($glossaryid));
 | 
        
           |  |  | 997 | }
 | 
        
           |  |  | 998 |   | 
        
           |  |  | 999 | /**
 | 
        
           |  |  | 1000 |  * @global object
 | 
        
           |  |  | 1001 |  * @global object
 | 
        
           |  |  | 1002 |  * @param string $concept
 | 
        
           |  |  | 1003 |  * @param int $courseid
 | 
        
           |  |  | 1004 |  * @return array
 | 
        
           |  |  | 1005 |  */
 | 
        
           |  |  | 1006 | function glossary_get_entries_search($concept, $courseid) {
 | 
        
           |  |  | 1007 |     global $DB;
 | 
        
           |  |  | 1008 |   | 
        
           |  |  | 1009 |     //Check if the user is an admin
 | 
        
           |  |  | 1010 |     $bypassadmin = 1; //This means NO (by default)
 | 
        
           |  |  | 1011 |     if (has_capability('moodle/course:viewhiddenactivities', context_system::instance())) {
 | 
        
           |  |  | 1012 |         $bypassadmin = 0; //This means YES
 | 
        
           |  |  | 1013 |     }
 | 
        
           |  |  | 1014 |   | 
        
           |  |  | 1015 |     //Check if the user is a teacher
 | 
        
           |  |  | 1016 |     $bypassteacher = 1; //This means NO (by default)
 | 
        
           |  |  | 1017 |     if (has_capability('mod/glossary:manageentries', context_course::instance($courseid))) {
 | 
        
           |  |  | 1018 |         $bypassteacher = 0; //This means YES
 | 
        
           |  |  | 1019 |     }
 | 
        
           |  |  | 1020 |   | 
        
           |  |  | 1021 |     $conceptlower = core_text::strtolower(trim($concept));
 | 
        
           |  |  | 1022 |   | 
        
           |  |  | 1023 |     $params = array('courseid1'=>$courseid, 'courseid2'=>$courseid, 'conceptlower'=>$conceptlower, 'concept'=>$concept);
 | 
        
           |  |  | 1024 |     $sensitiveconceptsql = $DB->sql_equal('concept', ':concept');
 | 
        
           |  |  | 1025 |   | 
        
           |  |  | 1026 |     return $DB->get_records_sql("SELECT e.*, g.name as glossaryname, cm.id as cmid, cm.course as courseid
 | 
        
           |  |  | 1027 |                                    FROM {glossary_entries} e, {glossary} g,
 | 
        
           |  |  | 1028 |                                         {course_modules} cm, {modules} m
 | 
        
           |  |  | 1029 |                                   WHERE m.name = 'glossary' AND
 | 
        
           |  |  | 1030 |                                         cm.module = m.id AND
 | 
        
           |  |  | 1031 |                                         (cm.visible = 1 OR  cm.visible = $bypassadmin OR
 | 
        
           |  |  | 1032 |                                             (cm.course = :courseid1 AND cm.visible = $bypassteacher)) AND
 | 
        
           |  |  | 1033 |                                         g.id = cm.instance AND
 | 
        
           |  |  | 1034 |                                         e.glossaryid = g.id  AND
 | 
        
           |  |  | 1035 |                                         ( (e.casesensitive != 1 AND LOWER(concept) = :conceptlower) OR
 | 
        
           |  |  | 1036 |                                           (e.casesensitive = 1 and $sensitiveconceptsql)) AND
 | 
        
           |  |  | 1037 |                                         (g.course = :courseid2 OR g.globalglossary = 1) AND
 | 
        
           |  |  | 1038 |                                          e.usedynalink != 0 AND
 | 
        
           |  |  | 1039 |                                          g.usedynalink != 0", $params);
 | 
        
           |  |  | 1040 | }
 | 
        
           |  |  | 1041 |   | 
        
           |  |  | 1042 | /**
 | 
        
           |  |  | 1043 |  * @global object
 | 
        
           |  |  | 1044 |  * @global object
 | 
        
           |  |  | 1045 |  * @param object $course
 | 
        
           |  |  | 1046 |  * @param object $course
 | 
        
           |  |  | 1047 |  * @param object $glossary
 | 
        
           |  |  | 1048 |  * @param object $entry
 | 
        
           |  |  | 1049 |  * @param string $mode
 | 
        
           |  |  | 1050 |  * @param string $hook
 | 
        
           |  |  | 1051 |  * @param int $printicons
 | 
        
           |  |  | 1052 |  * @param int $displayformat
 | 
        
           |  |  | 1053 |  * @param bool $printview
 | 
        
           |  |  | 1054 |  * @return mixed
 | 
        
           |  |  | 1055 |  */
 | 
        
           |  |  | 1056 | function glossary_print_entry($course, $cm, $glossary, $entry, $mode='',$hook='',$printicons = 1, $displayformat  = -1, $printview = false) {
 | 
        
           |  |  | 1057 |     global $USER, $CFG;
 | 
        
           |  |  | 1058 |     $return = false;
 | 
        
           |  |  | 1059 |     if ( $displayformat < 0 ) {
 | 
        
           |  |  | 1060 |         $displayformat = $glossary->displayformat;
 | 
        
           |  |  | 1061 |     }
 | 
        
           |  |  | 1062 |     if ($entry->approved or ($USER->id == $entry->userid) or ($mode == 'approval' and !$entry->approved) ) {
 | 
        
           |  |  | 1063 |         $formatfile = $CFG->dirroot.'/mod/glossary/formats/'.$displayformat.'/'.$displayformat.'_format.php';
 | 
        
           |  |  | 1064 |         if ($printview) {
 | 
        
           |  |  | 1065 |             $functionname = 'glossary_print_entry_'.$displayformat;
 | 
        
           |  |  | 1066 |         } else {
 | 
        
           |  |  | 1067 |             $functionname = 'glossary_show_entry_'.$displayformat;
 | 
        
           |  |  | 1068 |         }
 | 
        
           |  |  | 1069 |   | 
        
           |  |  | 1070 |         if (file_exists($formatfile)) {
 | 
        
           |  |  | 1071 |             include_once($formatfile);
 | 
        
           |  |  | 1072 |             if (function_exists($functionname)) {
 | 
        
           |  |  | 1073 |                 $return = $functionname($course, $cm, $glossary, $entry,$mode,$hook,$printicons);
 | 
        
           |  |  | 1074 |             } else if ($printview) {
 | 
        
           |  |  | 1075 |                 //If the glossary_print_entry_XXXX function doesn't exist, print default (old) print format
 | 
        
           |  |  | 1076 |                 $return = glossary_print_entry_default($entry, $glossary, $cm);
 | 
        
           |  |  | 1077 |             }
 | 
        
           |  |  | 1078 |         }
 | 
        
           |  |  | 1079 |     }
 | 
        
           |  |  | 1080 |     return $return;
 | 
        
           |  |  | 1081 | }
 | 
        
           |  |  | 1082 |   | 
        
           |  |  | 1083 | /**
 | 
        
           |  |  | 1084 |  * Default (old) print format used if custom function doesn't exist in format
 | 
        
           |  |  | 1085 |  *
 | 
        
           |  |  | 1086 |  * @param object $entry
 | 
        
           |  |  | 1087 |  * @param object $glossary
 | 
        
           |  |  | 1088 |  * @param object $cm
 | 
        
           |  |  | 1089 |  * @return void Output is echo'd
 | 
        
           |  |  | 1090 |  */
 | 
        
           |  |  | 1091 | function glossary_print_entry_default ($entry, $glossary, $cm) {
 | 
        
           |  |  | 1092 |     global $CFG;
 | 
        
           |  |  | 1093 |   | 
        
           |  |  | 1094 |     require_once($CFG->libdir . '/filelib.php');
 | 
        
           |  |  | 1095 |   | 
        
           |  |  | 1096 |     echo $OUTPUT->heading(strip_tags($entry->concept), 4);
 | 
        
           |  |  | 1097 |   | 
        
           |  |  | 1098 |     $definition = $entry->definition;
 | 
        
           |  |  | 1099 |   | 
        
           |  |  | 1100 |     $definition = '<span class="nolink">' . strip_tags($definition) . '</span>';
 | 
        
           |  |  | 1101 |   | 
        
           |  |  | 1102 |     $context = context_module::instance($cm->id);
 | 
        
           |  |  | 1103 |     $definition = file_rewrite_pluginfile_urls($definition, 'pluginfile.php', $context->id, 'mod_glossary', 'entry', $entry->id);
 | 
        
           |  |  | 1104 |   | 
        
           |  |  | 1105 |     $options = new stdClass();
 | 
        
           |  |  | 1106 |     $options->para = false;
 | 
        
           |  |  | 1107 |     $options->trusted = $entry->definitiontrust;
 | 
        
           |  |  | 1108 |     $options->context = $context;
 | 
        
           |  |  | 1109 |     $options->overflowdiv = true;
 | 
        
           |  |  | 1110 |     $definition = format_text($definition, $entry->definitionformat, $options);
 | 
        
           |  |  | 1111 |     echo ($definition);
 | 
        
           |  |  | 1112 |     echo '<br /><br />';
 | 
        
           |  |  | 1113 | }
 | 
        
           |  |  | 1114 |   | 
        
           |  |  | 1115 | /**
 | 
        
           |  |  | 1116 |  * Print glossary concept/term as a heading <h4>
 | 
        
           |  |  | 1117 |  * @param object $entry
 | 
        
           |  |  | 1118 |  */
 | 
        
           |  |  | 1119 | function  glossary_print_entry_concept($entry, $return=false) {
 | 
        
           |  |  | 1120 |     global $OUTPUT;
 | 
        
           |  |  | 1121 |   | 
        
           |  |  | 1122 |     $text = $OUTPUT->heading(format_string($entry->concept), 4);
 | 
        
           |  |  | 1123 |     if (!empty($entry->highlight)) {
 | 
        
           |  |  | 1124 |         $text = highlight($entry->highlight, $text);
 | 
        
           |  |  | 1125 |     }
 | 
        
           |  |  | 1126 |   | 
        
           |  |  | 1127 |     if ($return) {
 | 
        
           |  |  | 1128 |         return $text;
 | 
        
           |  |  | 1129 |     } else {
 | 
        
           |  |  | 1130 |         echo $text;
 | 
        
           |  |  | 1131 |     }
 | 
        
           |  |  | 1132 | }
 | 
        
           |  |  | 1133 |   | 
        
           |  |  | 1134 | /**
 | 
        
           |  |  | 1135 |  *
 | 
        
           |  |  | 1136 |  * @global moodle_database DB
 | 
        
           |  |  | 1137 |  * @param object $entry
 | 
        
           |  |  | 1138 |  * @param object $glossary
 | 
        
           |  |  | 1139 |  * @param object $cm
 | 
        
           |  |  | 1140 |  */
 | 
        
           |  |  | 1141 | function glossary_print_entry_definition($entry, $glossary, $cm) {
 | 
        
           |  |  | 1142 |     global $GLOSSARY_EXCLUDEENTRY;
 | 
        
           |  |  | 1143 |   | 
        
           |  |  | 1144 |     $definition = $entry->definition;
 | 
        
           |  |  | 1145 |   | 
        
           |  |  | 1146 |     // Do not link self.
 | 
        
           |  |  | 1147 |     $GLOSSARY_EXCLUDEENTRY = $entry->id;
 | 
        
           |  |  | 1148 |   | 
        
           |  |  | 1149 |     $context = context_module::instance($cm->id);
 | 
        
           |  |  | 1150 |     $definition = file_rewrite_pluginfile_urls($definition, 'pluginfile.php', $context->id, 'mod_glossary', 'entry', $entry->id);
 | 
        
           |  |  | 1151 |   | 
        
           |  |  | 1152 |     $options = new stdClass();
 | 
        
           |  |  | 1153 |     $options->para = false;
 | 
        
           |  |  | 1154 |     $options->trusted = $entry->definitiontrust;
 | 
        
           |  |  | 1155 |     $options->context = $context;
 | 
        
           |  |  | 1156 |     $options->overflowdiv = true;
 | 
        
           |  |  | 1157 |   | 
        
           |  |  | 1158 |     $text = format_text($definition, $entry->definitionformat, $options);
 | 
        
           |  |  | 1159 |   | 
        
           |  |  | 1160 |     // Stop excluding concepts from autolinking
 | 
        
           |  |  | 1161 |     unset($GLOSSARY_EXCLUDEENTRY);
 | 
        
           |  |  | 1162 |   | 
        
           |  |  | 1163 |     if (!empty($entry->highlight)) {
 | 
        
           |  |  | 1164 |         $text = highlight($entry->highlight, $text);
 | 
        
           |  |  | 1165 |     }
 | 
        
           |  |  | 1166 |     if (isset($entry->footer)) {   // Unparsed footer info
 | 
        
           |  |  | 1167 |         $text .= $entry->footer;
 | 
        
           |  |  | 1168 |     }
 | 
        
           |  |  | 1169 |     echo $text;
 | 
        
           |  |  | 1170 | }
 | 
        
           |  |  | 1171 |   | 
        
           |  |  | 1172 | /**
 | 
        
           |  |  | 1173 |  *
 | 
        
           |  |  | 1174 |  * @global object
 | 
        
           |  |  | 1175 |  * @param object $course
 | 
        
           |  |  | 1176 |  * @param object $cm
 | 
        
           |  |  | 1177 |  * @param object $glossary
 | 
        
           |  |  | 1178 |  * @param object $entry
 | 
        
           |  |  | 1179 |  * @param string $mode
 | 
        
           |  |  | 1180 |  * @param string $hook
 | 
        
           |  |  | 1181 |  * @param string $type
 | 
        
           |  |  | 1182 |  * @return string|void
 | 
        
           |  |  | 1183 |  */
 | 
        
           |  |  | 1184 | function  glossary_print_entry_aliases($course, $cm, $glossary, $entry,$mode='',$hook='', $type = 'print') {
 | 
        
           |  |  | 1185 |     global $DB;
 | 
        
           |  |  | 1186 |   | 
        
           |  |  | 1187 |     $return = '';
 | 
        
           |  |  | 1188 |     if ($aliases = $DB->get_fieldset_select('glossary_alias', 'alias', 'entryid = :entryid', ['entryid' => $entry->id])) {
 | 
        
           |  |  | 1189 |         $id = "keyword-{$entry->id}";
 | 
        
           |  |  | 1190 |         $return = html_writer::select($aliases, $id, '', false, ['id' => $id]);
 | 
        
           |  |  | 1191 |     }
 | 
        
           |  |  | 1192 |     if ($type == 'print') {
 | 
        
           |  |  | 1193 |         echo $return;
 | 
        
           |  |  | 1194 |     } else {
 | 
        
           |  |  | 1195 |         return $return;
 | 
        
           |  |  | 1196 |     }
 | 
        
           |  |  | 1197 | }
 | 
        
           |  |  | 1198 |   | 
        
           |  |  | 1199 | /**
 | 
        
           |  |  | 1200 |  *
 | 
        
           |  |  | 1201 |  * @global object
 | 
        
           |  |  | 1202 |  * @global object
 | 
        
           |  |  | 1203 |  * @global object
 | 
        
           |  |  | 1204 |  * @param object $course
 | 
        
           |  |  | 1205 |  * @param object $cm
 | 
        
           |  |  | 1206 |  * @param object $glossary
 | 
        
           |  |  | 1207 |  * @param object $entry
 | 
        
           |  |  | 1208 |  * @param string $mode
 | 
        
           |  |  | 1209 |  * @param string $hook
 | 
        
           |  |  | 1210 |  * @param string $type
 | 
        
           |  |  | 1211 |  * @return string|void
 | 
        
           |  |  | 1212 |  */
 | 
        
           |  |  | 1213 | function glossary_print_entry_icons($course, $cm, $glossary, $entry, $mode='',$hook='', $type = 'print') {
 | 
        
           |  |  | 1214 |     global $USER, $CFG, $DB, $OUTPUT;
 | 
        
           |  |  | 1215 |   | 
        
           |  |  | 1216 |     $context = context_module::instance($cm->id);
 | 
        
           |  |  | 1217 |   | 
        
           |  |  | 1218 |     $output = false;   // To decide if we must really return text in "return". Activate when needed only!
 | 
        
           |  |  | 1219 |     $importedentry = ($entry->sourceglossaryid == $glossary->id);
 | 
        
           |  |  | 1220 |     $ismainglossary = $glossary->mainglossary;
 | 
        
           |  |  | 1221 |   | 
        
           |  |  | 1222 |     $return = '<span class="commands">';
 | 
        
           |  |  | 1223 |     // Differentiate links for each entry.
 | 
        
           |  |  | 1224 |     $altsuffix = strip_tags(format_text($entry->concept));
 | 
        
           |  |  | 1225 |   | 
        
           |  |  | 1226 |     if (!$entry->approved) {
 | 
        
           |  |  | 1227 |         $output = true;
 | 
        
           |  |  | 1228 |         $return .= html_writer::tag('span', get_string('entryishidden','glossary'),
 | 
        
           |  |  | 1229 |             array('class' => 'glossary-hidden-note'));
 | 
        
           |  |  | 1230 |     }
 | 
        
           |  |  | 1231 |   | 
        
           |  |  | 1232 |     if ($entry->approved || has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 1233 |         $output = true;
 | 
        
           |  |  | 1234 |         $return .= \html_writer::link(
 | 
        
           |  |  | 1235 |             new \moodle_url('/mod/glossary/showentry.php', ['eid' => $entry->id]),
 | 
        
           |  |  | 1236 |             $OUTPUT->pix_icon('fp/link', get_string('entrylink', 'glossary', $altsuffix), 'theme'),
 | 
        
           |  |  | 1237 |             ['title' => get_string('entrylink', 'glossary', $altsuffix), 'class' => 'icon']
 | 
        
           |  |  | 1238 |         );
 | 
        
           |  |  | 1239 |     }
 | 
        
           |  |  | 1240 |   | 
        
           |  |  | 1241 |     if (has_capability('mod/glossary:approve', $context) && !$glossary->defaultapproval && $entry->approved) {
 | 
        
           |  |  | 1242 |         $output = true;
 | 
        
           |  |  | 1243 |         $return .= '<a class="icon" title="' . get_string('disapprove', 'glossary').
 | 
        
           |  |  | 1244 |                    '" href="approve.php?newstate=0&eid='.$entry->id.'&mode='.$mode.
 | 
        
           |  |  | 1245 |                    '&hook='.urlencode($hook).'&sesskey='.sesskey().
 | 
        
           |  |  | 1246 |                    '">' . $OUTPUT->pix_icon('t/block', get_string('disapprove', 'glossary')) . '</a>';
 | 
        
           |  |  | 1247 |     }
 | 
        
           |  |  | 1248 |   | 
        
           |  |  | 1249 |     $iscurrentuser = ($entry->userid == $USER->id);
 | 
        
           |  |  | 1250 |   | 
        
           |  |  | 1251 |     if (has_capability('mod/glossary:manageentries', $context) or (isloggedin() and has_capability('mod/glossary:write', $context) and $iscurrentuser)) {
 | 
        
           |  |  | 1252 |         // only teachers can export entries so check it out
 | 
        
           |  |  | 1253 |         if (has_capability('mod/glossary:export', $context) and !$ismainglossary and !$importedentry) {
 | 
        
           |  |  | 1254 |             $mainglossary = $DB->get_record('glossary', array('mainglossary'=>1,'course'=>$course->id));
 | 
        
           |  |  | 1255 |             if ( $mainglossary ) {  // if there is a main glossary defined, allow to export the current entry
 | 
        
           |  |  | 1256 |                 $output = true;
 | 
        
           |  |  | 1257 |                 $return .= '<a class="icon" title="'.get_string('exporttomainglossary','glossary') . '" ' .
 | 
        
           |  |  | 1258 |                     'href="exportentry.php?id='.$entry->id.'&prevmode='.$mode.'&hook='.urlencode($hook).'">' .
 | 
        
           |  |  | 1259 |                     $OUTPUT->pix_icon('export', get_string('exporttomainglossary', 'glossary'), 'glossary') . '</a>';
 | 
        
           |  |  | 1260 |             }
 | 
        
           |  |  | 1261 |         }
 | 
        
           |  |  | 1262 |   | 
        
           |  |  | 1263 |         $icon = 't/delete';
 | 
        
           |  |  | 1264 |         $iconcomponent = 'moodle';
 | 
        
           |  |  | 1265 |         if ( $entry->sourceglossaryid ) {
 | 
        
           |  |  | 1266 |             $icon = 'minus';   // graphical metaphor (minus) for deleting an imported entry
 | 
        
           |  |  | 1267 |             $iconcomponent = 'glossary';
 | 
        
           |  |  | 1268 |         }
 | 
        
           |  |  | 1269 |   | 
        
           |  |  | 1270 |         //Decide if an entry is editable:
 | 
        
           |  |  | 1271 |         // -It isn't a imported entry (so nobody can edit a imported (from secondary to main) entry)) and
 | 
        
           |  |  | 1272 |         // -The user is teacher or he is a student with time permissions (edit period or editalways defined).
 | 
        
           |  |  | 1273 |         $ineditperiod = ((time() - $entry->timecreated <  $CFG->maxeditingtime) || $glossary->editalways);
 | 
        
           |  |  | 1274 |         if ( !$importedentry and (has_capability('mod/glossary:manageentries', $context) or ($entry->userid == $USER->id and ($ineditperiod and has_capability('mod/glossary:write', $context))))) {
 | 
        
           |  |  | 1275 |             $output = true;
 | 
        
           |  |  | 1276 |             $url = "deleteentry.php?id=$cm->id&mode=delete&entry=$entry->id&prevmode=$mode&hook=".urlencode($hook);
 | 
        
           |  |  | 1277 |             $return .= "<a class='icon' title=\"" . get_string("delete") . "\" " .
 | 
        
           |  |  | 1278 |                        "href=\"$url\">" . $OUTPUT->pix_icon($icon, get_string('deleteentrya', 'mod_glossary', $altsuffix), $iconcomponent) . '</a>';
 | 
        
           |  |  | 1279 |   | 
        
           |  |  | 1280 |             $url = "edit.php?cmid=$cm->id&id=$entry->id&mode=$mode&hook=".urlencode($hook);
 | 
        
           |  |  | 1281 |             $return .= "<a class='icon' title=\"" . get_string("edit") . "\" href=\"$url\">" .
 | 
        
           |  |  | 1282 |                        $OUTPUT->pix_icon('i/edit', get_string('editentrya', 'mod_glossary', $altsuffix)) . '</a>';
 | 
        
           |  |  | 1283 |         } elseif ( $importedentry ) {
 | 
        
           |  |  | 1284 |             $return .= "<font size=\"-1\">" . get_string("exportedentry","glossary") . "</font>";
 | 
        
           |  |  | 1285 |         }
 | 
        
           |  |  | 1286 |     }
 | 
        
           |  |  | 1287 |     if (!empty($CFG->enableportfolios) && (has_capability('mod/glossary:exportentry', $context) || ($iscurrentuser && has_capability('mod/glossary:exportownentry', $context)))) {
 | 
        
           |  |  | 1288 |         require_once($CFG->libdir . '/portfoliolib.php');
 | 
        
           |  |  | 1289 |         $button = new portfolio_add_button();
 | 
        
           |  |  | 1290 |         $button->set_callback_options('glossary_entry_portfolio_caller',  array('id' => $cm->id, 'entryid' => $entry->id), 'mod_glossary');
 | 
        
           |  |  | 1291 |   | 
        
           |  |  | 1292 |         $filecontext = $context;
 | 
        
           |  |  | 1293 |         if ($entry->sourceglossaryid == $cm->instance) {
 | 
        
           |  |  | 1294 |             if ($maincm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) {
 | 
        
           |  |  | 1295 |                 $filecontext = context_module::instance($maincm->id);
 | 
        
           |  |  | 1296 |             }
 | 
        
           |  |  | 1297 |         }
 | 
        
           |  |  | 1298 |         $fs = get_file_storage();
 | 
        
           |  |  | 1299 |         if ($files = $fs->get_area_files($filecontext->id, 'mod_glossary', 'attachment', $entry->id, "timemodified", false)
 | 
        
           |  |  | 1300 |          || $files = $fs->get_area_files($filecontext->id, 'mod_glossary', 'entry', $entry->id, "timemodified", false)) {
 | 
        
           |  |  | 1301 |   | 
        
           |  |  | 1302 |             $button->set_formats(PORTFOLIO_FORMAT_RICHHTML);
 | 
        
           |  |  | 1303 |         } else {
 | 
        
           |  |  | 1304 |             $button->set_formats(PORTFOLIO_FORMAT_PLAINHTML);
 | 
        
           |  |  | 1305 |         }
 | 
        
           |  |  | 1306 |   | 
        
           |  |  | 1307 |         $return .= $button->to_html(PORTFOLIO_ADD_ICON_LINK);
 | 
        
           |  |  | 1308 |     }
 | 
        
           |  |  | 1309 |     $return .= '</span>';
 | 
        
           |  |  | 1310 |   | 
        
           |  |  | 1311 |     if (!empty($CFG->usecomments) && has_capability('mod/glossary:comment', $context) and $glossary->allowcomments) {
 | 
        
           |  |  | 1312 |         require_once($CFG->dirroot . '/comment/lib.php');
 | 
        
           |  |  | 1313 |         $cmt = new stdClass();
 | 
        
           |  |  | 1314 |         $cmt->component = 'mod_glossary';
 | 
        
           |  |  | 1315 |         $cmt->context  = $context;
 | 
        
           |  |  | 1316 |         $cmt->course   = $course;
 | 
        
           |  |  | 1317 |         $cmt->cm       = $cm;
 | 
        
           |  |  | 1318 |         $cmt->area     = 'glossary_entry';
 | 
        
           |  |  | 1319 |         $cmt->itemid   = $entry->id;
 | 
        
           |  |  | 1320 |         $cmt->showcount = true;
 | 
        
           |  |  | 1321 |         $comment = new comment($cmt);
 | 
        
           |  |  | 1322 |         $return .= '<div>'.$comment->output(true).'</div>';
 | 
        
           |  |  | 1323 |         $output = true;
 | 
        
           |  |  | 1324 |     }
 | 
        
           |  |  | 1325 |   | 
        
           |  |  | 1326 |     //If we haven't calculated any REAL thing, delete result ($return)
 | 
        
           |  |  | 1327 |     if (!$output) {
 | 
        
           |  |  | 1328 |         $return = '';
 | 
        
           |  |  | 1329 |     }
 | 
        
           |  |  | 1330 |     //Print or get
 | 
        
           |  |  | 1331 |     if ($type == 'print') {
 | 
        
           |  |  | 1332 |         echo $return;
 | 
        
           |  |  | 1333 |     } else {
 | 
        
           |  |  | 1334 |         return $return;
 | 
        
           |  |  | 1335 |     }
 | 
        
           |  |  | 1336 | }
 | 
        
           |  |  | 1337 |   | 
        
           |  |  | 1338 | /**
 | 
        
           |  |  | 1339 |  * @param object $course
 | 
        
           |  |  | 1340 |  * @param object $cm
 | 
        
           |  |  | 1341 |  * @param object $glossary
 | 
        
           |  |  | 1342 |  * @param object $entry
 | 
        
           |  |  | 1343 |  * @param string $mode
 | 
        
           |  |  | 1344 |  * @param object $hook
 | 
        
           |  |  | 1345 |  * @param bool $printicons
 | 
        
           |  |  | 1346 |  * @param bool $aliases
 | 
        
           |  |  | 1347 |  * @param bool $printseparator Whether to print a thematic break (separator) at the end of the lower section.
 | 
        
           |  |  | 1348 |  * @return void
 | 
        
           |  |  | 1349 |  */
 | 
        
           |  |  | 1350 | function glossary_print_entry_lower_section($course, $cm, $glossary, $entry, $mode, $hook, $printicons, $aliases = true,
 | 
        
           |  |  | 1351 |         $printseparator = true) {
 | 
        
           |  |  | 1352 |     if ($aliases) {
 | 
        
           |  |  | 1353 |         $aliases = glossary_print_entry_aliases($course, $cm, $glossary, $entry, $mode, $hook,'html');
 | 
        
           |  |  | 1354 |     }
 | 
        
           |  |  | 1355 |     $icons   = '';
 | 
        
           |  |  | 1356 |     if ($printicons) {
 | 
        
           |  |  | 1357 |         $icons   = glossary_print_entry_icons($course, $cm, $glossary, $entry, $mode, $hook,'html');
 | 
        
           |  |  | 1358 |     }
 | 
        
           |  |  | 1359 |     if ($aliases || $icons || !empty($entry->rating)) {
 | 
        
           | 1441 | ariadna | 1360 |         echo '<table class="table-reboot">';
 | 
        
           | 1 | efrain | 1361 |         if ( $aliases ) {
 | 
        
           |  |  | 1362 |             $id = "keyword-{$entry->id}";
 | 
        
           | 1441 | ariadna | 1363 |             echo '<tr valign="top"><td class="aliases hstack gap-2">' .
 | 
        
           | 1 | efrain | 1364 |                 '<label for="' . $id . '">' . get_string('aliases', 'glossary') . ': </label>' .
 | 
        
           |  |  | 1365 |                 $aliases . '</td></tr>';
 | 
        
           |  |  | 1366 |         }
 | 
        
           |  |  | 1367 |         if ($icons) {
 | 
        
           |  |  | 1368 |             echo '<tr valign="top"><td class="icons">'.$icons.'</td></tr>';
 | 
        
           |  |  | 1369 |         }
 | 
        
           |  |  | 1370 |         if (!empty($entry->rating)) {
 | 
        
           |  |  | 1371 |             echo '<tr valign="top"><td class="ratings pt-3">';
 | 
        
           |  |  | 1372 |             glossary_print_entry_ratings($course, $entry);
 | 
        
           |  |  | 1373 |             echo '</td></tr>';
 | 
        
           |  |  | 1374 |         }
 | 
        
           |  |  | 1375 |         echo '</table>';
 | 
        
           |  |  | 1376 |   | 
        
           |  |  | 1377 |         if ($printseparator) {
 | 
        
           |  |  | 1378 |             echo "<hr>\n";
 | 
        
           |  |  | 1379 |         }
 | 
        
           |  |  | 1380 |     }
 | 
        
           |  |  | 1381 | }
 | 
        
           |  |  | 1382 |   | 
        
           |  |  | 1383 | /**
 | 
        
           |  |  | 1384 |  * Print the list of attachments for this glossary entry
 | 
        
           |  |  | 1385 |  *
 | 
        
           |  |  | 1386 |  * @param object $entry
 | 
        
           |  |  | 1387 |  * @param object $cm The coursemodule
 | 
        
           |  |  | 1388 |  * @param string $format The format for this view (html, or text)
 | 
        
           |  |  | 1389 |  * @param string $unused1 This parameter is no longer used
 | 
        
           |  |  | 1390 |  * @param string $unused2 This parameter is no longer used
 | 
        
           |  |  | 1391 |  */
 | 
        
           |  |  | 1392 | function glossary_print_entry_attachment($entry, $cm, $format = null, $unused1 = null, $unused2 = null) {
 | 
        
           |  |  | 1393 |     // Valid format values: html: The HTML link for the attachment is an icon; and
 | 
        
           |  |  | 1394 |     //                      text: The HTML link for the attachment is text.
 | 
        
           |  |  | 1395 |     if ($entry->attachment) {
 | 
        
           |  |  | 1396 |         echo '<div class="attachments">';
 | 
        
           |  |  | 1397 |         echo glossary_print_attachments($entry, $cm, $format);
 | 
        
           |  |  | 1398 |         echo '</div>';
 | 
        
           |  |  | 1399 |     }
 | 
        
           |  |  | 1400 |     if ($unused1) {
 | 
        
           |  |  | 1401 |         debugging('The align parameter is deprecated, please use appropriate CSS instead', DEBUG_DEVELOPER);
 | 
        
           |  |  | 1402 |     }
 | 
        
           |  |  | 1403 |     if ($unused2 !== null) {
 | 
        
           |  |  | 1404 |         debugging('The insidetable parameter is deprecated, please use appropriate CSS instead', DEBUG_DEVELOPER);
 | 
        
           |  |  | 1405 |     }
 | 
        
           |  |  | 1406 | }
 | 
        
           |  |  | 1407 |   | 
        
           |  |  | 1408 | /**
 | 
        
           |  |  | 1409 |  * @global object
 | 
        
           |  |  | 1410 |  * @param object $cm
 | 
        
           |  |  | 1411 |  * @param object $entry
 | 
        
           |  |  | 1412 |  * @param string $mode
 | 
        
           |  |  | 1413 |  * @param string $align
 | 
        
           |  |  | 1414 |  * @param bool $insidetable
 | 
        
           |  |  | 1415 |  */
 | 
        
           |  |  | 1416 | function  glossary_print_entry_approval($cm, $entry, $mode, $align="right", $insidetable=true) {
 | 
        
           |  |  | 1417 |     global $CFG, $OUTPUT;
 | 
        
           |  |  | 1418 |   | 
        
           |  |  | 1419 |     if ($mode == 'approval' and !$entry->approved) {
 | 
        
           |  |  | 1420 |         if ($insidetable) {
 | 
        
           | 1441 | ariadna | 1421 |             echo '<table class="glossaryapproval table-reboot" align="' . $align . '"><tr><td align="' . $align . '">';
 | 
        
           | 1 | efrain | 1422 |         }
 | 
        
           |  |  | 1423 |         echo $OUTPUT->action_icon(
 | 
        
           |  |  | 1424 |             new moodle_url('approve.php', array('eid' => $entry->id, 'mode' => $mode, 'sesskey' => sesskey())),
 | 
        
           |  |  | 1425 |             new pix_icon('t/approve', get_string('approve','glossary'), '',
 | 
        
           |  |  | 1426 |                 array('class' => 'iconsmall', 'align' => $align))
 | 
        
           |  |  | 1427 |         );
 | 
        
           |  |  | 1428 |         if ($insidetable) {
 | 
        
           |  |  | 1429 |             echo '</td></tr></table>';
 | 
        
           |  |  | 1430 |         }
 | 
        
           |  |  | 1431 |     }
 | 
        
           |  |  | 1432 | }
 | 
        
           |  |  | 1433 |   | 
        
           |  |  | 1434 | /**
 | 
        
           |  |  | 1435 |  * It returns all entries from all glossaries that matches the specified criteria
 | 
        
           |  |  | 1436 |  *  within a given $course. It performs an $extended search if necessary.
 | 
        
           |  |  | 1437 |  * It restrict the search to only one $glossary if the $glossary parameter is set.
 | 
        
           |  |  | 1438 |  *
 | 
        
           |  |  | 1439 |  * @global object
 | 
        
           |  |  | 1440 |  * @global object
 | 
        
           |  |  | 1441 |  * @param object $course
 | 
        
           |  |  | 1442 |  * @param array $searchterms
 | 
        
           |  |  | 1443 |  * @param int $extended
 | 
        
           |  |  | 1444 |  * @param object $glossary
 | 
        
           |  |  | 1445 |  * @return array
 | 
        
           |  |  | 1446 |  */
 | 
        
           |  |  | 1447 | function glossary_search($course, $searchterms, $extended = 0, $glossary = NULL) {
 | 
        
           |  |  | 1448 |     global $CFG, $DB;
 | 
        
           |  |  | 1449 |   | 
        
           |  |  | 1450 |     if ( !$glossary ) {
 | 
        
           |  |  | 1451 |         if ( $glossaries = $DB->get_records("glossary", array("course"=>$course->id)) ) {
 | 
        
           |  |  | 1452 |             $glos = "";
 | 
        
           |  |  | 1453 |             foreach ( $glossaries as $glossary ) {
 | 
        
           |  |  | 1454 |                 $glos .= "$glossary->id,";
 | 
        
           |  |  | 1455 |             }
 | 
        
           |  |  | 1456 |             $glos = substr($glos,0,-1);
 | 
        
           |  |  | 1457 |         }
 | 
        
           |  |  | 1458 |     } else {
 | 
        
           |  |  | 1459 |         $glos = $glossary->id;
 | 
        
           |  |  | 1460 |     }
 | 
        
           |  |  | 1461 |   | 
        
           |  |  | 1462 |     if (!has_capability('mod/glossary:manageentries', context_course::instance($glossary->course))) {
 | 
        
           |  |  | 1463 |         $glossarymodule = $DB->get_record("modules", array("name"=>"glossary"));
 | 
        
           |  |  | 1464 |         $onlyvisible = " AND g.id = cm.instance AND cm.visible = 1 AND cm.module = $glossarymodule->id";
 | 
        
           |  |  | 1465 |         $onlyvisibletable = ", {course_modules} cm";
 | 
        
           |  |  | 1466 |     } else {
 | 
        
           |  |  | 1467 |   | 
        
           |  |  | 1468 |         $onlyvisible = "";
 | 
        
           |  |  | 1469 |         $onlyvisibletable = "";
 | 
        
           |  |  | 1470 |     }
 | 
        
           |  |  | 1471 |   | 
        
           |  |  | 1472 |     if ($DB->sql_regex_supported()) {
 | 
        
           |  |  | 1473 |         $REGEXP    = $DB->sql_regex(true);
 | 
        
           |  |  | 1474 |         $NOTREGEXP = $DB->sql_regex(false);
 | 
        
           |  |  | 1475 |     }
 | 
        
           |  |  | 1476 |   | 
        
           |  |  | 1477 |     $searchcond = array();
 | 
        
           |  |  | 1478 |     $params     = array();
 | 
        
           |  |  | 1479 |     $i = 0;
 | 
        
           |  |  | 1480 |   | 
        
           |  |  | 1481 |     $concat = $DB->sql_concat('e.concept', "' '", 'e.definition');
 | 
        
           |  |  | 1482 |   | 
        
           |  |  | 1483 |   | 
        
           |  |  | 1484 |     foreach ($searchterms as $searchterm) {
 | 
        
           |  |  | 1485 |         $i++;
 | 
        
           |  |  | 1486 |   | 
        
           | 1441 | ariadna | 1487 |         // Initially we aren't going to perform NOT LIKE searches, only MSSQL
 | 
        
           |  |  | 1488 |         // will use it to simulate the "-" operator with LIKE clause.
 | 
        
           |  |  | 1489 |         $NOT = false;
 | 
        
           | 1 | efrain | 1490 |   | 
        
           | 1441 | ariadna | 1491 |         // Under MSSQL, trim the + and - operators and perform
 | 
        
           |  |  | 1492 |         // simpler LIKE (or NOT LIKE) queries
 | 
        
           | 1 | efrain | 1493 |         if (!$DB->sql_regex_supported()) {
 | 
        
           |  |  | 1494 |             if (substr($searchterm, 0, 1) == '-') {
 | 
        
           |  |  | 1495 |                 $NOT = true;
 | 
        
           |  |  | 1496 |             }
 | 
        
           |  |  | 1497 |             $searchterm = trim($searchterm, '+-');
 | 
        
           |  |  | 1498 |         }
 | 
        
           |  |  | 1499 |   | 
        
           |  |  | 1500 |         // TODO: +- may not work for non latin languages
 | 
        
           |  |  | 1501 |   | 
        
           |  |  | 1502 |         if (substr($searchterm,0,1) == '+') {
 | 
        
           |  |  | 1503 |             $searchterm = trim($searchterm, '+-');
 | 
        
           |  |  | 1504 |             $searchterm = preg_quote($searchterm, '|');
 | 
        
           |  |  | 1505 |             $searchcond[] = "$concat $REGEXP :ss$i";
 | 
        
           |  |  | 1506 |             $params['ss'.$i] = "(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)";
 | 
        
           |  |  | 1507 |   | 
        
           |  |  | 1508 |         } else if (substr($searchterm,0,1) == "-") {
 | 
        
           |  |  | 1509 |             $searchterm = trim($searchterm, '+-');
 | 
        
           |  |  | 1510 |             $searchterm = preg_quote($searchterm, '|');
 | 
        
           |  |  | 1511 |             $searchcond[] = "$concat $NOTREGEXP :ss$i";
 | 
        
           |  |  | 1512 |             $params['ss'.$i] = "(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)";
 | 
        
           |  |  | 1513 |   | 
        
           |  |  | 1514 |         } else {
 | 
        
           |  |  | 1515 |             $searchcond[] = $DB->sql_like($concat, ":ss$i", false, true, $NOT);
 | 
        
           |  |  | 1516 |             $params['ss'.$i] = "%$searchterm%";
 | 
        
           |  |  | 1517 |         }
 | 
        
           |  |  | 1518 |     }
 | 
        
           |  |  | 1519 |   | 
        
           |  |  | 1520 |     if (empty($searchcond)) {
 | 
        
           |  |  | 1521 |         $totalcount = 0;
 | 
        
           |  |  | 1522 |         return array();
 | 
        
           |  |  | 1523 |     }
 | 
        
           |  |  | 1524 |   | 
        
           |  |  | 1525 |     $searchcond = implode(" AND ", $searchcond);
 | 
        
           |  |  | 1526 |   | 
        
           |  |  | 1527 |     $sql = "SELECT e.*
 | 
        
           |  |  | 1528 |               FROM {glossary_entries} e, {glossary} g $onlyvisibletable
 | 
        
           |  |  | 1529 |              WHERE $searchcond
 | 
        
           |  |  | 1530 |                AND (e.glossaryid = g.id or e.sourceglossaryid = g.id) $onlyvisible
 | 
        
           |  |  | 1531 |                AND g.id IN ($glos) AND e.approved <> 0";
 | 
        
           |  |  | 1532 |   | 
        
           |  |  | 1533 |     return $DB->get_records_sql($sql, $params);
 | 
        
           |  |  | 1534 | }
 | 
        
           |  |  | 1535 |   | 
        
           |  |  | 1536 | /**
 | 
        
           |  |  | 1537 |  * @global object
 | 
        
           |  |  | 1538 |  * @param array $searchterms
 | 
        
           |  |  | 1539 |  * @param object $glossary
 | 
        
           |  |  | 1540 |  * @param bool $extended
 | 
        
           |  |  | 1541 |  * @return array
 | 
        
           |  |  | 1542 |  */
 | 
        
           |  |  | 1543 | function glossary_search_entries($searchterms, $glossary, $extended) {
 | 
        
           |  |  | 1544 |     global $DB;
 | 
        
           |  |  | 1545 |   | 
        
           |  |  | 1546 |     $course = $DB->get_record("course", array("id"=>$glossary->course));
 | 
        
           |  |  | 1547 |     return glossary_search($course,$searchterms,$extended,$glossary);
 | 
        
           |  |  | 1548 | }
 | 
        
           |  |  | 1549 |   | 
        
           |  |  | 1550 | /**
 | 
        
           |  |  | 1551 |  * if return=html, then return a html string.
 | 
        
           |  |  | 1552 |  * if return=text, then return a text-only string.
 | 
        
           |  |  | 1553 |  * otherwise, print HTML for non-images, and return image HTML
 | 
        
           |  |  | 1554 |  *     if attachment is an image, $align set its aligment.
 | 
        
           |  |  | 1555 |  *
 | 
        
           |  |  | 1556 |  * @global object
 | 
        
           |  |  | 1557 |  * @global object
 | 
        
           |  |  | 1558 |  * @param object $entry
 | 
        
           |  |  | 1559 |  * @param object $cm
 | 
        
           |  |  | 1560 |  * @param string $type html, txt, empty
 | 
        
           |  |  | 1561 |  * @param string $unused This parameter is no longer used
 | 
        
           |  |  | 1562 |  * @return string image string or nothing depending on $type param
 | 
        
           |  |  | 1563 |  */
 | 
        
           |  |  | 1564 | function glossary_print_attachments($entry, $cm, $type=NULL, $unused = null) {
 | 
        
           |  |  | 1565 |     global $CFG, $DB, $OUTPUT;
 | 
        
           |  |  | 1566 |   | 
        
           |  |  | 1567 |     if (!$context = context_module::instance($cm->id, IGNORE_MISSING)) {
 | 
        
           |  |  | 1568 |         return '';
 | 
        
           |  |  | 1569 |     }
 | 
        
           |  |  | 1570 |   | 
        
           |  |  | 1571 |     if ($entry->sourceglossaryid == $cm->instance) {
 | 
        
           |  |  | 1572 |         if (!$maincm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) {
 | 
        
           |  |  | 1573 |             return '';
 | 
        
           |  |  | 1574 |         }
 | 
        
           |  |  | 1575 |         $filecontext = context_module::instance($maincm->id);
 | 
        
           |  |  | 1576 |   | 
        
           |  |  | 1577 |     } else {
 | 
        
           |  |  | 1578 |         $filecontext = $context;
 | 
        
           |  |  | 1579 |     }
 | 
        
           |  |  | 1580 |   | 
        
           |  |  | 1581 |     $strattachment = get_string('attachment', 'glossary');
 | 
        
           |  |  | 1582 |   | 
        
           |  |  | 1583 |     $fs = get_file_storage();
 | 
        
           |  |  | 1584 |   | 
        
           |  |  | 1585 |     $imagereturn = '';
 | 
        
           |  |  | 1586 |     $output = '';
 | 
        
           |  |  | 1587 |   | 
        
           |  |  | 1588 |     if ($files = $fs->get_area_files($filecontext->id, 'mod_glossary', 'attachment', $entry->id, "timemodified", false)) {
 | 
        
           |  |  | 1589 |         foreach ($files as $file) {
 | 
        
           |  |  | 1590 |             $filename = $file->get_filename();
 | 
        
           |  |  | 1591 |             $mimetype = $file->get_mimetype();
 | 
        
           |  |  | 1592 |             $iconimage = $OUTPUT->pix_icon(file_file_icon($file), get_mimetype_description($file), 'moodle', array('class' => 'icon'));
 | 
        
           |  |  | 1593 |             $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$context->id.'/mod_glossary/attachment/'.$entry->id.'/'.$filename);
 | 
        
           |  |  | 1594 |   | 
        
           |  |  | 1595 |             if ($type == 'html') {
 | 
        
           |  |  | 1596 |                 $output .= "<a href=\"$path\">$iconimage</a> ";
 | 
        
           |  |  | 1597 |                 $output .= "<a href=\"$path\">".s($filename)."</a>";
 | 
        
           |  |  | 1598 |                 $output .= "<br />";
 | 
        
           |  |  | 1599 |   | 
        
           |  |  | 1600 |             } else if ($type == 'text') {
 | 
        
           |  |  | 1601 |                 $output .= "$strattachment ".s($filename).":\n$path\n";
 | 
        
           |  |  | 1602 |   | 
        
           |  |  | 1603 |             } else {
 | 
        
           |  |  | 1604 |                 if (in_array($mimetype, array('image/gif', 'image/jpeg', 'image/png'))) {
 | 
        
           |  |  | 1605 |                     // Image attachments don't get printed as links
 | 
        
           |  |  | 1606 |                     $imagereturn .= "<br /><img src=\"$path\" alt=\"\" />";
 | 
        
           |  |  | 1607 |                 } else {
 | 
        
           |  |  | 1608 |                     $output .= "<a href=\"$path\">$iconimage</a> ";
 | 
        
           |  |  | 1609 |                     $output .= format_text("<a href=\"$path\">".s($filename)."</a>", FORMAT_HTML, array('context'=>$context));
 | 
        
           |  |  | 1610 |                     $output .= '<br />';
 | 
        
           |  |  | 1611 |                 }
 | 
        
           |  |  | 1612 |             }
 | 
        
           |  |  | 1613 |         }
 | 
        
           |  |  | 1614 |     }
 | 
        
           |  |  | 1615 |   | 
        
           |  |  | 1616 |     if ($type) {
 | 
        
           |  |  | 1617 |         return $output;
 | 
        
           |  |  | 1618 |     } else {
 | 
        
           |  |  | 1619 |         echo $output;
 | 
        
           |  |  | 1620 |         return $imagereturn;
 | 
        
           |  |  | 1621 |     }
 | 
        
           |  |  | 1622 | }
 | 
        
           |  |  | 1623 |   | 
        
           |  |  | 1624 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 1625 | // File API                                                                   //
 | 
        
           |  |  | 1626 | ////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 1627 |   | 
        
           |  |  | 1628 | /**
 | 
        
           |  |  | 1629 |  * Lists all browsable file areas
 | 
        
           |  |  | 1630 |  *
 | 
        
           |  |  | 1631 |  * @package  mod_glossary
 | 
        
           |  |  | 1632 |  * @category files
 | 
        
           |  |  | 1633 |  * @param stdClass $course course object
 | 
        
           |  |  | 1634 |  * @param stdClass $cm course module object
 | 
        
           |  |  | 1635 |  * @param stdClass $context context object
 | 
        
           |  |  | 1636 |  * @return array
 | 
        
           |  |  | 1637 |  */
 | 
        
           |  |  | 1638 | function glossary_get_file_areas($course, $cm, $context) {
 | 
        
           |  |  | 1639 |     return array(
 | 
        
           |  |  | 1640 |         'attachment' => get_string('areaattachment', 'mod_glossary'),
 | 
        
           |  |  | 1641 |         'entry' => get_string('areaentry', 'mod_glossary'),
 | 
        
           |  |  | 1642 |     );
 | 
        
           |  |  | 1643 | }
 | 
        
           |  |  | 1644 |   | 
        
           |  |  | 1645 | /**
 | 
        
           |  |  | 1646 |  * File browsing support for glossary module.
 | 
        
           |  |  | 1647 |  *
 | 
        
           |  |  | 1648 |  * @param file_browser $browser
 | 
        
           |  |  | 1649 |  * @param array $areas
 | 
        
           |  |  | 1650 |  * @param stdClass $course
 | 
        
           |  |  | 1651 |  * @param cm_info $cm
 | 
        
           |  |  | 1652 |  * @param context $context
 | 
        
           |  |  | 1653 |  * @param string $filearea
 | 
        
           |  |  | 1654 |  * @param int $itemid
 | 
        
           |  |  | 1655 |  * @param string $filepath
 | 
        
           |  |  | 1656 |  * @param string $filename
 | 
        
           |  |  | 1657 |  * @return file_info_stored file_info_stored instance or null if not found
 | 
        
           |  |  | 1658 |  */
 | 
        
           |  |  | 1659 | function glossary_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
 | 
        
           |  |  | 1660 |     global $CFG, $DB, $USER;
 | 
        
           |  |  | 1661 |   | 
        
           |  |  | 1662 |     if ($context->contextlevel != CONTEXT_MODULE) {
 | 
        
           |  |  | 1663 |         return null;
 | 
        
           |  |  | 1664 |     }
 | 
        
           |  |  | 1665 |   | 
        
           |  |  | 1666 |     if (!isset($areas[$filearea])) {
 | 
        
           |  |  | 1667 |         return null;
 | 
        
           |  |  | 1668 |     }
 | 
        
           |  |  | 1669 |   | 
        
           |  |  | 1670 |     if (is_null($itemid)) {
 | 
        
           |  |  | 1671 |         require_once($CFG->dirroot.'/mod/glossary/locallib.php');
 | 
        
           |  |  | 1672 |         return new glossary_file_info_container($browser, $course, $cm, $context, $areas, $filearea);
 | 
        
           |  |  | 1673 |     }
 | 
        
           |  |  | 1674 |   | 
        
           |  |  | 1675 |     if (!$entry = $DB->get_record('glossary_entries', array('id' => $itemid))) {
 | 
        
           |  |  | 1676 |         return null;
 | 
        
           |  |  | 1677 |     }
 | 
        
           |  |  | 1678 |   | 
        
           |  |  | 1679 |     if (!$glossary = $DB->get_record('glossary', array('id' => $cm->instance))) {
 | 
        
           |  |  | 1680 |         return null;
 | 
        
           |  |  | 1681 |     }
 | 
        
           |  |  | 1682 |   | 
        
           |  |  | 1683 |     if ($glossary->defaultapproval and !$entry->approved and !has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 1684 |         return null;
 | 
        
           |  |  | 1685 |     }
 | 
        
           |  |  | 1686 |   | 
        
           |  |  | 1687 |     // this trickery here is because we need to support source glossary access
 | 
        
           |  |  | 1688 |     if ($entry->glossaryid == $cm->instance) {
 | 
        
           |  |  | 1689 |         $filecontext = $context;
 | 
        
           |  |  | 1690 |     } else if ($entry->sourceglossaryid == $cm->instance) {
 | 
        
           |  |  | 1691 |         if (!$maincm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) {
 | 
        
           |  |  | 1692 |             return null;
 | 
        
           |  |  | 1693 |         }
 | 
        
           |  |  | 1694 |         $filecontext = context_module::instance($maincm->id);
 | 
        
           |  |  | 1695 |     } else {
 | 
        
           |  |  | 1696 |         return null;
 | 
        
           |  |  | 1697 |     }
 | 
        
           |  |  | 1698 |   | 
        
           |  |  | 1699 |     $fs = get_file_storage();
 | 
        
           |  |  | 1700 |     $filepath = is_null($filepath) ? '/' : $filepath;
 | 
        
           |  |  | 1701 |     $filename = is_null($filename) ? '.' : $filename;
 | 
        
           |  |  | 1702 |     if (!($storedfile = $fs->get_file($filecontext->id, 'mod_glossary', $filearea, $itemid, $filepath, $filename))) {
 | 
        
           |  |  | 1703 |         return null;
 | 
        
           |  |  | 1704 |     }
 | 
        
           |  |  | 1705 |   | 
        
           |  |  | 1706 |     // Checks to see if the user can manage files or is the owner.
 | 
        
           |  |  | 1707 |     // TODO MDL-33805 - Do not use userid here and move the capability check above.
 | 
        
           |  |  | 1708 |     if (!has_capability('moodle/course:managefiles', $context) && $storedfile->get_userid() != $USER->id) {
 | 
        
           |  |  | 1709 |         return null;
 | 
        
           |  |  | 1710 |     }
 | 
        
           |  |  | 1711 |   | 
        
           |  |  | 1712 |     $urlbase = $CFG->wwwroot.'/pluginfile.php';
 | 
        
           |  |  | 1713 |   | 
        
           |  |  | 1714 |     return new file_info_stored($browser, $filecontext, $storedfile, $urlbase, s($entry->concept), true, true, false, false);
 | 
        
           |  |  | 1715 | }
 | 
        
           |  |  | 1716 |   | 
        
           |  |  | 1717 | /**
 | 
        
           |  |  | 1718 |  * Serves the glossary attachments. Implements needed access control ;-)
 | 
        
           |  |  | 1719 |  *
 | 
        
           |  |  | 1720 |  * @package  mod_glossary
 | 
        
           |  |  | 1721 |  * @category files
 | 
        
           |  |  | 1722 |  * @param stdClass $course course object
 | 
        
           |  |  | 1723 |  * @param stdClass $cm course module object
 | 
        
           |  |  | 1724 |  * @param stdClsss $context context object
 | 
        
           |  |  | 1725 |  * @param string $filearea file area
 | 
        
           |  |  | 1726 |  * @param array $args extra arguments
 | 
        
           |  |  | 1727 |  * @param bool $forcedownload whether or not force download
 | 
        
           |  |  | 1728 |  * @param array $options additional options affecting the file serving
 | 
        
           |  |  | 1729 |  * @return bool false if file not found, does not return if found - justsend the file
 | 
        
           |  |  | 1730 |  */
 | 
        
           |  |  | 1731 | function glossary_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) {
 | 
        
           |  |  | 1732 |     global $CFG, $DB;
 | 
        
           |  |  | 1733 |   | 
        
           |  |  | 1734 |     if ($context->contextlevel != CONTEXT_MODULE) {
 | 
        
           |  |  | 1735 |         return false;
 | 
        
           |  |  | 1736 |     }
 | 
        
           |  |  | 1737 |   | 
        
           |  |  | 1738 |     require_course_login($course, true, $cm);
 | 
        
           |  |  | 1739 |   | 
        
           |  |  | 1740 |     if ($filearea === 'attachment' or $filearea === 'entry') {
 | 
        
           |  |  | 1741 |         $entryid = (int)array_shift($args);
 | 
        
           |  |  | 1742 |   | 
        
           |  |  | 1743 |         require_course_login($course, true, $cm);
 | 
        
           |  |  | 1744 |   | 
        
           |  |  | 1745 |         if (!$entry = $DB->get_record('glossary_entries', array('id'=>$entryid))) {
 | 
        
           |  |  | 1746 |             return false;
 | 
        
           |  |  | 1747 |         }
 | 
        
           |  |  | 1748 |   | 
        
           |  |  | 1749 |         if (!$glossary = $DB->get_record('glossary', array('id'=>$cm->instance))) {
 | 
        
           |  |  | 1750 |             return false;
 | 
        
           |  |  | 1751 |         }
 | 
        
           |  |  | 1752 |   | 
        
           |  |  | 1753 |         if ($glossary->defaultapproval and !$entry->approved and !has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 1754 |             return false;
 | 
        
           |  |  | 1755 |         }
 | 
        
           |  |  | 1756 |   | 
        
           |  |  | 1757 |         // this trickery here is because we need to support source glossary access
 | 
        
           |  |  | 1758 |   | 
        
           |  |  | 1759 |         if ($entry->glossaryid == $cm->instance) {
 | 
        
           |  |  | 1760 |             $filecontext = $context;
 | 
        
           |  |  | 1761 |   | 
        
           |  |  | 1762 |         } else if ($entry->sourceglossaryid == $cm->instance) {
 | 
        
           |  |  | 1763 |             if (!$maincm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) {
 | 
        
           |  |  | 1764 |                 return false;
 | 
        
           |  |  | 1765 |             }
 | 
        
           |  |  | 1766 |             $filecontext = context_module::instance($maincm->id);
 | 
        
           |  |  | 1767 |   | 
        
           |  |  | 1768 |         } else {
 | 
        
           |  |  | 1769 |             return false;
 | 
        
           |  |  | 1770 |         }
 | 
        
           |  |  | 1771 |   | 
        
           |  |  | 1772 |         $relativepath = implode('/', $args);
 | 
        
           |  |  | 1773 |         $fullpath = "/$filecontext->id/mod_glossary/$filearea/$entryid/$relativepath";
 | 
        
           |  |  | 1774 |   | 
        
           |  |  | 1775 |         $fs = get_file_storage();
 | 
        
           |  |  | 1776 |         if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
 | 
        
           |  |  | 1777 |             return false;
 | 
        
           |  |  | 1778 |         }
 | 
        
           |  |  | 1779 |   | 
        
           |  |  | 1780 |         // finally send the file
 | 
        
           |  |  | 1781 |         send_stored_file($file, 0, 0, true, $options); // download MUST be forced - security!
 | 
        
           |  |  | 1782 |   | 
        
           |  |  | 1783 |     } else if ($filearea === 'export') {
 | 
        
           |  |  | 1784 |         require_login($course, false, $cm);
 | 
        
           |  |  | 1785 |         require_capability('mod/glossary:export', $context);
 | 
        
           |  |  | 1786 |   | 
        
           |  |  | 1787 |         if (!$glossary = $DB->get_record('glossary', array('id'=>$cm->instance))) {
 | 
        
           |  |  | 1788 |             return false;
 | 
        
           |  |  | 1789 |         }
 | 
        
           |  |  | 1790 |   | 
        
           |  |  | 1791 |         $cat = array_shift($args);
 | 
        
           |  |  | 1792 |         $cat = clean_param($cat, PARAM_ALPHANUM);
 | 
        
           |  |  | 1793 |   | 
        
           |  |  | 1794 |         $filename = clean_filename(strip_tags(format_string($glossary->name)).'.xml');
 | 
        
           |  |  | 1795 |         $content = glossary_generate_export_file($glossary, NULL, $cat);
 | 
        
           |  |  | 1796 |   | 
        
           |  |  | 1797 |         send_file($content, $filename, 0, 0, true, true);
 | 
        
           |  |  | 1798 |     }
 | 
        
           |  |  | 1799 |   | 
        
           |  |  | 1800 |     return false;
 | 
        
           |  |  | 1801 | }
 | 
        
           |  |  | 1802 |   | 
        
           |  |  | 1803 | /**
 | 
        
           |  |  | 1804 |  *
 | 
        
           |  |  | 1805 |  */
 | 
        
           |  |  | 1806 | function glossary_print_tabbed_table_end() {
 | 
        
           |  |  | 1807 |      echo "</div></div>";
 | 
        
           |  |  | 1808 | }
 | 
        
           |  |  | 1809 |   | 
        
           |  |  | 1810 | /**
 | 
        
           |  |  | 1811 |  * @param object $cm
 | 
        
           |  |  | 1812 |  * @param object $glossary
 | 
        
           |  |  | 1813 |  * @param string $mode
 | 
        
           |  |  | 1814 |  * @param string $hook
 | 
        
           |  |  | 1815 |  * @param string $sortkey
 | 
        
           |  |  | 1816 |  * @param string $sortorder
 | 
        
           |  |  | 1817 |  */
 | 
        
           |  |  | 1818 | function glossary_print_approval_menu($cm, $glossary,$mode, $hook, $sortkey = '', $sortorder = '') {
 | 
        
           |  |  | 1819 |     if ($glossary->showalphabet) {
 | 
        
           |  |  | 1820 |         echo '<div class="glossaryexplain">' . get_string("explainalphabet","glossary") . '</div><br />';
 | 
        
           |  |  | 1821 |     }
 | 
        
           |  |  | 1822 |     glossary_print_special_links($cm, $glossary, $mode, $hook);
 | 
        
           |  |  | 1823 |   | 
        
           |  |  | 1824 |     glossary_print_alphabet_links($cm, $glossary, $mode, $hook,$sortkey, $sortorder);
 | 
        
           |  |  | 1825 |   | 
        
           |  |  | 1826 |     glossary_print_all_links($cm, $glossary, $mode, $hook);
 | 
        
           |  |  | 1827 |   | 
        
           | 1441 | ariadna | 1828 |     glossary_print_sorting_links($cm, $mode, $sortkey, $sortorder);
 | 
        
           | 1 | efrain | 1829 | }
 | 
        
           |  |  | 1830 | /**
 | 
        
           |  |  | 1831 |  * @param object $cm
 | 
        
           |  |  | 1832 |  * @param object $glossary
 | 
        
           |  |  | 1833 |  * @param string $hook
 | 
        
           |  |  | 1834 |  * @param string $sortkey
 | 
        
           |  |  | 1835 |  * @param string $sortorder
 | 
        
           |  |  | 1836 |  */
 | 
        
           |  |  | 1837 | function glossary_print_import_menu($cm, $glossary, $mode, $hook, $sortkey='', $sortorder = '') {
 | 
        
           |  |  | 1838 |     echo '<div class="glossaryexplain">' . get_string("explainimport","glossary") . '</div>';
 | 
        
           |  |  | 1839 | }
 | 
        
           |  |  | 1840 |   | 
        
           |  |  | 1841 | /**
 | 
        
           |  |  | 1842 |  * @param object $cm
 | 
        
           |  |  | 1843 |  * @param object $glossary
 | 
        
           |  |  | 1844 |  * @param string $hook
 | 
        
           |  |  | 1845 |  * @param string $sortkey
 | 
        
           |  |  | 1846 |  * @param string $sortorder
 | 
        
           |  |  | 1847 |  */
 | 
        
           |  |  | 1848 | function glossary_print_export_menu($cm, $glossary, $mode, $hook, $sortkey='', $sortorder = '') {
 | 
        
           |  |  | 1849 |     echo '<div class="glossaryexplain">' . get_string("explainexport","glossary") . '</div>';
 | 
        
           |  |  | 1850 | }
 | 
        
           |  |  | 1851 | /**
 | 
        
           |  |  | 1852 |  * @param object $cm
 | 
        
           |  |  | 1853 |  * @param object $glossary
 | 
        
           |  |  | 1854 |  * @param string $hook
 | 
        
           |  |  | 1855 |  * @param string $sortkey
 | 
        
           |  |  | 1856 |  * @param string $sortorder
 | 
        
           |  |  | 1857 |  */
 | 
        
           |  |  | 1858 | function glossary_print_alphabet_menu($cm, $glossary, $mode, $hook, $sortkey='', $sortorder = '') {
 | 
        
           |  |  | 1859 |     if ( $mode != 'date' ) {
 | 
        
           |  |  | 1860 |         if ($glossary->showalphabet) {
 | 
        
           |  |  | 1861 |             echo '<div class="glossaryexplain">' . get_string("explainalphabet","glossary") . '</div><br />';
 | 
        
           |  |  | 1862 |         }
 | 
        
           |  |  | 1863 |   | 
        
           |  |  | 1864 |         glossary_print_special_links($cm, $glossary, $mode, $hook);
 | 
        
           |  |  | 1865 |   | 
        
           |  |  | 1866 |         glossary_print_alphabet_links($cm, $glossary, $mode, $hook, $sortkey, $sortorder);
 | 
        
           |  |  | 1867 |   | 
        
           |  |  | 1868 |         glossary_print_all_links($cm, $glossary, $mode, $hook);
 | 
        
           |  |  | 1869 |     } else {
 | 
        
           |  |  | 1870 |         glossary_print_sorting_links($cm, $mode, $sortkey,$sortorder);
 | 
        
           |  |  | 1871 |     }
 | 
        
           |  |  | 1872 | }
 | 
        
           |  |  | 1873 |   | 
        
           |  |  | 1874 | /**
 | 
        
           |  |  | 1875 |  * @param object $cm
 | 
        
           |  |  | 1876 |  * @param object $glossary
 | 
        
           |  |  | 1877 |  * @param string $hook
 | 
        
           |  |  | 1878 |  * @param string $sortkey
 | 
        
           |  |  | 1879 |  * @param string $sortorder
 | 
        
           |  |  | 1880 |  */
 | 
        
           |  |  | 1881 | function glossary_print_author_menu($cm, $glossary,$mode, $hook, $sortkey = '', $sortorder = '') {
 | 
        
           |  |  | 1882 |     if ($glossary->showalphabet) {
 | 
        
           |  |  | 1883 |         echo '<div class="glossaryexplain">' . get_string("explainalphabet","glossary") . '</div><br />';
 | 
        
           |  |  | 1884 |     }
 | 
        
           |  |  | 1885 |   | 
        
           |  |  | 1886 |     glossary_print_alphabet_links($cm, $glossary, $mode, $hook, $sortkey, $sortorder);
 | 
        
           |  |  | 1887 |     glossary_print_all_links($cm, $glossary, $mode, $hook);
 | 
        
           |  |  | 1888 |     glossary_print_sorting_links($cm, $mode, $sortkey,$sortorder);
 | 
        
           |  |  | 1889 | }
 | 
        
           |  |  | 1890 |   | 
        
           |  |  | 1891 | /**
 | 
        
           |  |  | 1892 |  * @global object
 | 
        
           |  |  | 1893 |  * @global object
 | 
        
           |  |  | 1894 |  * @param object $cm
 | 
        
           |  |  | 1895 |  * @param object $glossary
 | 
        
           |  |  | 1896 |  * @param string $hook
 | 
        
           |  |  | 1897 |  * @param object $category
 | 
        
           |  |  | 1898 |  */
 | 
        
           |  |  | 1899 | function glossary_print_categories_menu($cm, $glossary, $hook, $category) {
 | 
        
           |  |  | 1900 |      global $CFG, $DB, $OUTPUT;
 | 
        
           |  |  | 1901 |   | 
        
           |  |  | 1902 |      $context = context_module::instance($cm->id);
 | 
        
           |  |  | 1903 |   | 
        
           |  |  | 1904 |     // Prepare format_string/text options
 | 
        
           |  |  | 1905 |     $fmtoptions = array(
 | 
        
           |  |  | 1906 |         'context' => $context);
 | 
        
           |  |  | 1907 |   | 
        
           | 1441 | ariadna | 1908 |      echo '<table class="table-reboot" border="0" width="100%">';
 | 
        
           | 1 | efrain | 1909 |      echo '<tr>';
 | 
        
           |  |  | 1910 |   | 
        
           |  |  | 1911 |      echo '<td align="center" style="width:20%">';
 | 
        
           |  |  | 1912 |      if (has_capability('mod/glossary:managecategories', $context)) {
 | 
        
           |  |  | 1913 |              $options['id'] = $cm->id;
 | 
        
           |  |  | 1914 |              $options['mode'] = 'cat';
 | 
        
           |  |  | 1915 |              $options['hook'] = $hook;
 | 
        
           |  |  | 1916 |              echo $OUTPUT->single_button(new moodle_url("editcategories.php", $options), get_string("editcategories","glossary"), "get");
 | 
        
           |  |  | 1917 |      }
 | 
        
           |  |  | 1918 |      echo '</td>';
 | 
        
           |  |  | 1919 |   | 
        
           |  |  | 1920 |      echo '<td align="center" style="width:60%">';
 | 
        
           |  |  | 1921 |      echo '<b>';
 | 
        
           |  |  | 1922 |   | 
        
           |  |  | 1923 |      $menu = array();
 | 
        
           |  |  | 1924 |      $menu[GLOSSARY_SHOW_ALL_CATEGORIES] = get_string("allcategories","glossary");
 | 
        
           |  |  | 1925 |      $menu[GLOSSARY_SHOW_NOT_CATEGORISED] = get_string("notcategorised","glossary");
 | 
        
           |  |  | 1926 |   | 
        
           |  |  | 1927 |      $categories = $DB->get_records("glossary_categories", array("glossaryid"=>$glossary->id), "name ASC");
 | 
        
           |  |  | 1928 |      $selected = '';
 | 
        
           |  |  | 1929 |      if ( $categories ) {
 | 
        
           |  |  | 1930 |           foreach ($categories as $currentcategory) {
 | 
        
           |  |  | 1931 |                  $url = $currentcategory->id;
 | 
        
           |  |  | 1932 |                  if ( $category ) {
 | 
        
           |  |  | 1933 |                      if ($currentcategory->id == $category->id) {
 | 
        
           |  |  | 1934 |                          $selected = $url;
 | 
        
           |  |  | 1935 |                      }
 | 
        
           |  |  | 1936 |                  }
 | 
        
           |  |  | 1937 |                  $menu[$url] = format_string($currentcategory->name, true, $fmtoptions);
 | 
        
           |  |  | 1938 |           }
 | 
        
           |  |  | 1939 |      }
 | 
        
           |  |  | 1940 |      if ( !$selected ) {
 | 
        
           |  |  | 1941 |          $selected = GLOSSARY_SHOW_NOT_CATEGORISED;
 | 
        
           |  |  | 1942 |      }
 | 
        
           |  |  | 1943 |   | 
        
           |  |  | 1944 |      if ( $category ) {
 | 
        
           |  |  | 1945 |         echo format_string($category->name, true, $fmtoptions);
 | 
        
           |  |  | 1946 |      } else {
 | 
        
           |  |  | 1947 |         if ( $hook == GLOSSARY_SHOW_NOT_CATEGORISED ) {
 | 
        
           |  |  | 1948 |   | 
        
           |  |  | 1949 |             echo get_string("entrieswithoutcategory","glossary");
 | 
        
           |  |  | 1950 |             $selected = GLOSSARY_SHOW_NOT_CATEGORISED;
 | 
        
           |  |  | 1951 |   | 
        
           |  |  | 1952 |         } else if ( empty($hook) ) {
 | 
        
           |  |  | 1953 |   | 
        
           |  |  | 1954 |             echo get_string("allcategories","glossary");
 | 
        
           |  |  | 1955 |             $selected = GLOSSARY_SHOW_ALL_CATEGORIES;
 | 
        
           |  |  | 1956 |   | 
        
           |  |  | 1957 |         }
 | 
        
           |  |  | 1958 |      }
 | 
        
           |  |  | 1959 |      echo '</b></td>';
 | 
        
           |  |  | 1960 |      echo '<td align="center" style="width:20%">';
 | 
        
           |  |  | 1961 |   | 
        
           |  |  | 1962 |      $select = new single_select(new moodle_url("/mod/glossary/view.php", array('id'=>$cm->id, 'mode'=>'cat')), 'hook', $menu, $selected, null, "catmenu");
 | 
        
           |  |  | 1963 |      $select->set_label(get_string('categories', 'glossary'), array('class' => 'accesshide'));
 | 
        
           |  |  | 1964 |      echo $OUTPUT->render($select);
 | 
        
           |  |  | 1965 |   | 
        
           |  |  | 1966 |      echo '</td>';
 | 
        
           |  |  | 1967 |      echo '</tr>';
 | 
        
           |  |  | 1968 |   | 
        
           |  |  | 1969 |      echo '</table>';
 | 
        
           |  |  | 1970 | }
 | 
        
           |  |  | 1971 |   | 
        
           |  |  | 1972 | /**
 | 
        
           |  |  | 1973 |  * @global object
 | 
        
           |  |  | 1974 |  * @param object $cm
 | 
        
           |  |  | 1975 |  * @param object $glossary
 | 
        
           |  |  | 1976 |  * @param string $mode
 | 
        
           |  |  | 1977 |  * @param string $hook
 | 
        
           |  |  | 1978 |  */
 | 
        
           |  |  | 1979 | function glossary_print_all_links($cm, $glossary, $mode, $hook) {
 | 
        
           |  |  | 1980 | global $CFG;
 | 
        
           |  |  | 1981 |      if ( $glossary->showall) {
 | 
        
           |  |  | 1982 |          $strallentries       = get_string("allentries", "glossary");
 | 
        
           |  |  | 1983 |          if ( $hook == 'ALL' ) {
 | 
        
           |  |  | 1984 |               echo "<b>$strallentries</b>";
 | 
        
           |  |  | 1985 |          } else {
 | 
        
           |  |  | 1986 |               $strexplainall = strip_tags(get_string("explainall","glossary"));
 | 
        
           |  |  | 1987 |               echo "<a title=\"$strexplainall\" href=\"$CFG->wwwroot/mod/glossary/view.php?id=$cm->id&mode=$mode&hook=ALL\">$strallentries</a>";
 | 
        
           |  |  | 1988 |          }
 | 
        
           |  |  | 1989 |      }
 | 
        
           |  |  | 1990 | }
 | 
        
           |  |  | 1991 |   | 
        
           |  |  | 1992 | /**
 | 
        
           |  |  | 1993 |  * @global object
 | 
        
           |  |  | 1994 |  * @param object $cm
 | 
        
           |  |  | 1995 |  * @param object $glossary
 | 
        
           |  |  | 1996 |  * @param string $mode
 | 
        
           |  |  | 1997 |  * @param string $hook
 | 
        
           |  |  | 1998 |  */
 | 
        
           |  |  | 1999 | function glossary_print_special_links($cm, $glossary, $mode, $hook) {
 | 
        
           |  |  | 2000 | global $CFG;
 | 
        
           |  |  | 2001 |      if ( $glossary->showspecial) {
 | 
        
           |  |  | 2002 |          $strspecial          = get_string("special", "glossary");
 | 
        
           |  |  | 2003 |          if ( $hook == 'SPECIAL' ) {
 | 
        
           |  |  | 2004 |               echo "<b>$strspecial</b> | ";
 | 
        
           |  |  | 2005 |          } else {
 | 
        
           |  |  | 2006 |               $strexplainspecial = strip_tags(get_string("explainspecial","glossary"));
 | 
        
           |  |  | 2007 |               echo "<a title=\"$strexplainspecial\" href=\"$CFG->wwwroot/mod/glossary/view.php?id=$cm->id&mode=$mode&hook=SPECIAL\">$strspecial</a> | ";
 | 
        
           |  |  | 2008 |          }
 | 
        
           |  |  | 2009 |      }
 | 
        
           |  |  | 2010 | }
 | 
        
           |  |  | 2011 |   | 
        
           |  |  | 2012 | /**
 | 
        
           |  |  | 2013 |  * @global object
 | 
        
           |  |  | 2014 |  * @param object $glossary
 | 
        
           |  |  | 2015 |  * @param string $mode
 | 
        
           |  |  | 2016 |  * @param string $hook
 | 
        
           |  |  | 2017 |  * @param string $sortkey
 | 
        
           |  |  | 2018 |  * @param string $sortorder
 | 
        
           |  |  | 2019 |  */
 | 
        
           |  |  | 2020 | function glossary_print_alphabet_links($cm, $glossary, $mode, $hook, $sortkey, $sortorder) {
 | 
        
           |  |  | 2021 | global $CFG;
 | 
        
           |  |  | 2022 |      if ( $glossary->showalphabet) {
 | 
        
           |  |  | 2023 |           $alphabet = explode(",", get_string('alphabet', 'langconfig'));
 | 
        
           |  |  | 2024 |           for ($i = 0; $i < count($alphabet); $i++) {
 | 
        
           |  |  | 2025 |               if ( $hook == $alphabet[$i] and $hook) {
 | 
        
           |  |  | 2026 |                    echo "<b>$alphabet[$i]</b>";
 | 
        
           |  |  | 2027 |               } else {
 | 
        
           |  |  | 2028 |                    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>";
 | 
        
           |  |  | 2029 |               }
 | 
        
           |  |  | 2030 |               echo ' | ';
 | 
        
           |  |  | 2031 |           }
 | 
        
           |  |  | 2032 |      }
 | 
        
           |  |  | 2033 | }
 | 
        
           |  |  | 2034 |   | 
        
           |  |  | 2035 | /**
 | 
        
           |  |  | 2036 |  * @global object
 | 
        
           |  |  | 2037 |  * @param object $cm
 | 
        
           |  |  | 2038 |  * @param string $mode
 | 
        
           |  |  | 2039 |  * @param string $sortkey
 | 
        
           |  |  | 2040 |  * @param string $sortorder
 | 
        
           |  |  | 2041 |  */
 | 
        
           |  |  | 2042 | function glossary_print_sorting_links($cm, $mode, $sortkey = '',$sortorder = '') {
 | 
        
           |  |  | 2043 |     global $CFG, $OUTPUT;
 | 
        
           |  |  | 2044 |   | 
        
           |  |  | 2045 |     $asc    = get_string("ascending","glossary");
 | 
        
           |  |  | 2046 |     $desc   = get_string("descending","glossary");
 | 
        
           |  |  | 2047 |     $bopen  = '<b>';
 | 
        
           |  |  | 2048 |     $bclose = '</b>';
 | 
        
           |  |  | 2049 |   | 
        
           | 1441 | ariadna | 2050 |     $neworder = '';
 | 
        
           |  |  | 2051 |     $currentorder = '';
 | 
        
           |  |  | 2052 |     $currentsort = '';
 | 
        
           |  |  | 2053 |   | 
        
           |  |  | 2054 |     if ($sortkey === '') {
 | 
        
           |  |  | 2055 |         $sortkey = 'CREATION';
 | 
        
           |  |  | 2056 |     }
 | 
        
           |  |  | 2057 |   | 
        
           | 1 | efrain | 2058 |      if ( $sortorder ) {
 | 
        
           |  |  | 2059 |          if ( $sortorder == 'asc' ) {
 | 
        
           |  |  | 2060 |              $currentorder = $asc;
 | 
        
           |  |  | 2061 |              $neworder = '&sortorder=desc';
 | 
        
           |  |  | 2062 |              $newordertitle = get_string('changeto', 'glossary', $desc);
 | 
        
           |  |  | 2063 |          } else {
 | 
        
           |  |  | 2064 |              $currentorder = $desc;
 | 
        
           |  |  | 2065 |              $neworder = '&sortorder=asc';
 | 
        
           |  |  | 2066 |              $newordertitle = get_string('changeto', 'glossary', $asc);
 | 
        
           |  |  | 2067 |          }
 | 
        
           |  |  | 2068 |          $icon = " " . $OUTPUT->pix_icon($sortorder, $newordertitle, 'glossary');
 | 
        
           |  |  | 2069 |      } else {
 | 
        
           |  |  | 2070 |          if ( $sortkey != 'CREATION' and $sortkey != 'UPDATE' and
 | 
        
           |  |  | 2071 |                $sortkey != 'FIRSTNAME' and $sortkey != 'LASTNAME' ) {
 | 
        
           |  |  | 2072 |              $icon = "";
 | 
        
           |  |  | 2073 |              $newordertitle = $asc;
 | 
        
           |  |  | 2074 |          } else {
 | 
        
           |  |  | 2075 |              $newordertitle = $desc;
 | 
        
           |  |  | 2076 |              $neworder = '&sortorder=desc';
 | 
        
           |  |  | 2077 |              $icon = " " . $OUTPUT->pix_icon('asc', $newordertitle, 'glossary');
 | 
        
           |  |  | 2078 |          }
 | 
        
           |  |  | 2079 |      }
 | 
        
           |  |  | 2080 |   | 
        
           | 1441 | ariadna | 2081 |     $ficon     = '';
 | 
        
           |  |  | 2082 |     $fneworder = '';
 | 
        
           | 1 | efrain | 2083 |   | 
        
           | 1441 | ariadna | 2084 |     $sicon     = '';
 | 
        
           |  |  | 2085 |     $sneworder = '';
 | 
        
           | 1 | efrain | 2086 |   | 
        
           | 1441 | ariadna | 2087 |     $sbtag      = '';
 | 
        
           |  |  | 2088 |     $fbtag      = '';
 | 
        
           |  |  | 2089 |     $fendbtag      = '';
 | 
        
           | 1 | efrain | 2090 |   | 
        
           | 1441 | ariadna | 2091 |     $sendbtag  = '';
 | 
        
           |  |  | 2092 |   | 
        
           | 1 | efrain | 2093 |      if ( $sortkey == 'CREATION' or $sortkey == 'FIRSTNAME' ) {
 | 
        
           |  |  | 2094 |          $ficon       = $icon;
 | 
        
           |  |  | 2095 |          $fneworder   = $neworder;
 | 
        
           |  |  | 2096 |          $fordertitle = $newordertitle;
 | 
        
           |  |  | 2097 |          $sordertitle = $asc;
 | 
        
           |  |  | 2098 |          $fbtag       = $bopen;
 | 
        
           |  |  | 2099 |          $fendbtag    = $bclose;
 | 
        
           |  |  | 2100 |      } elseif ($sortkey == 'UPDATE' or $sortkey == 'LASTNAME') {
 | 
        
           |  |  | 2101 |          $sicon = $icon;
 | 
        
           |  |  | 2102 |          $sneworder   = $neworder;
 | 
        
           |  |  | 2103 |          $fordertitle = $asc;
 | 
        
           |  |  | 2104 |          $sordertitle = $newordertitle;
 | 
        
           |  |  | 2105 |          $sbtag       = $bopen;
 | 
        
           |  |  | 2106 |          $sendbtag    = $bclose;
 | 
        
           |  |  | 2107 |      } else {
 | 
        
           |  |  | 2108 |          $fordertitle = $asc;
 | 
        
           |  |  | 2109 |          $sordertitle = $asc;
 | 
        
           |  |  | 2110 |      }
 | 
        
           |  |  | 2111 |   | 
        
           |  |  | 2112 |      if ( $sortkey == 'CREATION' or $sortkey == 'UPDATE' ) {
 | 
        
           |  |  | 2113 |          $forder = 'CREATION';
 | 
        
           |  |  | 2114 |          $sorder =  'UPDATE';
 | 
        
           |  |  | 2115 |          $fsort  = get_string("sortbycreation", "glossary");
 | 
        
           |  |  | 2116 |          $ssort  = get_string("sortbylastupdate", "glossary");
 | 
        
           |  |  | 2117 |   | 
        
           |  |  | 2118 |          $currentsort = $fsort;
 | 
        
           |  |  | 2119 |          if ($sortkey == 'UPDATE') {
 | 
        
           |  |  | 2120 |              $currentsort = $ssort;
 | 
        
           |  |  | 2121 |          }
 | 
        
           |  |  | 2122 |          $sort        = get_string("sortchronogically", "glossary");
 | 
        
           |  |  | 2123 |      } elseif ( $sortkey == 'FIRSTNAME' or $sortkey == 'LASTNAME') {
 | 
        
           |  |  | 2124 |          $forder = 'FIRSTNAME';
 | 
        
           |  |  | 2125 |          $sorder =  'LASTNAME';
 | 
        
           |  |  | 2126 |          $fsort  = get_string("firstname");
 | 
        
           |  |  | 2127 |          $ssort  = get_string("lastname");
 | 
        
           |  |  | 2128 |   | 
        
           |  |  | 2129 |          $currentsort = $fsort;
 | 
        
           |  |  | 2130 |          if ($sortkey == 'LASTNAME') {
 | 
        
           |  |  | 2131 |              $currentsort = $ssort;
 | 
        
           |  |  | 2132 |          }
 | 
        
           |  |  | 2133 |          $sort        = get_string("sortby", "glossary");
 | 
        
           |  |  | 2134 |      }
 | 
        
           |  |  | 2135 |      $current = '<span class="accesshide">'.get_string('current', 'glossary', "$currentsort $currentorder").'</span>';
 | 
        
           |  |  | 2136 |      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 | ".
 | 
        
           |  |  | 2137 |                           "$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 />";
 | 
        
           |  |  | 2138 | }
 | 
        
           |  |  | 2139 |   | 
        
           |  |  | 2140 | /**
 | 
        
           |  |  | 2141 |  *
 | 
        
           |  |  | 2142 |  * @param object $entry0
 | 
        
           |  |  | 2143 |  * @param object $entry1
 | 
        
           |  |  | 2144 |  * @return int [-1 | 0 | 1]
 | 
        
           |  |  | 2145 |  */
 | 
        
           |  |  | 2146 | function glossary_sort_entries ( $entry0, $entry1 ) {
 | 
        
           |  |  | 2147 |   | 
        
           |  |  | 2148 |     if ( core_text::strtolower(ltrim($entry0->concept)) < core_text::strtolower(ltrim($entry1->concept)) ) {
 | 
        
           |  |  | 2149 |         return -1;
 | 
        
           |  |  | 2150 |     } elseif ( core_text::strtolower(ltrim($entry0->concept)) > core_text::strtolower(ltrim($entry1->concept)) ) {
 | 
        
           |  |  | 2151 |         return 1;
 | 
        
           |  |  | 2152 |     } else {
 | 
        
           |  |  | 2153 |         return 0;
 | 
        
           |  |  | 2154 |     }
 | 
        
           |  |  | 2155 | }
 | 
        
           |  |  | 2156 |   | 
        
           |  |  | 2157 |   | 
        
           |  |  | 2158 | /**
 | 
        
           |  |  | 2159 |  * @global object
 | 
        
           |  |  | 2160 |  * @global object
 | 
        
           |  |  | 2161 |  * @global object
 | 
        
           |  |  | 2162 |  * @param object $course
 | 
        
           |  |  | 2163 |  * @param object $entry
 | 
        
           |  |  | 2164 |  * @return bool
 | 
        
           |  |  | 2165 |  */
 | 
        
           |  |  | 2166 | function  glossary_print_entry_ratings($course, $entry) {
 | 
        
           |  |  | 2167 |     global $OUTPUT;
 | 
        
           |  |  | 2168 |     if( !empty($entry->rating) ){
 | 
        
           |  |  | 2169 |         echo $OUTPUT->render($entry->rating);
 | 
        
           |  |  | 2170 |     }
 | 
        
           |  |  | 2171 | }
 | 
        
           |  |  | 2172 |   | 
        
           |  |  | 2173 | /**
 | 
        
           |  |  | 2174 |  *
 | 
        
           |  |  | 2175 |  * @global object
 | 
        
           |  |  | 2176 |  * @global object
 | 
        
           |  |  | 2177 |  * @global object
 | 
        
           |  |  | 2178 |  * @param int $courseid
 | 
        
           |  |  | 2179 |  * @param array $entries
 | 
        
           |  |  | 2180 |  * @param int $displayformat
 | 
        
           |  |  | 2181 |  */
 | 
        
           |  |  | 2182 | function glossary_print_dynaentry($courseid, $entries, $displayformat = -1) {
 | 
        
           |  |  | 2183 |     global $USER, $CFG, $DB;
 | 
        
           |  |  | 2184 |   | 
        
           |  |  | 2185 |     echo '<div class="boxaligncenter">';
 | 
        
           | 1441 | ariadna | 2186 |     echo '<table class="glossarypopup table-reboot" cellspacing="0"><tr>';
 | 
        
           | 1 | efrain | 2187 |     echo '<td>';
 | 
        
           |  |  | 2188 |     if ( $entries ) {
 | 
        
           |  |  | 2189 |         foreach ( $entries as $entry ) {
 | 
        
           |  |  | 2190 |             if (! $glossary = $DB->get_record('glossary', array('id'=>$entry->glossaryid))) {
 | 
        
           |  |  | 2191 |                 throw new \moodle_exception('invalidid', 'glossary');
 | 
        
           |  |  | 2192 |             }
 | 
        
           |  |  | 2193 |             if (! $course = $DB->get_record('course', array('id'=>$glossary->course))) {
 | 
        
           |  |  | 2194 |                 throw new \moodle_exception('coursemisconf');
 | 
        
           |  |  | 2195 |             }
 | 
        
           |  |  | 2196 |             if (!$cm = get_coursemodule_from_instance('glossary', $entry->glossaryid, $glossary->course) ) {
 | 
        
           |  |  | 2197 |                 throw new \moodle_exception('invalidid', 'glossary');
 | 
        
           |  |  | 2198 |             }
 | 
        
           |  |  | 2199 |   | 
        
           |  |  | 2200 |             //If displayformat is present, override glossary->displayformat
 | 
        
           |  |  | 2201 |             if ($displayformat < 0) {
 | 
        
           |  |  | 2202 |                 $dp = $glossary->displayformat;
 | 
        
           |  |  | 2203 |             } else {
 | 
        
           |  |  | 2204 |                 $dp = $displayformat;
 | 
        
           |  |  | 2205 |             }
 | 
        
           |  |  | 2206 |   | 
        
           |  |  | 2207 |             //Get popupformatname
 | 
        
           |  |  | 2208 |             $format = $DB->get_record('glossary_formats', array('name'=>$dp));
 | 
        
           |  |  | 2209 |             $displayformat = $format->popupformatname;
 | 
        
           |  |  | 2210 |   | 
        
           |  |  | 2211 |             //Check displayformat variable and set to default if necessary
 | 
        
           |  |  | 2212 |             if (!$displayformat) {
 | 
        
           |  |  | 2213 |                 $displayformat = 'dictionary';
 | 
        
           |  |  | 2214 |             }
 | 
        
           |  |  | 2215 |   | 
        
           |  |  | 2216 |             $formatfile = $CFG->dirroot.'/mod/glossary/formats/'.$displayformat.'/'.$displayformat.'_format.php';
 | 
        
           |  |  | 2217 |             $functionname = 'glossary_show_entry_'.$displayformat;
 | 
        
           |  |  | 2218 |   | 
        
           |  |  | 2219 |             if (file_exists($formatfile)) {
 | 
        
           |  |  | 2220 |                 include_once($formatfile);
 | 
        
           |  |  | 2221 |                 if (function_exists($functionname)) {
 | 
        
           |  |  | 2222 |                     $functionname($course, $cm, $glossary, $entry,'','','','');
 | 
        
           |  |  | 2223 |                 }
 | 
        
           |  |  | 2224 |             }
 | 
        
           |  |  | 2225 |         }
 | 
        
           |  |  | 2226 |     }
 | 
        
           |  |  | 2227 |     echo '</td>';
 | 
        
           |  |  | 2228 |     echo '</tr></table></div>';
 | 
        
           |  |  | 2229 | }
 | 
        
           |  |  | 2230 |   | 
        
           |  |  | 2231 | /**
 | 
        
           |  |  | 2232 |  *
 | 
        
           |  |  | 2233 |  * @global object
 | 
        
           |  |  | 2234 |  * @param array $entries
 | 
        
           |  |  | 2235 |  * @param array $aliases
 | 
        
           |  |  | 2236 |  * @param array $categories
 | 
        
           |  |  | 2237 |  * @return string
 | 
        
           |  |  | 2238 |  */
 | 
        
           |  |  | 2239 | function glossary_generate_export_csv($entries, $aliases, $categories) {
 | 
        
           |  |  | 2240 |     global $CFG;
 | 
        
           |  |  | 2241 |     $csv = '';
 | 
        
           |  |  | 2242 |     $delimiter = '';
 | 
        
           |  |  | 2243 |     require_once($CFG->libdir . '/csvlib.class.php');
 | 
        
           |  |  | 2244 |     $delimiter = csv_import_reader::get_delimiter('comma');
 | 
        
           |  |  | 2245 |     $csventries = array(0 => array(get_string('concept', 'glossary'), get_string('definition', 'glossary')));
 | 
        
           |  |  | 2246 |     $csvaliases = array(0 => array());
 | 
        
           |  |  | 2247 |     $csvcategories = array(0 => array());
 | 
        
           |  |  | 2248 |     $aliascount = 0;
 | 
        
           |  |  | 2249 |     $categorycount = 0;
 | 
        
           |  |  | 2250 |   | 
        
           |  |  | 2251 |     foreach ($entries as $entry) {
 | 
        
           |  |  | 2252 |         $thisaliasesentry = array();
 | 
        
           |  |  | 2253 |         $thiscategoriesentry = array();
 | 
        
           |  |  | 2254 |         $thiscsventry = array($entry->concept, nl2br($entry->definition));
 | 
        
           |  |  | 2255 |   | 
        
           |  |  | 2256 |         if (array_key_exists($entry->id, $aliases) && is_array($aliases[$entry->id])) {
 | 
        
           |  |  | 2257 |             $thiscount = count($aliases[$entry->id]);
 | 
        
           |  |  | 2258 |             if ($thiscount > $aliascount) {
 | 
        
           |  |  | 2259 |                 $aliascount = $thiscount;
 | 
        
           |  |  | 2260 |             }
 | 
        
           |  |  | 2261 |             foreach ($aliases[$entry->id] as $alias) {
 | 
        
           |  |  | 2262 |                 $thisaliasesentry[] = trim($alias);
 | 
        
           |  |  | 2263 |             }
 | 
        
           |  |  | 2264 |         }
 | 
        
           |  |  | 2265 |         if (array_key_exists($entry->id, $categories) && is_array($categories[$entry->id])) {
 | 
        
           |  |  | 2266 |             $thiscount = count($categories[$entry->id]);
 | 
        
           |  |  | 2267 |             if ($thiscount > $categorycount) {
 | 
        
           |  |  | 2268 |                 $categorycount = $thiscount;
 | 
        
           |  |  | 2269 |             }
 | 
        
           |  |  | 2270 |             foreach ($categories[$entry->id] as $catentry) {
 | 
        
           |  |  | 2271 |                 $thiscategoriesentry[] = trim($catentry);
 | 
        
           |  |  | 2272 |             }
 | 
        
           |  |  | 2273 |         }
 | 
        
           |  |  | 2274 |         $csventries[$entry->id] = $thiscsventry;
 | 
        
           |  |  | 2275 |         $csvaliases[$entry->id] = $thisaliasesentry;
 | 
        
           |  |  | 2276 |         $csvcategories[$entry->id] = $thiscategoriesentry;
 | 
        
           |  |  | 2277 |   | 
        
           |  |  | 2278 |     }
 | 
        
           |  |  | 2279 |     $returnstr = '';
 | 
        
           |  |  | 2280 |     foreach ($csventries as $id => $row) {
 | 
        
           |  |  | 2281 |         $aliasstr = '';
 | 
        
           |  |  | 2282 |         $categorystr = '';
 | 
        
           |  |  | 2283 |         if ($id == 0) {
 | 
        
           |  |  | 2284 |             $aliasstr = get_string('alias', 'glossary');
 | 
        
           |  |  | 2285 |             $categorystr = get_string('category', 'glossary');
 | 
        
           |  |  | 2286 |         }
 | 
        
           |  |  | 2287 |         $row = array_merge($row, array_pad($csvaliases[$id], $aliascount, $aliasstr), array_pad($csvcategories[$id], $categorycount, $categorystr));
 | 
        
           |  |  | 2288 |         $returnstr .= '"' . implode('"' . $delimiter . '"', $row) . '"' . "\n";
 | 
        
           |  |  | 2289 |     }
 | 
        
           |  |  | 2290 |     return $returnstr;
 | 
        
           |  |  | 2291 | }
 | 
        
           |  |  | 2292 |   | 
        
           |  |  | 2293 | /**
 | 
        
           |  |  | 2294 |  *
 | 
        
           |  |  | 2295 |  * @param object $glossary
 | 
        
           |  |  | 2296 |  * @param string $ignored invalid parameter
 | 
        
           |  |  | 2297 |  * @param int|string $hook
 | 
        
           |  |  | 2298 |  * @return string
 | 
        
           |  |  | 2299 |  */
 | 
        
           |  |  | 2300 | function glossary_generate_export_file($glossary, $ignored = "", $hook = 0) {
 | 
        
           |  |  | 2301 |     global $CFG, $DB;
 | 
        
           |  |  | 2302 |   | 
        
           |  |  | 2303 |     // Large exports are likely to take their time and memory.
 | 
        
           |  |  | 2304 |     core_php_time_limit::raise();
 | 
        
           |  |  | 2305 |     raise_memory_limit(MEMORY_EXTRA);
 | 
        
           |  |  | 2306 |   | 
        
           |  |  | 2307 |     $cm = get_coursemodule_from_instance('glossary', $glossary->id, $glossary->course);
 | 
        
           |  |  | 2308 |     $context = context_module::instance($cm->id);
 | 
        
           |  |  | 2309 |   | 
        
           |  |  | 2310 |     $co  = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
 | 
        
           |  |  | 2311 |   | 
        
           |  |  | 2312 |     $co .= glossary_start_tag("GLOSSARY",0,true);
 | 
        
           |  |  | 2313 |     $co .= glossary_start_tag("INFO",1,true);
 | 
        
           |  |  | 2314 |         $co .= glossary_full_tag("NAME",2,false,$glossary->name);
 | 
        
           |  |  | 2315 |         $co .= glossary_full_tag("INTRO",2,false,$glossary->intro);
 | 
        
           |  |  | 2316 |         $co .= glossary_full_tag("INTROFORMAT",2,false,$glossary->introformat);
 | 
        
           |  |  | 2317 |         $co .= glossary_full_tag("ALLOWDUPLICATEDENTRIES",2,false,$glossary->allowduplicatedentries);
 | 
        
           |  |  | 2318 |         $co .= glossary_full_tag("DISPLAYFORMAT",2,false,$glossary->displayformat);
 | 
        
           |  |  | 2319 |         $co .= glossary_full_tag("SHOWSPECIAL",2,false,$glossary->showspecial);
 | 
        
           |  |  | 2320 |         $co .= glossary_full_tag("SHOWALPHABET",2,false,$glossary->showalphabet);
 | 
        
           |  |  | 2321 |         $co .= glossary_full_tag("SHOWALL",2,false,$glossary->showall);
 | 
        
           |  |  | 2322 |         $co .= glossary_full_tag("ALLOWCOMMENTS",2,false,$glossary->allowcomments);
 | 
        
           |  |  | 2323 |         $co .= glossary_full_tag("USEDYNALINK",2,false,$glossary->usedynalink);
 | 
        
           |  |  | 2324 |         $co .= glossary_full_tag("DEFAULTAPPROVAL",2,false,$glossary->defaultapproval);
 | 
        
           |  |  | 2325 |         $co .= glossary_full_tag("GLOBALGLOSSARY",2,false,$glossary->globalglossary);
 | 
        
           |  |  | 2326 |         $co .= glossary_full_tag("ENTBYPAGE",2,false,$glossary->entbypage);
 | 
        
           |  |  | 2327 |         $co .= glossary_xml_export_files('INTROFILES', 2, $context->id, 'intro', 0);
 | 
        
           |  |  | 2328 |   | 
        
           |  |  | 2329 |         if ( $entries = $DB->get_records("glossary_entries", array("glossaryid"=>$glossary->id))) {
 | 
        
           |  |  | 2330 |             $co .= glossary_start_tag("ENTRIES",2,true);
 | 
        
           |  |  | 2331 |             foreach ($entries as $entry) {
 | 
        
           |  |  | 2332 |                 $permissiongranted = 1;
 | 
        
           |  |  | 2333 |                 if ( $hook ) {
 | 
        
           |  |  | 2334 |                     switch ( $hook ) {
 | 
        
           |  |  | 2335 |                     case "ALL":
 | 
        
           |  |  | 2336 |                     case "SPECIAL":
 | 
        
           |  |  | 2337 |                     break;
 | 
        
           |  |  | 2338 |                     default:
 | 
        
           |  |  | 2339 |                         $permissiongranted = ($entry->concept[ strlen($hook)-1 ] == $hook);
 | 
        
           |  |  | 2340 |                     break;
 | 
        
           |  |  | 2341 |                     }
 | 
        
           |  |  | 2342 |                 }
 | 
        
           |  |  | 2343 |                 if ( $hook ) {
 | 
        
           |  |  | 2344 |                     switch ( $hook ) {
 | 
        
           |  |  | 2345 |                     case GLOSSARY_SHOW_ALL_CATEGORIES:
 | 
        
           |  |  | 2346 |                     break;
 | 
        
           |  |  | 2347 |                     case GLOSSARY_SHOW_NOT_CATEGORISED:
 | 
        
           |  |  | 2348 |                         $permissiongranted = !$DB->record_exists("glossary_entries_categories", array("entryid"=>$entry->id));
 | 
        
           |  |  | 2349 |                     break;
 | 
        
           |  |  | 2350 |                     default:
 | 
        
           |  |  | 2351 |                         $permissiongranted = $DB->record_exists("glossary_entries_categories", array("entryid"=>$entry->id, "categoryid"=>$hook));
 | 
        
           |  |  | 2352 |                     break;
 | 
        
           |  |  | 2353 |                     }
 | 
        
           |  |  | 2354 |                 }
 | 
        
           |  |  | 2355 |                 if ( $entry->approved and $permissiongranted ) {
 | 
        
           |  |  | 2356 |                     $co .= glossary_start_tag("ENTRY",3,true);
 | 
        
           |  |  | 2357 |                     $co .= glossary_full_tag("CONCEPT",4,false,trim($entry->concept));
 | 
        
           |  |  | 2358 |                     $co .= glossary_full_tag("DEFINITION",4,false,$entry->definition);
 | 
        
           |  |  | 2359 |                     $co .= glossary_full_tag("FORMAT",4,false,$entry->definitionformat); // note: use old name for BC reasons
 | 
        
           | 1441 | ariadna | 2360 |                     $co .= glossary_full_tag('DEFINITIONTRUST', 4, false, $entry->definitiontrust);
 | 
        
           | 1 | efrain | 2361 |                     $co .= glossary_full_tag("USEDYNALINK",4,false,$entry->usedynalink);
 | 
        
           |  |  | 2362 |                     $co .= glossary_full_tag("CASESENSITIVE",4,false,$entry->casesensitive);
 | 
        
           |  |  | 2363 |                     $co .= glossary_full_tag("FULLMATCH",4,false,$entry->fullmatch);
 | 
        
           |  |  | 2364 |                     $co .= glossary_full_tag("TEACHERENTRY",4,false,$entry->teacherentry);
 | 
        
           |  |  | 2365 |   | 
        
           |  |  | 2366 |                     if ( $aliases = $DB->get_records("glossary_alias", array("entryid"=>$entry->id))) {
 | 
        
           |  |  | 2367 |                         $co .= glossary_start_tag("ALIASES",4,true);
 | 
        
           |  |  | 2368 |                         foreach ($aliases as $alias) {
 | 
        
           |  |  | 2369 |                             $co .= glossary_start_tag("ALIAS",5,true);
 | 
        
           |  |  | 2370 |                                 $co .= glossary_full_tag("NAME",6,false,trim($alias->alias));
 | 
        
           |  |  | 2371 |                             $co .= glossary_end_tag("ALIAS",5,true);
 | 
        
           |  |  | 2372 |                         }
 | 
        
           |  |  | 2373 |                         $co .= glossary_end_tag("ALIASES",4,true);
 | 
        
           |  |  | 2374 |                     }
 | 
        
           |  |  | 2375 |                     if ( $catentries = $DB->get_records("glossary_entries_categories", array("entryid"=>$entry->id))) {
 | 
        
           |  |  | 2376 |                         $co .= glossary_start_tag("CATEGORIES",4,true);
 | 
        
           |  |  | 2377 |                         foreach ($catentries as $catentry) {
 | 
        
           |  |  | 2378 |                             $category = $DB->get_record("glossary_categories", array("id"=>$catentry->categoryid));
 | 
        
           |  |  | 2379 |   | 
        
           |  |  | 2380 |                             $co .= glossary_start_tag("CATEGORY",5,true);
 | 
        
           |  |  | 2381 |                                 $co .= glossary_full_tag("NAME",6,false,$category->name);
 | 
        
           |  |  | 2382 |                                 $co .= glossary_full_tag("USEDYNALINK",6,false,$category->usedynalink);
 | 
        
           |  |  | 2383 |                             $co .= glossary_end_tag("CATEGORY",5,true);
 | 
        
           |  |  | 2384 |                         }
 | 
        
           |  |  | 2385 |                         $co .= glossary_end_tag("CATEGORIES",4,true);
 | 
        
           |  |  | 2386 |                     }
 | 
        
           |  |  | 2387 |   | 
        
           |  |  | 2388 |                     // Export files embedded in entries.
 | 
        
           |  |  | 2389 |                     $co .= glossary_xml_export_files('ENTRYFILES', 4, $context->id, 'entry', $entry->id);
 | 
        
           |  |  | 2390 |   | 
        
           |  |  | 2391 |                     // Export attachments.
 | 
        
           |  |  | 2392 |                     $co .= glossary_xml_export_files('ATTACHMENTFILES', 4, $context->id, 'attachment', $entry->id);
 | 
        
           |  |  | 2393 |   | 
        
           |  |  | 2394 |                     // Export tags.
 | 
        
           |  |  | 2395 |                     $tags = core_tag_tag::get_item_tags_array('mod_glossary', 'glossary_entries', $entry->id);
 | 
        
           |  |  | 2396 |                     if (count($tags)) {
 | 
        
           |  |  | 2397 |                         $co .= glossary_start_tag("TAGS", 4, true);
 | 
        
           |  |  | 2398 |                         foreach ($tags as $tag) {
 | 
        
           |  |  | 2399 |                             $co .= glossary_full_tag("TAG", 5, false, $tag);
 | 
        
           |  |  | 2400 |                         }
 | 
        
           |  |  | 2401 |                         $co .= glossary_end_tag("TAGS", 4, true);
 | 
        
           |  |  | 2402 |                     }
 | 
        
           |  |  | 2403 |   | 
        
           |  |  | 2404 |                     $co .= glossary_end_tag("ENTRY",3,true);
 | 
        
           |  |  | 2405 |                 }
 | 
        
           |  |  | 2406 |             }
 | 
        
           |  |  | 2407 |             $co .= glossary_end_tag("ENTRIES",2,true);
 | 
        
           |  |  | 2408 |   | 
        
           |  |  | 2409 |         }
 | 
        
           |  |  | 2410 |   | 
        
           |  |  | 2411 |   | 
        
           |  |  | 2412 |     $co .= glossary_end_tag("INFO",1,true);
 | 
        
           |  |  | 2413 |     $co .= glossary_end_tag("GLOSSARY",0,true);
 | 
        
           |  |  | 2414 |   | 
        
           |  |  | 2415 |     return $co;
 | 
        
           |  |  | 2416 | }
 | 
        
           |  |  | 2417 | /// Functions designed by Eloy Lafuente
 | 
        
           |  |  | 2418 | /// Functions to create, open and write header of the xml file
 | 
        
           |  |  | 2419 |   | 
        
           |  |  | 2420 | /**
 | 
        
           |  |  | 2421 |  * Read import file and convert to current charset
 | 
        
           |  |  | 2422 |  *
 | 
        
           |  |  | 2423 |  * @global object
 | 
        
           |  |  | 2424 |  * @param string $file
 | 
        
           |  |  | 2425 |  * @return string
 | 
        
           |  |  | 2426 |  */
 | 
        
           |  |  | 2427 | function glossary_read_imported_file($file_content) {
 | 
        
           |  |  | 2428 |     global $CFG;
 | 
        
           |  |  | 2429 |     require_once "../../lib/xmlize.php";
 | 
        
           |  |  | 2430 |   | 
        
           |  |  | 2431 |     return xmlize($file_content, 0);
 | 
        
           |  |  | 2432 | }
 | 
        
           |  |  | 2433 |   | 
        
           |  |  | 2434 | /**
 | 
        
           |  |  | 2435 |  * Return the xml start tag
 | 
        
           |  |  | 2436 |  *
 | 
        
           |  |  | 2437 |  * @param string $tag
 | 
        
           |  |  | 2438 |  * @param int $level
 | 
        
           |  |  | 2439 |  * @param bool $endline
 | 
        
           |  |  | 2440 |  * @return string
 | 
        
           |  |  | 2441 |  */
 | 
        
           |  |  | 2442 | function glossary_start_tag($tag,$level=0,$endline=false) {
 | 
        
           |  |  | 2443 |         if ($endline) {
 | 
        
           |  |  | 2444 |            $endchar = "\n";
 | 
        
           |  |  | 2445 |         } else {
 | 
        
           |  |  | 2446 |            $endchar = "";
 | 
        
           |  |  | 2447 |         }
 | 
        
           |  |  | 2448 |         return str_repeat(" ",$level*2)."<".strtoupper($tag).">".$endchar;
 | 
        
           |  |  | 2449 | }
 | 
        
           |  |  | 2450 |   | 
        
           |  |  | 2451 | /**
 | 
        
           |  |  | 2452 |  * Return the xml end tag
 | 
        
           |  |  | 2453 |  * @param string $tag
 | 
        
           |  |  | 2454 |  * @param int $level
 | 
        
           |  |  | 2455 |  * @param bool $endline
 | 
        
           |  |  | 2456 |  * @return string
 | 
        
           |  |  | 2457 |  */
 | 
        
           |  |  | 2458 | function glossary_end_tag($tag,$level=0,$endline=true) {
 | 
        
           |  |  | 2459 |         if ($endline) {
 | 
        
           |  |  | 2460 |            $endchar = "\n";
 | 
        
           |  |  | 2461 |         } else {
 | 
        
           |  |  | 2462 |            $endchar = "";
 | 
        
           |  |  | 2463 |         }
 | 
        
           |  |  | 2464 |         return str_repeat(" ",$level*2)."</".strtoupper($tag).">".$endchar;
 | 
        
           |  |  | 2465 | }
 | 
        
           |  |  | 2466 |   | 
        
           |  |  | 2467 | /**
 | 
        
           |  |  | 2468 |  * Return the start tag, the contents and the end tag
 | 
        
           |  |  | 2469 |  *
 | 
        
           |  |  | 2470 |  * @global object
 | 
        
           |  |  | 2471 |  * @param string $tag
 | 
        
           |  |  | 2472 |  * @param int $level
 | 
        
           |  |  | 2473 |  * @param bool $endline
 | 
        
           |  |  | 2474 |  * @param string $content
 | 
        
           |  |  | 2475 |  * @return string
 | 
        
           |  |  | 2476 |  */
 | 
        
           |  |  | 2477 | function glossary_full_tag($tag, $level, $endline, $content) {
 | 
        
           |  |  | 2478 |         global $CFG;
 | 
        
           |  |  | 2479 |   | 
        
           |  |  | 2480 |         $st = glossary_start_tag($tag,$level,$endline);
 | 
        
           |  |  | 2481 |         $co = preg_replace("/\r\n|\r/", "\n", s($content));
 | 
        
           |  |  | 2482 |         $et = glossary_end_tag($tag,0,true);
 | 
        
           |  |  | 2483 |         return $st.$co.$et;
 | 
        
           |  |  | 2484 | }
 | 
        
           |  |  | 2485 |   | 
        
           |  |  | 2486 | /**
 | 
        
           |  |  | 2487 |  * Prepares file area to export as part of XML export
 | 
        
           |  |  | 2488 |  *
 | 
        
           |  |  | 2489 |  * @param string $tag XML tag to use for the group
 | 
        
           |  |  | 2490 |  * @param int $taglevel
 | 
        
           |  |  | 2491 |  * @param int $contextid
 | 
        
           |  |  | 2492 |  * @param string $filearea
 | 
        
           |  |  | 2493 |  * @param int $itemid
 | 
        
           |  |  | 2494 |  * @return string
 | 
        
           |  |  | 2495 |  */
 | 
        
           |  |  | 2496 | function glossary_xml_export_files($tag, $taglevel, $contextid, $filearea, $itemid) {
 | 
        
           |  |  | 2497 |     $co = '';
 | 
        
           |  |  | 2498 |     $fs = get_file_storage();
 | 
        
           |  |  | 2499 |     if ($files = $fs->get_area_files(
 | 
        
           |  |  | 2500 |         $contextid, 'mod_glossary', $filearea, $itemid, 'itemid,filepath,filename', false)) {
 | 
        
           |  |  | 2501 |         $co .= glossary_start_tag($tag, $taglevel, true);
 | 
        
           |  |  | 2502 |         foreach ($files as $file) {
 | 
        
           |  |  | 2503 |             $co .= glossary_start_tag('FILE', $taglevel + 1, true);
 | 
        
           |  |  | 2504 |             $co .= glossary_full_tag('FILENAME', $taglevel + 2, false, $file->get_filename());
 | 
        
           |  |  | 2505 |             $co .= glossary_full_tag('FILEPATH', $taglevel + 2, false, $file->get_filepath());
 | 
        
           |  |  | 2506 |             $co .= glossary_full_tag('CONTENTS', $taglevel + 2, false, base64_encode($file->get_content()));
 | 
        
           |  |  | 2507 |             $co .= glossary_full_tag('FILEAUTHOR', $taglevel + 2, false, $file->get_author());
 | 
        
           |  |  | 2508 |             $co .= glossary_full_tag('FILELICENSE', $taglevel + 2, false, $file->get_license());
 | 
        
           |  |  | 2509 |             $co .= glossary_end_tag('FILE', $taglevel + 1);
 | 
        
           |  |  | 2510 |         }
 | 
        
           |  |  | 2511 |         $co .= glossary_end_tag($tag, $taglevel);
 | 
        
           |  |  | 2512 |     }
 | 
        
           |  |  | 2513 |     return $co;
 | 
        
           |  |  | 2514 | }
 | 
        
           |  |  | 2515 |   | 
        
           |  |  | 2516 | /**
 | 
        
           |  |  | 2517 |  * Parses files from XML import and inserts them into file system
 | 
        
           |  |  | 2518 |  *
 | 
        
           |  |  | 2519 |  * @param array $xmlparent parent element in parsed XML tree
 | 
        
           |  |  | 2520 |  * @param string $tag
 | 
        
           |  |  | 2521 |  * @param int $contextid
 | 
        
           |  |  | 2522 |  * @param string $filearea
 | 
        
           |  |  | 2523 |  * @param int $itemid
 | 
        
           |  |  | 2524 |  * @return int
 | 
        
           |  |  | 2525 |  */
 | 
        
           |  |  | 2526 | function glossary_xml_import_files($xmlparent, $tag, $contextid, $filearea, $itemid) {
 | 
        
           |  |  | 2527 |     global $USER, $CFG;
 | 
        
           |  |  | 2528 |     $count = 0;
 | 
        
           |  |  | 2529 |     if (isset($xmlparent[$tag][0]['#']['FILE'])) {
 | 
        
           |  |  | 2530 |         $fs = get_file_storage();
 | 
        
           |  |  | 2531 |         $files = $xmlparent[$tag][0]['#']['FILE'];
 | 
        
           |  |  | 2532 |         foreach ($files as $file) {
 | 
        
           |  |  | 2533 |             $filerecord = array(
 | 
        
           |  |  | 2534 |                 'contextid' => $contextid,
 | 
        
           |  |  | 2535 |                 'component' => 'mod_glossary',
 | 
        
           |  |  | 2536 |                 'filearea'  => $filearea,
 | 
        
           |  |  | 2537 |                 'itemid'    => $itemid,
 | 
        
           |  |  | 2538 |                 'filepath'  => $file['#']['FILEPATH'][0]['#'],
 | 
        
           |  |  | 2539 |                 'filename'  => $file['#']['FILENAME'][0]['#'],
 | 
        
           |  |  | 2540 |                 'userid'    => $USER->id
 | 
        
           |  |  | 2541 |             );
 | 
        
           |  |  | 2542 |             if (array_key_exists('FILEAUTHOR', $file['#'])) {
 | 
        
           |  |  | 2543 |                 $filerecord['author'] = $file['#']['FILEAUTHOR'][0]['#'];
 | 
        
           |  |  | 2544 |             }
 | 
        
           |  |  | 2545 |             if (array_key_exists('FILELICENSE', $file['#'])) {
 | 
        
           |  |  | 2546 |                 $license = $file['#']['FILELICENSE'][0]['#'];
 | 
        
           |  |  | 2547 |                 require_once($CFG->libdir . "/licenselib.php");
 | 
        
           |  |  | 2548 |                 if (license_manager::get_license_by_shortname($license)) {
 | 
        
           |  |  | 2549 |                     $filerecord['license'] = $license;
 | 
        
           |  |  | 2550 |                 }
 | 
        
           |  |  | 2551 |             }
 | 
        
           |  |  | 2552 |             $content =  $file['#']['CONTENTS'][0]['#'];
 | 
        
           |  |  | 2553 |             $fs->create_file_from_string($filerecord, base64_decode($content));
 | 
        
           |  |  | 2554 |             $count++;
 | 
        
           |  |  | 2555 |         }
 | 
        
           |  |  | 2556 |     }
 | 
        
           |  |  | 2557 |     return $count;
 | 
        
           |  |  | 2558 | }
 | 
        
           |  |  | 2559 |   | 
        
           |  |  | 2560 | /**
 | 
        
           |  |  | 2561 |  * How many unrated entries are in the given glossary for a given user?
 | 
        
           |  |  | 2562 |  *
 | 
        
           |  |  | 2563 |  * @global moodle_database $DB
 | 
        
           |  |  | 2564 |  * @param int $glossaryid
 | 
        
           |  |  | 2565 |  * @param int $userid
 | 
        
           |  |  | 2566 |  * @return int
 | 
        
           |  |  | 2567 |  */
 | 
        
           |  |  | 2568 | function glossary_count_unrated_entries($glossaryid, $userid) {
 | 
        
           |  |  | 2569 |     global $DB;
 | 
        
           |  |  | 2570 |   | 
        
           |  |  | 2571 |     $sql = "SELECT COUNT('x') as num
 | 
        
           |  |  | 2572 |               FROM {glossary_entries}
 | 
        
           |  |  | 2573 |              WHERE glossaryid = :glossaryid AND
 | 
        
           |  |  | 2574 |                    userid <> :userid";
 | 
        
           |  |  | 2575 |     $params = array('glossaryid' => $glossaryid, 'userid' => $userid);
 | 
        
           |  |  | 2576 |     $entries = $DB->count_records_sql($sql, $params);
 | 
        
           |  |  | 2577 |   | 
        
           |  |  | 2578 |     if ($entries) {
 | 
        
           |  |  | 2579 |         // We need to get the contextid for the glossaryid we have been given.
 | 
        
           |  |  | 2580 |         $sql = "SELECT ctx.id
 | 
        
           |  |  | 2581 |                   FROM {context} ctx
 | 
        
           |  |  | 2582 |                   JOIN {course_modules} cm ON cm.id = ctx.instanceid
 | 
        
           |  |  | 2583 |                   JOIN {modules} m ON m.id = cm.module
 | 
        
           |  |  | 2584 |                   JOIN {glossary} g ON g.id = cm.instance
 | 
        
           |  |  | 2585 |                  WHERE ctx.contextlevel = :contextlevel AND
 | 
        
           |  |  | 2586 |                        m.name = 'glossary' AND
 | 
        
           |  |  | 2587 |                        g.id = :glossaryid";
 | 
        
           |  |  | 2588 |         $contextid = $DB->get_field_sql($sql, array('glossaryid' => $glossaryid, 'contextlevel' => CONTEXT_MODULE));
 | 
        
           |  |  | 2589 |   | 
        
           |  |  | 2590 |         // Now we need to count the ratings that this user has made
 | 
        
           |  |  | 2591 |         $sql = "SELECT COUNT('x') AS num
 | 
        
           |  |  | 2592 |                   FROM {glossary_entries} e
 | 
        
           |  |  | 2593 |                   JOIN {rating} r ON r.itemid = e.id
 | 
        
           |  |  | 2594 |                  WHERE e.glossaryid = :glossaryid AND
 | 
        
           |  |  | 2595 |                        r.userid = :userid AND
 | 
        
           |  |  | 2596 |                        r.component = 'mod_glossary' AND
 | 
        
           |  |  | 2597 |                        r.ratingarea = 'entry' AND
 | 
        
           |  |  | 2598 |                        r.contextid = :contextid";
 | 
        
           |  |  | 2599 |         $params = array('glossaryid' => $glossaryid, 'userid' => $userid, 'contextid' => $contextid);
 | 
        
           |  |  | 2600 |         $rated = $DB->count_records_sql($sql, $params);
 | 
        
           |  |  | 2601 |         if ($rated) {
 | 
        
           |  |  | 2602 |             // The number or enties minus the number or rated entries equals the number of unrated
 | 
        
           |  |  | 2603 |             // entries
 | 
        
           |  |  | 2604 |             if ($entries > $rated) {
 | 
        
           |  |  | 2605 |                 return $entries - $rated;
 | 
        
           |  |  | 2606 |             } else {
 | 
        
           |  |  | 2607 |                 return 0;    // Just in case there was a counting error
 | 
        
           |  |  | 2608 |             }
 | 
        
           |  |  | 2609 |         } else {
 | 
        
           |  |  | 2610 |             return (int)$entries;
 | 
        
           |  |  | 2611 |         }
 | 
        
           |  |  | 2612 |     } else {
 | 
        
           |  |  | 2613 |         return 0;
 | 
        
           |  |  | 2614 |     }
 | 
        
           |  |  | 2615 | }
 | 
        
           |  |  | 2616 |   | 
        
           |  |  | 2617 | /**
 | 
        
           |  |  | 2618 |  *
 | 
        
           |  |  | 2619 |  * Returns the html code to represent any pagging bar. Paramenters are:
 | 
        
           |  |  | 2620 |  *
 | 
        
           |  |  | 2621 |  * The function dinamically show the first and last pages, and "scroll" over pages.
 | 
        
           |  |  | 2622 |  * Fully compatible with Moodle's print_paging_bar() function. Perhaps some day this
 | 
        
           |  |  | 2623 |  * could replace the general one. ;-)
 | 
        
           |  |  | 2624 |  *
 | 
        
           |  |  | 2625 |  * @param int $totalcount total number of records to be displayed
 | 
        
           |  |  | 2626 |  * @param int $page page currently selected (0 based)
 | 
        
           |  |  | 2627 |  * @param int $perpage number of records per page
 | 
        
           |  |  | 2628 |  * @param string $baseurl url to link in each page, the string 'page=XX' will be added automatically.
 | 
        
           |  |  | 2629 |  *
 | 
        
           |  |  | 2630 |  * @param int $maxpageallowed Optional maximum number of page allowed.
 | 
        
           |  |  | 2631 |  * @param int $maxdisplay Optional maximum number of page links to show in the bar
 | 
        
           |  |  | 2632 |  * @param string $separator Optional string to be used between pages in the bar
 | 
        
           |  |  | 2633 |  * @param string $specialtext Optional string to be showed as an special link
 | 
        
           |  |  | 2634 |  * @param string $specialvalue Optional value (page) to be used in the special link
 | 
        
           |  |  | 2635 |  * @param bool $previousandnext Optional to decide if we want the previous and next links
 | 
        
           |  |  | 2636 |  * @return string
 | 
        
           |  |  | 2637 |  */
 | 
        
           |  |  | 2638 | function glossary_get_paging_bar($totalcount, $page, $perpage, $baseurl, $maxpageallowed=99999, $maxdisplay=20, $separator=" ", $specialtext="", $specialvalue=-1, $previousandnext = true) {
 | 
        
           |  |  | 2639 |   | 
        
           |  |  | 2640 |     $code = '';
 | 
        
           |  |  | 2641 |   | 
        
           |  |  | 2642 |     $showspecial = false;
 | 
        
           |  |  | 2643 |     $specialselected = false;
 | 
        
           |  |  | 2644 |   | 
        
           |  |  | 2645 |     //Check if we have to show the special link
 | 
        
           |  |  | 2646 |     if (!empty($specialtext)) {
 | 
        
           |  |  | 2647 |         $showspecial = true;
 | 
        
           |  |  | 2648 |     }
 | 
        
           |  |  | 2649 |     //Check if we are with the special link selected
 | 
        
           |  |  | 2650 |     if ($showspecial && $page == $specialvalue) {
 | 
        
           |  |  | 2651 |         $specialselected = true;
 | 
        
           |  |  | 2652 |     }
 | 
        
           |  |  | 2653 |   | 
        
           |  |  | 2654 |     //If there are results (more than 1 page)
 | 
        
           |  |  | 2655 |     if ($totalcount > $perpage) {
 | 
        
           |  |  | 2656 |         $code .= "<div style=\"text-align:center\">";
 | 
        
           |  |  | 2657 |         $code .= "<p>".get_string("page").":";
 | 
        
           |  |  | 2658 |   | 
        
           |  |  | 2659 |         $maxpage = (int)(($totalcount-1)/$perpage);
 | 
        
           |  |  | 2660 |   | 
        
           |  |  | 2661 |         //Lower and upper limit of page
 | 
        
           |  |  | 2662 |         if ($page < 0) {
 | 
        
           |  |  | 2663 |             $page = 0;
 | 
        
           |  |  | 2664 |         }
 | 
        
           |  |  | 2665 |         if ($page > $maxpageallowed) {
 | 
        
           |  |  | 2666 |             $page = $maxpageallowed;
 | 
        
           |  |  | 2667 |         }
 | 
        
           |  |  | 2668 |         if ($page > $maxpage) {
 | 
        
           |  |  | 2669 |             $page = $maxpage;
 | 
        
           |  |  | 2670 |         }
 | 
        
           |  |  | 2671 |   | 
        
           |  |  | 2672 |         //Calculate the window of pages
 | 
        
           |  |  | 2673 |         $pagefrom = $page - ((int)($maxdisplay / 2));
 | 
        
           |  |  | 2674 |         if ($pagefrom < 0) {
 | 
        
           |  |  | 2675 |             $pagefrom = 0;
 | 
        
           |  |  | 2676 |         }
 | 
        
           |  |  | 2677 |         $pageto = $pagefrom + $maxdisplay - 1;
 | 
        
           |  |  | 2678 |         if ($pageto > $maxpageallowed) {
 | 
        
           |  |  | 2679 |             $pageto = $maxpageallowed;
 | 
        
           |  |  | 2680 |         }
 | 
        
           |  |  | 2681 |         if ($pageto > $maxpage) {
 | 
        
           |  |  | 2682 |             $pageto = $maxpage;
 | 
        
           |  |  | 2683 |         }
 | 
        
           |  |  | 2684 |   | 
        
           |  |  | 2685 |         //Some movements can be necessary if don't see enought pages
 | 
        
           |  |  | 2686 |         if ($pageto - $pagefrom < $maxdisplay - 1) {
 | 
        
           |  |  | 2687 |             if ($pageto - $maxdisplay + 1 > 0) {
 | 
        
           |  |  | 2688 |                 $pagefrom = $pageto - $maxdisplay + 1;
 | 
        
           |  |  | 2689 |             }
 | 
        
           |  |  | 2690 |         }
 | 
        
           |  |  | 2691 |   | 
        
           |  |  | 2692 |         //Calculate first and last if necessary
 | 
        
           |  |  | 2693 |         $firstpagecode = '';
 | 
        
           |  |  | 2694 |         $lastpagecode = '';
 | 
        
           |  |  | 2695 |         if ($pagefrom > 0) {
 | 
        
           |  |  | 2696 |             $firstpagecode = "$separator<a href=\"{$baseurl}page=0\">1</a>";
 | 
        
           |  |  | 2697 |             if ($pagefrom > 1) {
 | 
        
           |  |  | 2698 |                 $firstpagecode .= "$separator...";
 | 
        
           |  |  | 2699 |             }
 | 
        
           |  |  | 2700 |         }
 | 
        
           |  |  | 2701 |         if ($pageto < $maxpage) {
 | 
        
           |  |  | 2702 |             if ($pageto < $maxpage -1) {
 | 
        
           |  |  | 2703 |                 $lastpagecode = "$separator...";
 | 
        
           |  |  | 2704 |             }
 | 
        
           |  |  | 2705 |             $lastpagecode .= "$separator<a href=\"{$baseurl}page=$maxpage\">".($maxpage+1)."</a>";
 | 
        
           |  |  | 2706 |         }
 | 
        
           |  |  | 2707 |   | 
        
           |  |  | 2708 |         //Previous
 | 
        
           |  |  | 2709 |         if ($page > 0 && $previousandnext) {
 | 
        
           |  |  | 2710 |             $pagenum = $page - 1;
 | 
        
           |  |  | 2711 |             $code .= " (<a  href=\"{$baseurl}page=$pagenum\">".get_string("previous")."</a>) ";
 | 
        
           |  |  | 2712 |         }
 | 
        
           |  |  | 2713 |   | 
        
           |  |  | 2714 |         //Add first
 | 
        
           |  |  | 2715 |         $code .= $firstpagecode;
 | 
        
           |  |  | 2716 |   | 
        
           |  |  | 2717 |         $pagenum = $pagefrom;
 | 
        
           |  |  | 2718 |   | 
        
           |  |  | 2719 |         //List of maxdisplay pages
 | 
        
           |  |  | 2720 |         while ($pagenum <= $pageto) {
 | 
        
           |  |  | 2721 |             $pagetoshow = $pagenum +1;
 | 
        
           |  |  | 2722 |             if ($pagenum == $page && !$specialselected) {
 | 
        
           |  |  | 2723 |                 $code .= "$separator<b>$pagetoshow</b>";
 | 
        
           |  |  | 2724 |             } else {
 | 
        
           |  |  | 2725 |                 $code .= "$separator<a href=\"{$baseurl}page=$pagenum\">$pagetoshow</a>";
 | 
        
           |  |  | 2726 |             }
 | 
        
           |  |  | 2727 |             $pagenum++;
 | 
        
           |  |  | 2728 |         }
 | 
        
           |  |  | 2729 |   | 
        
           |  |  | 2730 |         //Add last
 | 
        
           |  |  | 2731 |         $code .= $lastpagecode;
 | 
        
           |  |  | 2732 |   | 
        
           |  |  | 2733 |         //Next
 | 
        
           |  |  | 2734 |         if ($page < $maxpage && $page < $maxpageallowed && $previousandnext) {
 | 
        
           |  |  | 2735 |             $pagenum = $page + 1;
 | 
        
           |  |  | 2736 |             $code .= "$separator(<a href=\"{$baseurl}page=$pagenum\">".get_string("next")."</a>)";
 | 
        
           |  |  | 2737 |         }
 | 
        
           |  |  | 2738 |   | 
        
           |  |  | 2739 |         //Add special
 | 
        
           |  |  | 2740 |         if ($showspecial) {
 | 
        
           |  |  | 2741 |             $code .= '<br />';
 | 
        
           |  |  | 2742 |             if ($specialselected) {
 | 
        
           |  |  | 2743 |                 $code .= "$separator<b>$specialtext</b>";
 | 
        
           |  |  | 2744 |             } else {
 | 
        
           |  |  | 2745 |                 $code .= "$separator<a href=\"{$baseurl}page=$specialvalue\">$specialtext</a>";
 | 
        
           |  |  | 2746 |             }
 | 
        
           |  |  | 2747 |         }
 | 
        
           |  |  | 2748 |   | 
        
           |  |  | 2749 |         //End html
 | 
        
           |  |  | 2750 |         $code .= "</p>";
 | 
        
           |  |  | 2751 |         $code .= "</div>";
 | 
        
           |  |  | 2752 |     }
 | 
        
           |  |  | 2753 |   | 
        
           |  |  | 2754 |     return $code;
 | 
        
           |  |  | 2755 | }
 | 
        
           |  |  | 2756 |   | 
        
           |  |  | 2757 | /**
 | 
        
           |  |  | 2758 |  * List the actions that correspond to a view of this module.
 | 
        
           |  |  | 2759 |  * This is used by the participation report.
 | 
        
           |  |  | 2760 |  *
 | 
        
           |  |  | 2761 |  * Note: This is not used by new logging system. Event with
 | 
        
           |  |  | 2762 |  *       crud = 'r' and edulevel = LEVEL_PARTICIPATING will
 | 
        
           |  |  | 2763 |  *       be considered as view action.
 | 
        
           |  |  | 2764 |  *
 | 
        
           |  |  | 2765 |  * @return array
 | 
        
           |  |  | 2766 |  */
 | 
        
           |  |  | 2767 | function glossary_get_view_actions() {
 | 
        
           |  |  | 2768 |     return array('view','view all','view entry');
 | 
        
           |  |  | 2769 | }
 | 
        
           |  |  | 2770 |   | 
        
           |  |  | 2771 | /**
 | 
        
           |  |  | 2772 |  * List the actions that correspond to a post of this module.
 | 
        
           |  |  | 2773 |  * This is used by the participation report.
 | 
        
           |  |  | 2774 |  *
 | 
        
           |  |  | 2775 |  * Note: This is not used by new logging system. Event with
 | 
        
           |  |  | 2776 |  *       crud = ('c' || 'u' || 'd') and edulevel = LEVEL_PARTICIPATING
 | 
        
           |  |  | 2777 |  *       will be considered as post action.
 | 
        
           |  |  | 2778 |  *
 | 
        
           |  |  | 2779 |  * @return array
 | 
        
           |  |  | 2780 |  */
 | 
        
           |  |  | 2781 | function glossary_get_post_actions() {
 | 
        
           |  |  | 2782 |     return array('add category','add entry','approve entry','delete category','delete entry','edit category','update entry');
 | 
        
           |  |  | 2783 | }
 | 
        
           |  |  | 2784 |   | 
        
           |  |  | 2785 |   | 
        
           |  |  | 2786 | /**
 | 
        
           |  |  | 2787 |  * Implementation of the function for printing the form elements that control
 | 
        
           |  |  | 2788 |  * whether the course reset functionality affects the glossary.
 | 
        
           |  |  | 2789 |  * @param MoodleQuickForm $mform form passed by reference
 | 
        
           |  |  | 2790 |  */
 | 
        
           |  |  | 2791 | function glossary_reset_course_form_definition(&$mform) {
 | 
        
           |  |  | 2792 |     $mform->addElement('header', 'glossaryheader', get_string('modulenameplural', 'glossary'));
 | 
        
           | 1441 | ariadna | 2793 |     $mform->addElement('static', 'glossarydelete', get_string('delete'));
 | 
        
           | 1 | efrain | 2794 |     $mform->addElement('checkbox', 'reset_glossary_all', get_string('resetglossariesall','glossary'));
 | 
        
           |  |  | 2795 |   | 
        
           |  |  | 2796 |     $mform->addElement('select', 'reset_glossary_types', get_string('resetglossaries', 'glossary'),
 | 
        
           |  |  | 2797 |                        array('main'=>get_string('mainglossary', 'glossary'), 'secondary'=>get_string('secondaryglossary', 'glossary')), array('multiple' => 'multiple'));
 | 
        
           | 1441 | ariadna | 2798 |     $mform->hideIf('reset_glossary_types', 'reset_glossary_all', 'checked');
 | 
        
           | 1 | efrain | 2799 |   | 
        
           |  |  | 2800 |     $mform->addElement('checkbox', 'reset_glossary_notenrolled', get_string('deletenotenrolled', 'glossary'));
 | 
        
           | 1441 | ariadna | 2801 |     $mform->hideIf('reset_glossary_notenrolled', 'reset_glossary_all', 'checked');
 | 
        
           | 1 | efrain | 2802 |   | 
        
           |  |  | 2803 |     $mform->addElement('checkbox', 'reset_glossary_ratings', get_string('deleteallratings'));
 | 
        
           | 1441 | ariadna | 2804 |     $mform->hideIf('reset_glossary_ratings', 'reset_glossary_all', 'checked');
 | 
        
           | 1 | efrain | 2805 |   | 
        
           |  |  | 2806 |     $mform->addElement('checkbox', 'reset_glossary_comments', get_string('deleteallcomments'));
 | 
        
           | 1441 | ariadna | 2807 |     $mform->hideIf('reset_glossary_comments', 'reset_glossary_all', 'checked');
 | 
        
           | 1 | efrain | 2808 |   | 
        
           |  |  | 2809 |     $mform->addElement('checkbox', 'reset_glossary_tags', get_string('removeallglossarytags', 'glossary'));
 | 
        
           | 1441 | ariadna | 2810 |     $mform->hideIf('reset_glossary_tags', 'reset_glossary_all', 'checked');
 | 
        
           | 1 | efrain | 2811 | }
 | 
        
           |  |  | 2812 |   | 
        
           |  |  | 2813 | /**
 | 
        
           |  |  | 2814 |  * Course reset form defaults.
 | 
        
           |  |  | 2815 |  * @return array
 | 
        
           |  |  | 2816 |  */
 | 
        
           |  |  | 2817 | function glossary_reset_course_form_defaults($course) {
 | 
        
           |  |  | 2818 |     return array('reset_glossary_all'=>0, 'reset_glossary_ratings'=>1, 'reset_glossary_comments'=>1, 'reset_glossary_notenrolled'=>0);
 | 
        
           |  |  | 2819 | }
 | 
        
           |  |  | 2820 |   | 
        
           |  |  | 2821 | /**
 | 
        
           |  |  | 2822 |  * Removes all grades from gradebook
 | 
        
           |  |  | 2823 |  *
 | 
        
           |  |  | 2824 |  * @param int $courseid The ID of the course to reset
 | 
        
           |  |  | 2825 |  * @param string $type The optional type of glossary. 'main', 'secondary' or ''
 | 
        
           |  |  | 2826 |  */
 | 
        
           |  |  | 2827 | function glossary_reset_gradebook($courseid, $type='') {
 | 
        
           |  |  | 2828 |     global $DB;
 | 
        
           |  |  | 2829 |   | 
        
           |  |  | 2830 |     switch ($type) {
 | 
        
           |  |  | 2831 |         case 'main'      : $type = "AND g.mainglossary=1"; break;
 | 
        
           |  |  | 2832 |         case 'secondary' : $type = "AND g.mainglossary=0"; break;
 | 
        
           |  |  | 2833 |         default          : $type = ""; //all
 | 
        
           |  |  | 2834 |     }
 | 
        
           |  |  | 2835 |   | 
        
           |  |  | 2836 |     $sql = "SELECT g.*, cm.idnumber as cmidnumber, g.course as courseid
 | 
        
           |  |  | 2837 |               FROM {glossary} g, {course_modules} cm, {modules} m
 | 
        
           |  |  | 2838 |              WHERE m.name='glossary' AND m.id=cm.module AND cm.instance=g.id AND g.course=? $type";
 | 
        
           |  |  | 2839 |   | 
        
           |  |  | 2840 |     if ($glossarys = $DB->get_records_sql($sql, array($courseid))) {
 | 
        
           |  |  | 2841 |         foreach ($glossarys as $glossary) {
 | 
        
           |  |  | 2842 |             glossary_grade_item_update($glossary, 'reset');
 | 
        
           |  |  | 2843 |         }
 | 
        
           |  |  | 2844 |     }
 | 
        
           |  |  | 2845 | }
 | 
        
           |  |  | 2846 | /**
 | 
        
           |  |  | 2847 |  * Actual implementation of the reset course functionality, delete all the
 | 
        
           |  |  | 2848 |  * glossary responses for course $data->courseid.
 | 
        
           |  |  | 2849 |  *
 | 
        
           |  |  | 2850 |  * @global object
 | 
        
           |  |  | 2851 |  * @param $data the data submitted from the reset course.
 | 
        
           |  |  | 2852 |  * @return array status array
 | 
        
           |  |  | 2853 |  */
 | 
        
           |  |  | 2854 | function glossary_reset_userdata($data) {
 | 
        
           |  |  | 2855 |     global $CFG, $DB;
 | 
        
           |  |  | 2856 |     require_once($CFG->dirroot.'/rating/lib.php');
 | 
        
           |  |  | 2857 |   | 
        
           |  |  | 2858 |     $componentstr = get_string('modulenameplural', 'glossary');
 | 
        
           | 1441 | ariadna | 2859 |     $status = [];
 | 
        
           | 1 | efrain | 2860 |   | 
        
           |  |  | 2861 |     $allentriessql = "SELECT e.id
 | 
        
           |  |  | 2862 |                         FROM {glossary_entries} e
 | 
        
           |  |  | 2863 |                              JOIN {glossary} g ON e.glossaryid = g.id
 | 
        
           |  |  | 2864 |                        WHERE g.course = ?";
 | 
        
           |  |  | 2865 |   | 
        
           |  |  | 2866 |     $allglossariessql = "SELECT g.id
 | 
        
           |  |  | 2867 |                            FROM {glossary} g
 | 
        
           |  |  | 2868 |                           WHERE g.course = ?";
 | 
        
           |  |  | 2869 |   | 
        
           | 1441 | ariadna | 2870 |     $params = [$data->courseid];
 | 
        
           | 1 | efrain | 2871 |   | 
        
           |  |  | 2872 |     $fs = get_file_storage();
 | 
        
           |  |  | 2873 |   | 
        
           |  |  | 2874 |     $rm = new rating_manager();
 | 
        
           |  |  | 2875 |     $ratingdeloptions = new stdClass;
 | 
        
           |  |  | 2876 |     $ratingdeloptions->component = 'mod_glossary';
 | 
        
           |  |  | 2877 |     $ratingdeloptions->ratingarea = 'entry';
 | 
        
           |  |  | 2878 |   | 
        
           | 1441 | ariadna | 2879 |     // Delete entries if requested.
 | 
        
           | 1 | efrain | 2880 |     if (!empty($data->reset_glossary_all)
 | 
        
           |  |  | 2881 |          or (!empty($data->reset_glossary_types) and in_array('main', $data->reset_glossary_types) and in_array('secondary', $data->reset_glossary_types))) {
 | 
        
           |  |  | 2882 |   | 
        
           |  |  | 2883 |         $params[] = 'glossary_entry';
 | 
        
           |  |  | 2884 |         $DB->delete_records_select('comments', "itemid IN ($allentriessql) AND commentarea=?", $params);
 | 
        
           |  |  | 2885 |         $DB->delete_records_select('glossary_alias',    "entryid IN ($allentriessql)", $params);
 | 
        
           |  |  | 2886 |         $DB->delete_records_select('glossary_entries', "glossaryid IN ($allglossariessql)", $params);
 | 
        
           |  |  | 2887 |   | 
        
           | 1441 | ariadna | 2888 |         // Now get rid of all attachments.
 | 
        
           | 1 | efrain | 2889 |         if ($glossaries = $DB->get_records_sql($allglossariessql, $params)) {
 | 
        
           |  |  | 2890 |             foreach ($glossaries as $glossaryid=>$unused) {
 | 
        
           |  |  | 2891 |                 if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) {
 | 
        
           |  |  | 2892 |                     continue;
 | 
        
           |  |  | 2893 |                 }
 | 
        
           |  |  | 2894 |                 $context = context_module::instance($cm->id);
 | 
        
           |  |  | 2895 |                 $fs->delete_area_files($context->id, 'mod_glossary', 'attachment');
 | 
        
           |  |  | 2896 |   | 
        
           | 1441 | ariadna | 2897 |                 // Delete ratings.
 | 
        
           | 1 | efrain | 2898 |                 $ratingdeloptions->contextid = $context->id;
 | 
        
           |  |  | 2899 |                 $rm->delete_ratings($ratingdeloptions);
 | 
        
           |  |  | 2900 |   | 
        
           |  |  | 2901 |                 core_tag_tag::delete_instances('mod_glossary', null, $context->id);
 | 
        
           |  |  | 2902 |             }
 | 
        
           |  |  | 2903 |         }
 | 
        
           |  |  | 2904 |   | 
        
           | 1441 | ariadna | 2905 |         // Remove all grades from gradebook.
 | 
        
           | 1 | efrain | 2906 |         if (empty($data->reset_gradebook_grades)) {
 | 
        
           |  |  | 2907 |             glossary_reset_gradebook($data->courseid);
 | 
        
           |  |  | 2908 |         }
 | 
        
           |  |  | 2909 |   | 
        
           | 1441 | ariadna | 2910 |         $status[] = [
 | 
        
           |  |  | 2911 |             'component' => $componentstr,
 | 
        
           |  |  | 2912 |             'item' => get_string('resetglossariesall', 'glossary'),
 | 
        
           |  |  | 2913 |             'error' => false,
 | 
        
           |  |  | 2914 |         ];
 | 
        
           | 1 | efrain | 2915 |   | 
        
           |  |  | 2916 |     } else if (!empty($data->reset_glossary_types)) {
 | 
        
           | 1441 | ariadna | 2917 |         $mainentriessql = "$allentriessql AND g.mainglossary=1";
 | 
        
           |  |  | 2918 |         $secondaryentriessql = "$allentriessql AND g.mainglossary=0";
 | 
        
           | 1 | efrain | 2919 |   | 
        
           | 1441 | ariadna | 2920 |         $mainglossariessql = "$allglossariessql AND g.mainglossary=1";
 | 
        
           | 1 | efrain | 2921 |         $secondaryglossariessql = "$allglossariessql AND g.mainglossary=0";
 | 
        
           |  |  | 2922 |   | 
        
           |  |  | 2923 |         if (in_array('main', $data->reset_glossary_types)) {
 | 
        
           |  |  | 2924 |             $params[] = 'glossary_entry';
 | 
        
           |  |  | 2925 |             $DB->delete_records_select('comments', "itemid IN ($mainentriessql) AND commentarea=?", $params);
 | 
        
           |  |  | 2926 |             $DB->delete_records_select('glossary_entries', "glossaryid IN ($mainglossariessql)", $params);
 | 
        
           |  |  | 2927 |   | 
        
           |  |  | 2928 |             if ($glossaries = $DB->get_records_sql($mainglossariessql, $params)) {
 | 
        
           |  |  | 2929 |                 foreach ($glossaries as $glossaryid=>$unused) {
 | 
        
           |  |  | 2930 |                     if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) {
 | 
        
           |  |  | 2931 |                         continue;
 | 
        
           |  |  | 2932 |                     }
 | 
        
           |  |  | 2933 |                     $context = context_module::instance($cm->id);
 | 
        
           |  |  | 2934 |                     $fs->delete_area_files($context->id, 'mod_glossary', 'attachment');
 | 
        
           |  |  | 2935 |   | 
        
           | 1441 | ariadna | 2936 |                     // Delete ratings.
 | 
        
           | 1 | efrain | 2937 |                     $ratingdeloptions->contextid = $context->id;
 | 
        
           |  |  | 2938 |                     $rm->delete_ratings($ratingdeloptions);
 | 
        
           |  |  | 2939 |   | 
        
           |  |  | 2940 |                     core_tag_tag::delete_instances('mod_glossary', null, $context->id);
 | 
        
           |  |  | 2941 |                 }
 | 
        
           |  |  | 2942 |             }
 | 
        
           |  |  | 2943 |   | 
        
           | 1441 | ariadna | 2944 |             // Remove all grades from gradebook.
 | 
        
           | 1 | efrain | 2945 |             if (empty($data->reset_gradebook_grades)) {
 | 
        
           |  |  | 2946 |                 glossary_reset_gradebook($data->courseid, 'main');
 | 
        
           |  |  | 2947 |             }
 | 
        
           |  |  | 2948 |   | 
        
           | 1441 | ariadna | 2949 |             $status[] = [
 | 
        
           |  |  | 2950 |                 'component' => $componentstr,
 | 
        
           |  |  | 2951 |                 'item' => get_string('resetglossaries', 'glossary').': '.get_string('mainglossary', 'glossary'),
 | 
        
           |  |  | 2952 |                 'error' => false,
 | 
        
           |  |  | 2953 |             ];
 | 
        
           | 1 | efrain | 2954 |   | 
        
           |  |  | 2955 |         } else if (in_array('secondary', $data->reset_glossary_types)) {
 | 
        
           |  |  | 2956 |             $params[] = 'glossary_entry';
 | 
        
           |  |  | 2957 |             $DB->delete_records_select('comments', "itemid IN ($secondaryentriessql) AND commentarea=?", $params);
 | 
        
           |  |  | 2958 |             $DB->delete_records_select('glossary_entries', "glossaryid IN ($secondaryglossariessql)", $params);
 | 
        
           | 1441 | ariadna | 2959 |             // Remove exported source flag from entries in main glossary.
 | 
        
           | 1 | efrain | 2960 |             $DB->execute("UPDATE {glossary_entries}
 | 
        
           |  |  | 2961 |                              SET sourceglossaryid=0
 | 
        
           |  |  | 2962 |                            WHERE glossaryid IN ($mainglossariessql)", $params);
 | 
        
           |  |  | 2963 |   | 
        
           |  |  | 2964 |             if ($glossaries = $DB->get_records_sql($secondaryglossariessql, $params)) {
 | 
        
           |  |  | 2965 |                 foreach ($glossaries as $glossaryid=>$unused) {
 | 
        
           |  |  | 2966 |                     if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) {
 | 
        
           |  |  | 2967 |                         continue;
 | 
        
           |  |  | 2968 |                     }
 | 
        
           |  |  | 2969 |                     $context = context_module::instance($cm->id);
 | 
        
           |  |  | 2970 |                     $fs->delete_area_files($context->id, 'mod_glossary', 'attachment');
 | 
        
           |  |  | 2971 |   | 
        
           | 1441 | ariadna | 2972 |                     // Delete ratings.
 | 
        
           | 1 | efrain | 2973 |                     $ratingdeloptions->contextid = $context->id;
 | 
        
           |  |  | 2974 |                     $rm->delete_ratings($ratingdeloptions);
 | 
        
           |  |  | 2975 |   | 
        
           |  |  | 2976 |                     core_tag_tag::delete_instances('mod_glossary', null, $context->id);
 | 
        
           |  |  | 2977 |                 }
 | 
        
           |  |  | 2978 |             }
 | 
        
           |  |  | 2979 |   | 
        
           | 1441 | ariadna | 2980 |             // Remove all grades from gradebook.
 | 
        
           | 1 | efrain | 2981 |             if (empty($data->reset_gradebook_grades)) {
 | 
        
           |  |  | 2982 |                 glossary_reset_gradebook($data->courseid, 'secondary');
 | 
        
           |  |  | 2983 |             }
 | 
        
           |  |  | 2984 |   | 
        
           | 1441 | ariadna | 2985 |             $status[] = [
 | 
        
           |  |  | 2986 |                 'component' => $componentstr,
 | 
        
           |  |  | 2987 |                 'item' => get_string('resetglossaries', 'glossary').': '.get_string('secondaryglossary', 'glossary'),
 | 
        
           |  |  | 2988 |                 'error' => false,
 | 
        
           |  |  | 2989 |             ];
 | 
        
           | 1 | efrain | 2990 |         }
 | 
        
           |  |  | 2991 |     }
 | 
        
           |  |  | 2992 |   | 
        
           | 1441 | ariadna | 2993 |     // Remove entries by users not enrolled into course.
 | 
        
           | 1 | efrain | 2994 |     if (!empty($data->reset_glossary_notenrolled)) {
 | 
        
           |  |  | 2995 |         $entriessql = "SELECT e.id, e.userid, e.glossaryid, u.id AS userexists, u.deleted AS userdeleted
 | 
        
           |  |  | 2996 |                          FROM {glossary_entries} e
 | 
        
           |  |  | 2997 |                               JOIN {glossary} g ON e.glossaryid = g.id
 | 
        
           |  |  | 2998 |                               LEFT JOIN {user} u ON e.userid = u.id
 | 
        
           |  |  | 2999 |                         WHERE g.course = ? AND e.userid > 0";
 | 
        
           |  |  | 3000 |   | 
        
           | 1441 | ariadna | 3001 |         $coursecontext = context_course::instance($data->courseid);
 | 
        
           |  |  | 3002 |         $notenrolled = [];
 | 
        
           | 1 | efrain | 3003 |         $rs = $DB->get_recordset_sql($entriessql, $params);
 | 
        
           |  |  | 3004 |         if ($rs->valid()) {
 | 
        
           |  |  | 3005 |             foreach ($rs as $entry) {
 | 
        
           | 1441 | ariadna | 3006 |                 if (array_key_exists($entry->userid, $notenrolled) || !$entry->userexists || $entry->userdeleted
 | 
        
           |  |  | 3007 |                   || !is_enrolled($coursecontext , $entry->userid)) {
 | 
        
           |  |  | 3008 |                     $DB->delete_records('comments', ['commentarea' => 'glossary_entry', 'itemid' => $entry->id]);
 | 
        
           |  |  | 3009 |                     $DB->delete_records('glossary_entries', ['id' => $entry->id]);
 | 
        
           | 1 | efrain | 3010 |   | 
        
           |  |  | 3011 |                     if ($cm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) {
 | 
        
           |  |  | 3012 |                         $context = context_module::instance($cm->id);
 | 
        
           |  |  | 3013 |                         $fs->delete_area_files($context->id, 'mod_glossary', 'attachment', $entry->id);
 | 
        
           |  |  | 3014 |   | 
        
           |  |  | 3015 |                         //delete ratings
 | 
        
           |  |  | 3016 |                         $ratingdeloptions->contextid = $context->id;
 | 
        
           |  |  | 3017 |                         $rm->delete_ratings($ratingdeloptions);
 | 
        
           |  |  | 3018 |                     }
 | 
        
           |  |  | 3019 |                 }
 | 
        
           |  |  | 3020 |             }
 | 
        
           | 1441 | ariadna | 3021 |             $status[] = [
 | 
        
           |  |  | 3022 |                 'component' => $componentstr,
 | 
        
           |  |  | 3023 |                 'item' => get_string('deletenotenrolled', 'glossary'),
 | 
        
           |  |  | 3024 |                 'error' => false,
 | 
        
           |  |  | 3025 |             ];
 | 
        
           | 1 | efrain | 3026 |         }
 | 
        
           |  |  | 3027 |         $rs->close();
 | 
        
           |  |  | 3028 |     }
 | 
        
           |  |  | 3029 |   | 
        
           | 1441 | ariadna | 3030 |     // Remove all ratings.
 | 
        
           | 1 | efrain | 3031 |     if (!empty($data->reset_glossary_ratings)) {
 | 
        
           | 1441 | ariadna | 3032 |         // Remove ratings.
 | 
        
           | 1 | efrain | 3033 |         if ($glossaries = $DB->get_records_sql($allglossariessql, $params)) {
 | 
        
           |  |  | 3034 |             foreach ($glossaries as $glossaryid=>$unused) {
 | 
        
           |  |  | 3035 |                 if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) {
 | 
        
           |  |  | 3036 |                     continue;
 | 
        
           |  |  | 3037 |                 }
 | 
        
           |  |  | 3038 |                 $context = context_module::instance($cm->id);
 | 
        
           |  |  | 3039 |   | 
        
           | 1441 | ariadna | 3040 |                 // Delete ratings.
 | 
        
           | 1 | efrain | 3041 |                 $ratingdeloptions->contextid = $context->id;
 | 
        
           |  |  | 3042 |                 $rm->delete_ratings($ratingdeloptions);
 | 
        
           |  |  | 3043 |             }
 | 
        
           |  |  | 3044 |         }
 | 
        
           |  |  | 3045 |   | 
        
           | 1441 | ariadna | 3046 |         // Remove all grades from gradebook.
 | 
        
           | 1 | efrain | 3047 |         if (empty($data->reset_gradebook_grades)) {
 | 
        
           |  |  | 3048 |             glossary_reset_gradebook($data->courseid);
 | 
        
           |  |  | 3049 |         }
 | 
        
           | 1441 | ariadna | 3050 |         $status[] = [
 | 
        
           |  |  | 3051 |             'component' => $componentstr,
 | 
        
           |  |  | 3052 |             'item' => get_string('deleteallratings'),
 | 
        
           |  |  | 3053 |             'error' => false,
 | 
        
           |  |  | 3054 |         ];
 | 
        
           | 1 | efrain | 3055 |     }
 | 
        
           |  |  | 3056 |   | 
        
           | 1441 | ariadna | 3057 |     // Remove comments.
 | 
        
           | 1 | efrain | 3058 |     if (!empty($data->reset_glossary_comments)) {
 | 
        
           |  |  | 3059 |         $params[] = 'glossary_entry';
 | 
        
           |  |  | 3060 |         $DB->delete_records_select('comments', "itemid IN ($allentriessql) AND commentarea= ? ", $params);
 | 
        
           | 1441 | ariadna | 3061 |         $status[] = [
 | 
        
           |  |  | 3062 |             'component' => $componentstr,
 | 
        
           |  |  | 3063 |             'item' => get_string('deleteallcomments'),
 | 
        
           |  |  | 3064 |             'error' => false,
 | 
        
           |  |  | 3065 |         ];
 | 
        
           | 1 | efrain | 3066 |     }
 | 
        
           |  |  | 3067 |   | 
        
           |  |  | 3068 |     // Remove all the tags.
 | 
        
           |  |  | 3069 |     if (!empty($data->reset_glossary_tags)) {
 | 
        
           |  |  | 3070 |         if ($glossaries = $DB->get_records_sql($allglossariessql, $params)) {
 | 
        
           |  |  | 3071 |             foreach ($glossaries as $glossaryid => $unused) {
 | 
        
           |  |  | 3072 |                 if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) {
 | 
        
           |  |  | 3073 |                     continue;
 | 
        
           |  |  | 3074 |                 }
 | 
        
           |  |  | 3075 |   | 
        
           |  |  | 3076 |                 $context = context_module::instance($cm->id);
 | 
        
           |  |  | 3077 |                 core_tag_tag::delete_instances('mod_glossary', null, $context->id);
 | 
        
           |  |  | 3078 |             }
 | 
        
           |  |  | 3079 |         }
 | 
        
           |  |  | 3080 |   | 
        
           | 1441 | ariadna | 3081 |         $status[] = [
 | 
        
           |  |  | 3082 |             'component' => $componentstr,
 | 
        
           |  |  | 3083 |             'item' => get_string('removeallglossarytags', 'glossary'),
 | 
        
           |  |  | 3084 |             'error' => false,
 | 
        
           |  |  | 3085 |         ];
 | 
        
           | 1 | efrain | 3086 |     }
 | 
        
           |  |  | 3087 |   | 
        
           | 1441 | ariadna | 3088 |     // Updating dates - shift may be negative too.
 | 
        
           | 1 | efrain | 3089 |     if ($data->timeshift) {
 | 
        
           |  |  | 3090 |         // Any changes to the list of dates that needs to be rolled should be same during course restore and course reset.
 | 
        
           |  |  | 3091 |         // See MDL-9367.
 | 
        
           | 1441 | ariadna | 3092 |         shift_course_mod_dates('glossary', ['assesstimestart', 'assesstimefinish'], $data->timeshift, $data->courseid);
 | 
        
           |  |  | 3093 |         $status[] = [
 | 
        
           |  |  | 3094 |             'component' => $componentstr,
 | 
        
           |  |  | 3095 |             'item' => get_string('date'),
 | 
        
           |  |  | 3096 |             'error' => false,
 | 
        
           |  |  | 3097 |         ];
 | 
        
           | 1 | efrain | 3098 |     }
 | 
        
           |  |  | 3099 |   | 
        
           |  |  | 3100 |     return $status;
 | 
        
           |  |  | 3101 | }
 | 
        
           |  |  | 3102 |   | 
        
           |  |  | 3103 | /**
 | 
        
           |  |  | 3104 |  * Returns all other caps used in module
 | 
        
           |  |  | 3105 |  * @return array
 | 
        
           |  |  | 3106 |  */
 | 
        
           |  |  | 3107 | function glossary_get_extra_capabilities() {
 | 
        
           |  |  | 3108 |     return ['moodle/rating:view', 'moodle/rating:viewany', 'moodle/rating:viewall', 'moodle/rating:rate',
 | 
        
           |  |  | 3109 |             'moodle/comment:view', 'moodle/comment:post', 'moodle/comment:delete'];
 | 
        
           |  |  | 3110 | }
 | 
        
           |  |  | 3111 |   | 
        
           |  |  | 3112 | /**
 | 
        
           |  |  | 3113 |  * @param string $feature FEATURE_xx constant for requested feature
 | 
        
           |  |  | 3114 |  * @return mixed True if module supports feature, false if not, null if doesn't know or string for the module purpose.
 | 
        
           |  |  | 3115 |  */
 | 
        
           |  |  | 3116 | function glossary_supports($feature) {
 | 
        
           |  |  | 3117 |     switch($feature) {
 | 
        
           |  |  | 3118 |         case FEATURE_GROUPS:                  return false;
 | 
        
           |  |  | 3119 |         case FEATURE_GROUPINGS:               return false;
 | 
        
           |  |  | 3120 |         case FEATURE_MOD_INTRO:               return true;
 | 
        
           |  |  | 3121 |         case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
 | 
        
           |  |  | 3122 |         case FEATURE_COMPLETION_HAS_RULES:    return true;
 | 
        
           |  |  | 3123 |         case FEATURE_GRADE_HAS_GRADE:         return true;
 | 
        
           |  |  | 3124 |         case FEATURE_GRADE_OUTCOMES:          return true;
 | 
        
           |  |  | 3125 |         case FEATURE_RATE:                    return true;
 | 
        
           |  |  | 3126 |         case FEATURE_BACKUP_MOODLE2:          return true;
 | 
        
           |  |  | 3127 |         case FEATURE_SHOW_DESCRIPTION:        return true;
 | 
        
           |  |  | 3128 |         case FEATURE_COMMENT:                 return true;
 | 
        
           |  |  | 3129 |         case FEATURE_MOD_PURPOSE:             return MOD_PURPOSE_COLLABORATION;
 | 
        
           |  |  | 3130 |   | 
        
           |  |  | 3131 |         default: return null;
 | 
        
           |  |  | 3132 |     }
 | 
        
           |  |  | 3133 | }
 | 
        
           |  |  | 3134 |   | 
        
           |  |  | 3135 | function glossary_extend_navigation($navigation, $course, $module, $cm) {
 | 
        
           |  |  | 3136 |     global $CFG, $DB;
 | 
        
           |  |  | 3137 |   | 
        
           |  |  | 3138 |     $displayformat = $DB->get_record('glossary_formats', array('name' => $module->displayformat));
 | 
        
           |  |  | 3139 |     // Get visible tabs for the format and check if the menu needs to be displayed.
 | 
        
           |  |  | 3140 |     $showtabs = glossary_get_visible_tabs($displayformat);
 | 
        
           |  |  | 3141 |   | 
        
           |  |  | 3142 |     foreach ($showtabs as $showtabkey => $showtabvalue) {
 | 
        
           |  |  | 3143 |   | 
        
           |  |  | 3144 |         switch($showtabvalue) {
 | 
        
           |  |  | 3145 |             case GLOSSARY_STANDARD :
 | 
        
           |  |  | 3146 |                 $navigation->add(get_string('standardview', 'glossary'), new moodle_url('/mod/glossary/view.php',
 | 
        
           |  |  | 3147 |                         array('id' => $cm->id, 'mode' => 'letter')));
 | 
        
           |  |  | 3148 |                 break;
 | 
        
           |  |  | 3149 |             case GLOSSARY_CATEGORY :
 | 
        
           |  |  | 3150 |                 $navigation->add(get_string('categoryview', 'glossary'), new moodle_url('/mod/glossary/view.php',
 | 
        
           |  |  | 3151 |                         array('id' => $cm->id, 'mode' => 'cat')));
 | 
        
           |  |  | 3152 |                 break;
 | 
        
           |  |  | 3153 |             case GLOSSARY_DATE :
 | 
        
           |  |  | 3154 |                 $navigation->add(get_string('dateview', 'glossary'), new moodle_url('/mod/glossary/view.php',
 | 
        
           |  |  | 3155 |                         array('id' => $cm->id, 'mode' => 'date')));
 | 
        
           |  |  | 3156 |                 break;
 | 
        
           |  |  | 3157 |             case GLOSSARY_AUTHOR :
 | 
        
           |  |  | 3158 |                 $navigation->add(get_string('authorview', 'glossary'), new moodle_url('/mod/glossary/view.php',
 | 
        
           |  |  | 3159 |                         array('id' => $cm->id, 'mode' => 'author')));
 | 
        
           |  |  | 3160 |                 break;
 | 
        
           |  |  | 3161 |         }
 | 
        
           |  |  | 3162 |     }
 | 
        
           |  |  | 3163 | }
 | 
        
           |  |  | 3164 |   | 
        
           |  |  | 3165 | /**
 | 
        
           |  |  | 3166 |  * Adds module specific settings to the settings block
 | 
        
           |  |  | 3167 |  *
 | 
        
           |  |  | 3168 |  * @param settings_navigation $settings The settings navigation object
 | 
        
           |  |  | 3169 |  * @param navigation_node $glossarynode The node to add module settings to
 | 
        
           |  |  | 3170 |  */
 | 
        
           |  |  | 3171 | function glossary_extend_settings_navigation(settings_navigation $settings, navigation_node $glossarynode) {
 | 
        
           |  |  | 3172 |     global $DB, $CFG, $USER;
 | 
        
           |  |  | 3173 |   | 
        
           |  |  | 3174 |     $mode = optional_param('mode', '', PARAM_ALPHA);
 | 
        
           |  |  | 3175 |     $hook = optional_param('hook', 'ALL', PARAM_CLEAN);
 | 
        
           |  |  | 3176 |   | 
        
           |  |  | 3177 |     if (has_capability('mod/glossary:import', $settings->get_page()->cm->context)) {
 | 
        
           |  |  | 3178 |         $node = $glossarynode->add(get_string('importentries', 'glossary'),
 | 
        
           |  |  | 3179 |             new moodle_url('/mod/glossary/import.php', ['id' => $settings->get_page()->cm->id]));
 | 
        
           |  |  | 3180 |         $node->set_show_in_secondary_navigation(false);
 | 
        
           |  |  | 3181 |     }
 | 
        
           |  |  | 3182 |   | 
        
           |  |  | 3183 |     if (has_capability('mod/glossary:export', $settings->get_page()->cm->context)) {
 | 
        
           |  |  | 3184 |         $node = $glossarynode->add(get_string('exportentries', 'glossary'),
 | 
        
           |  |  | 3185 |             new moodle_url('/mod/glossary/export.php', ['id' => $settings->get_page()->cm->id, 'mode' => $mode,
 | 
        
           |  |  | 3186 |             'hook' => $hook]));
 | 
        
           |  |  | 3187 |         $node->set_show_in_secondary_navigation(false);
 | 
        
           |  |  | 3188 |     }
 | 
        
           |  |  | 3189 |   | 
        
           |  |  | 3190 |     $glossary = $DB->get_record('glossary', array("id" => $settings->get_page()->cm->instance));
 | 
        
           |  |  | 3191 |     $hiddenentries = $DB->count_records('glossary_entries', ['glossaryid' => $settings->get_page()->cm->instance,
 | 
        
           |  |  | 3192 |         'approved' => 0]);
 | 
        
           |  |  | 3193 |   | 
        
           |  |  | 3194 |     // Safe guard check - Ideally, there shouldn't be any hidden entries if the glossary has 'defaultapproval'.
 | 
        
           |  |  | 3195 |     if (has_capability('mod/glossary:approve', $settings->get_page()->cm->context) &&
 | 
        
           |  |  | 3196 |             (!$glossary->defaultapproval || $hiddenentries)) {
 | 
        
           |  |  | 3197 |         $glossarynode->add(get_string('pendingapprovalcount', 'glossary', $hiddenentries),
 | 
        
           |  |  | 3198 |             new moodle_url('/mod/glossary/view.php', ['id' => $settings->get_page()->cm->id, 'mode' => 'approval']),
 | 
        
           |  |  | 3199 |             navigation_node::TYPE_CUSTOM, null, 'pendingapproval');
 | 
        
           |  |  | 3200 |     }
 | 
        
           |  |  | 3201 |   | 
        
           |  |  | 3202 |     if (has_capability('mod/glossary:write', $settings->get_page()->cm->context)) {
 | 
        
           |  |  | 3203 |         $node = $glossarynode->add(get_string('addentry', 'glossary'),
 | 
        
           |  |  | 3204 |             new moodle_url('/mod/glossary/edit.php', ['cmid' => $settings->get_page()->cm->id]));
 | 
        
           |  |  | 3205 |         $node->set_show_in_secondary_navigation(false);
 | 
        
           |  |  | 3206 |     }
 | 
        
           |  |  | 3207 |   | 
        
           |  |  | 3208 |     if (!empty($CFG->enablerssfeeds) && !empty($CFG->glossary_enablerssfeeds) && $glossary->rsstype &&
 | 
        
           |  |  | 3209 |             $glossary->rssarticles && has_capability('mod/glossary:view', $settings->get_page()->cm->context)) {
 | 
        
           |  |  | 3210 |         require_once("$CFG->libdir/rsslib.php");
 | 
        
           |  |  | 3211 |   | 
        
           |  |  | 3212 |         $string = get_string('rsstype', 'glossary');
 | 
        
           |  |  | 3213 |   | 
        
           |  |  | 3214 |         $url = new moodle_url(rss_get_url($settings->get_page()->cm->context->id, $USER->id, 'mod_glossary',
 | 
        
           |  |  | 3215 |             $glossary->id));
 | 
        
           |  |  | 3216 |         $node = $glossarynode->add($string, $url, settings_navigation::TYPE_SETTING, null, null, new pix_icon('i/rss', ''));
 | 
        
           |  |  | 3217 |         $node->set_show_in_secondary_navigation(false);
 | 
        
           |  |  | 3218 |     }
 | 
        
           |  |  | 3219 | }
 | 
        
           |  |  | 3220 |   | 
        
           |  |  | 3221 | /**
 | 
        
           |  |  | 3222 |  * Running addtional permission check on plugin, for example, plugins
 | 
        
           |  |  | 3223 |  * may have switch to turn on/off comments option, this callback will
 | 
        
           |  |  | 3224 |  * affect UI display, not like pluginname_comment_validate only throw
 | 
        
           |  |  | 3225 |  * exceptions.
 | 
        
           |  |  | 3226 |  * Capability check has been done in comment->check_permissions(), we
 | 
        
           |  |  | 3227 |  * don't need to do it again here.
 | 
        
           |  |  | 3228 |  *
 | 
        
           |  |  | 3229 |  * @package  mod_glossary
 | 
        
           |  |  | 3230 |  * @category comment
 | 
        
           |  |  | 3231 |  *
 | 
        
           |  |  | 3232 |  * @param stdClass $comment_param {
 | 
        
           |  |  | 3233 |  *              context  => context the context object
 | 
        
           |  |  | 3234 |  *              courseid => int course id
 | 
        
           |  |  | 3235 |  *              cm       => stdClass course module object
 | 
        
           |  |  | 3236 |  *              commentarea => string comment area
 | 
        
           |  |  | 3237 |  *              itemid      => int itemid
 | 
        
           |  |  | 3238 |  * }
 | 
        
           |  |  | 3239 |  * @return array
 | 
        
           |  |  | 3240 |  */
 | 
        
           |  |  | 3241 | function glossary_comment_permissions($comment_param) {
 | 
        
           |  |  | 3242 |     return array('post'=>true, 'view'=>true);
 | 
        
           |  |  | 3243 | }
 | 
        
           |  |  | 3244 |   | 
        
           |  |  | 3245 | /**
 | 
        
           |  |  | 3246 |  * Validate comment parameter before perform other comments actions
 | 
        
           |  |  | 3247 |  *
 | 
        
           |  |  | 3248 |  * @package  mod_glossary
 | 
        
           |  |  | 3249 |  * @category comment
 | 
        
           |  |  | 3250 |  *
 | 
        
           |  |  | 3251 |  * @param stdClass $comment_param {
 | 
        
           |  |  | 3252 |  *              context  => context the context object
 | 
        
           |  |  | 3253 |  *              courseid => int course id
 | 
        
           |  |  | 3254 |  *              cm       => stdClass course module object
 | 
        
           |  |  | 3255 |  *              commentarea => string comment area
 | 
        
           |  |  | 3256 |  *              itemid      => int itemid
 | 
        
           |  |  | 3257 |  * }
 | 
        
           |  |  | 3258 |  * @return boolean
 | 
        
           |  |  | 3259 |  */
 | 
        
           |  |  | 3260 | function glossary_comment_validate($comment_param) {
 | 
        
           |  |  | 3261 |     global $DB;
 | 
        
           |  |  | 3262 |     // validate comment area
 | 
        
           |  |  | 3263 |     if ($comment_param->commentarea != 'glossary_entry') {
 | 
        
           |  |  | 3264 |         throw new comment_exception('invalidcommentarea');
 | 
        
           |  |  | 3265 |     }
 | 
        
           |  |  | 3266 |     if (!$record = $DB->get_record('glossary_entries', array('id'=>$comment_param->itemid))) {
 | 
        
           |  |  | 3267 |         throw new comment_exception('invalidcommentitemid');
 | 
        
           |  |  | 3268 |     }
 | 
        
           |  |  | 3269 |     if ($record->sourceglossaryid && $record->sourceglossaryid == $comment_param->cm->instance) {
 | 
        
           |  |  | 3270 |         $glossary = $DB->get_record('glossary', array('id'=>$record->sourceglossaryid));
 | 
        
           |  |  | 3271 |     } else {
 | 
        
           |  |  | 3272 |         $glossary = $DB->get_record('glossary', array('id'=>$record->glossaryid));
 | 
        
           |  |  | 3273 |     }
 | 
        
           |  |  | 3274 |     if (!$glossary) {
 | 
        
           |  |  | 3275 |         throw new comment_exception('invalidid', 'data');
 | 
        
           |  |  | 3276 |     }
 | 
        
           |  |  | 3277 |     if (!$course = $DB->get_record('course', array('id'=>$glossary->course))) {
 | 
        
           |  |  | 3278 |         throw new comment_exception('coursemisconf');
 | 
        
           |  |  | 3279 |     }
 | 
        
           |  |  | 3280 |     if (!$cm = get_coursemodule_from_instance('glossary', $glossary->id, $course->id)) {
 | 
        
           |  |  | 3281 |         throw new comment_exception('invalidcoursemodule');
 | 
        
           |  |  | 3282 |     }
 | 
        
           |  |  | 3283 |     $context = context_module::instance($cm->id);
 | 
        
           |  |  | 3284 |   | 
        
           |  |  | 3285 |     if ($glossary->defaultapproval and !$record->approved and !has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 3286 |         throw new comment_exception('notapproved', 'glossary');
 | 
        
           |  |  | 3287 |     }
 | 
        
           |  |  | 3288 |     // validate context id
 | 
        
           |  |  | 3289 |     if ($context->id != $comment_param->context->id) {
 | 
        
           |  |  | 3290 |         throw new comment_exception('invalidcontext');
 | 
        
           |  |  | 3291 |     }
 | 
        
           |  |  | 3292 |     // validation for comment deletion
 | 
        
           |  |  | 3293 |     if (!empty($comment_param->commentid)) {
 | 
        
           |  |  | 3294 |         if ($comment = $DB->get_record('comments', array('id'=>$comment_param->commentid))) {
 | 
        
           |  |  | 3295 |             if ($comment->commentarea != 'glossary_entry') {
 | 
        
           |  |  | 3296 |                 throw new comment_exception('invalidcommentarea');
 | 
        
           |  |  | 3297 |             }
 | 
        
           |  |  | 3298 |             if ($comment->contextid != $comment_param->context->id) {
 | 
        
           |  |  | 3299 |                 throw new comment_exception('invalidcontext');
 | 
        
           |  |  | 3300 |             }
 | 
        
           |  |  | 3301 |             if ($comment->itemid != $comment_param->itemid) {
 | 
        
           |  |  | 3302 |                 throw new comment_exception('invalidcommentitemid');
 | 
        
           |  |  | 3303 |             }
 | 
        
           |  |  | 3304 |         } else {
 | 
        
           |  |  | 3305 |             throw new comment_exception('invalidcommentid');
 | 
        
           |  |  | 3306 |         }
 | 
        
           |  |  | 3307 |     }
 | 
        
           |  |  | 3308 |     return true;
 | 
        
           |  |  | 3309 | }
 | 
        
           |  |  | 3310 |   | 
        
           |  |  | 3311 | /**
 | 
        
           |  |  | 3312 |  * Return a list of page types
 | 
        
           |  |  | 3313 |  * @param string $pagetype current page type
 | 
        
           |  |  | 3314 |  * @param stdClass $parentcontext Block's parent context
 | 
        
           |  |  | 3315 |  * @param stdClass $currentcontext Current context of block
 | 
        
           |  |  | 3316 |  */
 | 
        
           |  |  | 3317 | function glossary_page_type_list($pagetype, $parentcontext, $currentcontext) {
 | 
        
           |  |  | 3318 |     $module_pagetype = array(
 | 
        
           |  |  | 3319 |         'mod-glossary-*'=>get_string('page-mod-glossary-x', 'glossary'),
 | 
        
           |  |  | 3320 |         'mod-glossary-view'=>get_string('page-mod-glossary-view', 'glossary'),
 | 
        
           |  |  | 3321 |         'mod-glossary-edit'=>get_string('page-mod-glossary-edit', 'glossary'));
 | 
        
           |  |  | 3322 |     return $module_pagetype;
 | 
        
           |  |  | 3323 | }
 | 
        
           |  |  | 3324 |   | 
        
           |  |  | 3325 | /**
 | 
        
           |  |  | 3326 |  * Return list of all glossary tabs.
 | 
        
           |  |  | 3327 |  * @throws coding_exception
 | 
        
           |  |  | 3328 |  * @return array
 | 
        
           |  |  | 3329 |  */
 | 
        
           |  |  | 3330 | function glossary_get_all_tabs() {
 | 
        
           |  |  | 3331 |   | 
        
           |  |  | 3332 |     return array (
 | 
        
           |  |  | 3333 |         GLOSSARY_AUTHOR => get_string('authorview', 'glossary'),
 | 
        
           |  |  | 3334 |         GLOSSARY_CATEGORY => get_string('categoryview', 'glossary'),
 | 
        
           |  |  | 3335 |         GLOSSARY_DATE => get_string('dateview', 'glossary')
 | 
        
           |  |  | 3336 |     );
 | 
        
           |  |  | 3337 | }
 | 
        
           |  |  | 3338 |   | 
        
           |  |  | 3339 | /**
 | 
        
           |  |  | 3340 |  * Set 'showtabs' value for glossary formats
 | 
        
           |  |  | 3341 |  * @param stdClass $glossaryformat record from 'glossary_formats' table
 | 
        
           |  |  | 3342 |  */
 | 
        
           |  |  | 3343 | function glossary_set_default_visible_tabs($glossaryformat) {
 | 
        
           |  |  | 3344 |     global $DB;
 | 
        
           |  |  | 3345 |   | 
        
           |  |  | 3346 |     switch($glossaryformat->name) {
 | 
        
           |  |  | 3347 |         case GLOSSARY_CONTINUOUS:
 | 
        
           |  |  | 3348 |             $showtabs = 'standard,category,date';
 | 
        
           |  |  | 3349 |             break;
 | 
        
           |  |  | 3350 |         case GLOSSARY_DICTIONARY:
 | 
        
           |  |  | 3351 |             $showtabs = 'standard';
 | 
        
           |  |  | 3352 |             // Special code for upgraded instances that already had categories set up
 | 
        
           |  |  | 3353 |             // in this format - enable "category" tab.
 | 
        
           |  |  | 3354 |             // In new instances only 'standard' tab will be visible.
 | 
        
           |  |  | 3355 |             if ($DB->record_exists_sql("SELECT 1
 | 
        
           |  |  | 3356 |                     FROM {glossary} g, {glossary_categories} gc
 | 
        
           |  |  | 3357 |                     WHERE g.id = gc.glossaryid and g.displayformat = ?",
 | 
        
           |  |  | 3358 |                     array(GLOSSARY_DICTIONARY))) {
 | 
        
           |  |  | 3359 |                 $showtabs .= ',category';
 | 
        
           |  |  | 3360 |             }
 | 
        
           |  |  | 3361 |             break;
 | 
        
           |  |  | 3362 |         case GLOSSARY_FULLWITHOUTAUTHOR:
 | 
        
           |  |  | 3363 |             $showtabs = 'standard,category,date';
 | 
        
           |  |  | 3364 |             break;
 | 
        
           |  |  | 3365 |         default:
 | 
        
           |  |  | 3366 |             $showtabs = 'standard,category,date,author';
 | 
        
           |  |  | 3367 |             break;
 | 
        
           |  |  | 3368 |     }
 | 
        
           |  |  | 3369 |   | 
        
           |  |  | 3370 |     $DB->set_field('glossary_formats', 'showtabs', $showtabs, array('id' => $glossaryformat->id));
 | 
        
           |  |  | 3371 |     $glossaryformat->showtabs = $showtabs;
 | 
        
           |  |  | 3372 | }
 | 
        
           |  |  | 3373 |   | 
        
           |  |  | 3374 | /**
 | 
        
           |  |  | 3375 |  * Convert 'showtabs' string to array
 | 
        
           |  |  | 3376 |  * @param stdClass $displayformat record from 'glossary_formats' table
 | 
        
           |  |  | 3377 |  * @return array
 | 
        
           |  |  | 3378 |  */
 | 
        
           |  |  | 3379 | function glossary_get_visible_tabs($displayformat) {
 | 
        
           |  |  | 3380 |     if (empty($displayformat->showtabs)) {
 | 
        
           |  |  | 3381 |         glossary_set_default_visible_tabs($displayformat);
 | 
        
           |  |  | 3382 |     }
 | 
        
           |  |  | 3383 |     $showtabs = preg_split('/,/', $displayformat->showtabs, -1, PREG_SPLIT_NO_EMPTY);
 | 
        
           |  |  | 3384 |   | 
        
           |  |  | 3385 |     return $showtabs;
 | 
        
           |  |  | 3386 | }
 | 
        
           |  |  | 3387 |   | 
        
           |  |  | 3388 | /**
 | 
        
           |  |  | 3389 |  * Notify that the glossary was viewed.
 | 
        
           |  |  | 3390 |  *
 | 
        
           |  |  | 3391 |  * This will trigger relevant events and activity completion.
 | 
        
           |  |  | 3392 |  *
 | 
        
           |  |  | 3393 |  * @param stdClass $glossary The glossary object.
 | 
        
           |  |  | 3394 |  * @param stdClass $course   The course object.
 | 
        
           |  |  | 3395 |  * @param stdClass $cm       The course module object.
 | 
        
           |  |  | 3396 |  * @param stdClass $context  The context object.
 | 
        
           |  |  | 3397 |  * @param string   $mode     The mode in which the glossary was viewed.
 | 
        
           |  |  | 3398 |  * @since Moodle 3.1
 | 
        
           |  |  | 3399 |  */
 | 
        
           |  |  | 3400 | function glossary_view($glossary, $course, $cm, $context, $mode) {
 | 
        
           |  |  | 3401 |   | 
        
           |  |  | 3402 |     // Completion trigger.
 | 
        
           |  |  | 3403 |     $completion = new completion_info($course);
 | 
        
           |  |  | 3404 |     $completion->set_module_viewed($cm);
 | 
        
           |  |  | 3405 |   | 
        
           |  |  | 3406 |     // Trigger the course module viewed event.
 | 
        
           |  |  | 3407 |     $event = \mod_glossary\event\course_module_viewed::create(array(
 | 
        
           |  |  | 3408 |         'objectid' => $glossary->id,
 | 
        
           |  |  | 3409 |         'context' => $context,
 | 
        
           |  |  | 3410 |         'other' => array('mode' => $mode)
 | 
        
           |  |  | 3411 |     ));
 | 
        
           |  |  | 3412 |     $event->add_record_snapshot('course', $course);
 | 
        
           |  |  | 3413 |     $event->add_record_snapshot('course_modules', $cm);
 | 
        
           |  |  | 3414 |     $event->add_record_snapshot('glossary', $glossary);
 | 
        
           |  |  | 3415 |     $event->trigger();
 | 
        
           |  |  | 3416 | }
 | 
        
           |  |  | 3417 |   | 
        
           |  |  | 3418 | /**
 | 
        
           |  |  | 3419 |  * Notify that a glossary entry was viewed.
 | 
        
           |  |  | 3420 |  *
 | 
        
           |  |  | 3421 |  * This will trigger relevant events.
 | 
        
           |  |  | 3422 |  *
 | 
        
           |  |  | 3423 |  * @param stdClass $entry    The entry object.
 | 
        
           |  |  | 3424 |  * @param stdClass $context  The context object.
 | 
        
           |  |  | 3425 |  * @since Moodle 3.1
 | 
        
           |  |  | 3426 |  */
 | 
        
           |  |  | 3427 | function glossary_entry_view($entry, $context) {
 | 
        
           |  |  | 3428 |   | 
        
           |  |  | 3429 |     // Trigger the entry viewed event.
 | 
        
           |  |  | 3430 |     $event = \mod_glossary\event\entry_viewed::create(array(
 | 
        
           |  |  | 3431 |         'objectid' => $entry->id,
 | 
        
           |  |  | 3432 |         'context' => $context
 | 
        
           |  |  | 3433 |     ));
 | 
        
           |  |  | 3434 |     $event->add_record_snapshot('glossary_entries', $entry);
 | 
        
           |  |  | 3435 |     $event->trigger();
 | 
        
           |  |  | 3436 |   | 
        
           |  |  | 3437 | }
 | 
        
           |  |  | 3438 |   | 
        
           |  |  | 3439 | /**
 | 
        
           |  |  | 3440 |  * Returns the entries of a glossary by letter.
 | 
        
           |  |  | 3441 |  *
 | 
        
           |  |  | 3442 |  * @param  object $glossary The glossary.
 | 
        
           |  |  | 3443 |  * @param  context $context The context of the glossary.
 | 
        
           |  |  | 3444 |  * @param  string $letter The letter, or ALL, or SPECIAL.
 | 
        
           |  |  | 3445 |  * @param  int $from Fetch records from.
 | 
        
           |  |  | 3446 |  * @param  int $limit Number of records to fetch.
 | 
        
           |  |  | 3447 |  * @param  array $options Accepts:
 | 
        
           |  |  | 3448 |  *                        - (bool) includenotapproved. When false, includes the non-approved entries created by
 | 
        
           |  |  | 3449 |  *                          the current user. When true, also includes the ones that the user has the permission to approve.
 | 
        
           | 1441 | ariadna | 3450 |  * @return array The first element being the recordset (taking into account the limit), the second the number of entries the overall
 | 
        
           |  |  | 3451 |  *               array has.
 | 
        
           | 1 | efrain | 3452 |  * @since Moodle 3.1
 | 
        
           |  |  | 3453 |  */
 | 
        
           |  |  | 3454 | function glossary_get_entries_by_letter($glossary, $context, $letter, $from, $limit, $options = array()) {
 | 
        
           |  |  | 3455 |   | 
        
           |  |  | 3456 |     $qb = new mod_glossary_entry_query_builder($glossary);
 | 
        
           |  |  | 3457 |   | 
        
           |  |  | 3458 |     if (!empty($options['includenotapproved']) && has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 3459 |         $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_ALL);
 | 
        
           |  |  | 3460 |     } else {
 | 
        
           |  |  | 3461 |         $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_SELF);
 | 
        
           |  |  | 3462 |     }
 | 
        
           |  |  | 3463 |   | 
        
           |  |  | 3464 |     $qb->add_field('*', 'entries');
 | 
        
           |  |  | 3465 |     $qb->join_user();
 | 
        
           |  |  | 3466 |     $qb->add_user_fields();
 | 
        
           |  |  | 3467 |     $qb->order_by('concept', 'entries');
 | 
        
           |  |  | 3468 |     $qb->order_by('id', 'entries', 'ASC'); // Sort on ID to avoid random ordering when entries share an ordering value.
 | 
        
           |  |  | 3469 |   | 
        
           | 1441 | ariadna | 3470 |     // Fetching the entries. Those are all entries.
 | 
        
           | 1 | efrain | 3471 |     $entries = $qb->get_records();
 | 
        
           |  |  | 3472 |   | 
        
           | 1441 | ariadna | 3473 |     // Now sorting out the array.
 | 
        
           |  |  | 3474 |     $filteredentries = [];
 | 
        
           |  |  | 3475 |   | 
        
           |  |  | 3476 |     if ($letter != 'ALL' && $letter != 'SPECIAL' && core_text::strlen($letter)) {
 | 
        
           |  |  | 3477 |         // Build a new array with the filtered entries.
 | 
        
           |  |  | 3478 |         foreach ($entries as $key => $entry) {
 | 
        
           |  |  | 3479 |             if (strtoupper(substr(format_string($entry->concept), 0, 1)) === strtoupper($letter)) {
 | 
        
           |  |  | 3480 |                 // Add it when starting with the correct letter.
 | 
        
           |  |  | 3481 |                 $filteredentries[$key] = $entry;
 | 
        
           |  |  | 3482 |             }
 | 
        
           |  |  | 3483 |         }
 | 
        
           |  |  | 3484 |         $entries = $filteredentries;
 | 
        
           |  |  | 3485 |     }
 | 
        
           |  |  | 3486 |   | 
        
           |  |  | 3487 |     if ($letter == 'SPECIAL') {
 | 
        
           |  |  | 3488 |         // Build a new array with the filtered entries.
 | 
        
           |  |  | 3489 |         foreach ($entries as $key => $entry) {
 | 
        
           |  |  | 3490 |             if (!ctype_alpha(substr(format_string($entry->concept), 0, 1))) {
 | 
        
           |  |  | 3491 |                 // Add it when starting with a non-letter character.
 | 
        
           |  |  | 3492 |                 $filteredentries[$key] = $entry;
 | 
        
           |  |  | 3493 |             }
 | 
        
           |  |  | 3494 |         }
 | 
        
           |  |  | 3495 |         $entries = $filteredentries;
 | 
        
           |  |  | 3496 |     }
 | 
        
           |  |  | 3497 |   | 
        
           |  |  | 3498 |     if ($letter == 'ALL') {
 | 
        
           |  |  | 3499 |         // No filtering needed.
 | 
        
           |  |  | 3500 |         $filteredentries = $entries;
 | 
        
           |  |  | 3501 |     }
 | 
        
           |  |  | 3502 |   | 
        
           |  |  | 3503 |     // Now sort the array in regard to the current language.
 | 
        
           |  |  | 3504 |     usort($filteredentries, function($a, $b) {
 | 
        
           |  |  | 3505 |         return format_string($a->concept) <=> format_string($b->concept);
 | 
        
           |  |  | 3506 |     });
 | 
        
           |  |  | 3507 |   | 
        
           |  |  | 3508 |     // Size of the overall array.
 | 
        
           |  |  | 3509 |     $count = count($entries);
 | 
        
           |  |  | 3510 |   | 
        
           |  |  | 3511 |     // Now applying limit.
 | 
        
           |  |  | 3512 |     if (isset($limit)) {
 | 
        
           |  |  | 3513 |         if (isset($from)) {
 | 
        
           |  |  | 3514 |             $entries = array_slice($filteredentries, $from, $limit);
 | 
        
           |  |  | 3515 |         } else {
 | 
        
           |  |  | 3516 |             $entries = array_slice($filteredentries);
 | 
        
           |  |  | 3517 |         }
 | 
        
           |  |  | 3518 |     } else {
 | 
        
           |  |  | 3519 |         $entries = $filteredentries;
 | 
        
           |  |  | 3520 |     }
 | 
        
           |  |  | 3521 |   | 
        
           | 1 | efrain | 3522 |     return array($entries, $count);
 | 
        
           |  |  | 3523 | }
 | 
        
           |  |  | 3524 |   | 
        
           |  |  | 3525 | /**
 | 
        
           |  |  | 3526 |  * Returns the entries of a glossary by date.
 | 
        
           |  |  | 3527 |  *
 | 
        
           |  |  | 3528 |  * @param  object $glossary The glossary.
 | 
        
           |  |  | 3529 |  * @param  context $context The context of the glossary.
 | 
        
           |  |  | 3530 |  * @param  string $order The mode of ordering: CREATION or UPDATE.
 | 
        
           |  |  | 3531 |  * @param  string $sort The direction of the ordering: ASC or DESC.
 | 
        
           |  |  | 3532 |  * @param  int $from Fetch records from.
 | 
        
           |  |  | 3533 |  * @param  int $limit Number of records to fetch.
 | 
        
           |  |  | 3534 |  * @param  array $options Accepts:
 | 
        
           |  |  | 3535 |  *                        - (bool) includenotapproved. When false, includes the non-approved entries created by
 | 
        
           |  |  | 3536 |  *                          the current user. When true, also includes the ones that the user has the permission to approve.
 | 
        
           | 1441 | ariadna | 3537 |  * @return array The first element being the recordset (taking into account the limit), the second the number of entries the overall
 | 
        
           |  |  | 3538 |  *               array has.
 | 
        
           | 1 | efrain | 3539 |  * @since Moodle 3.1
 | 
        
           |  |  | 3540 |  */
 | 
        
           |  |  | 3541 | function glossary_get_entries_by_date($glossary, $context, $order, $sort, $from, $limit, $options = array()) {
 | 
        
           |  |  | 3542 |   | 
        
           |  |  | 3543 |     $qb = new mod_glossary_entry_query_builder($glossary);
 | 
        
           |  |  | 3544 |     if (!empty($options['includenotapproved']) && has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 3545 |         $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_ALL);
 | 
        
           |  |  | 3546 |     } else {
 | 
        
           |  |  | 3547 |         $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_SELF);
 | 
        
           |  |  | 3548 |     }
 | 
        
           |  |  | 3549 |   | 
        
           |  |  | 3550 |     $qb->add_field('*', 'entries');
 | 
        
           |  |  | 3551 |     $qb->join_user();
 | 
        
           |  |  | 3552 |     $qb->add_user_fields();
 | 
        
           |  |  | 3553 |     $qb->limit($from, $limit);
 | 
        
           |  |  | 3554 |   | 
        
           |  |  | 3555 |     if ($order == 'CREATION') {
 | 
        
           |  |  | 3556 |         $qb->order_by('timecreated', 'entries', $sort);
 | 
        
           |  |  | 3557 |     } else {
 | 
        
           |  |  | 3558 |         $qb->order_by('timemodified', 'entries', $sort);
 | 
        
           |  |  | 3559 |     }
 | 
        
           |  |  | 3560 |     $qb->order_by('id', 'entries', $sort); // Sort on ID to avoid random ordering when entries share an ordering value.
 | 
        
           |  |  | 3561 |   | 
        
           |  |  | 3562 |     // Fetching the entries.
 | 
        
           |  |  | 3563 |     $count = $qb->count_records();
 | 
        
           |  |  | 3564 |     $entries = $qb->get_records();
 | 
        
           |  |  | 3565 |   | 
        
           |  |  | 3566 |     return array($entries, $count);
 | 
        
           |  |  | 3567 | }
 | 
        
           |  |  | 3568 |   | 
        
           |  |  | 3569 | /**
 | 
        
           |  |  | 3570 |  * Returns the entries of a glossary by category.
 | 
        
           |  |  | 3571 |  *
 | 
        
           |  |  | 3572 |  * @param  object $glossary The glossary.
 | 
        
           |  |  | 3573 |  * @param  context $context The context of the glossary.
 | 
        
           |  |  | 3574 |  * @param  int $categoryid The category ID, or GLOSSARY_SHOW_* constant.
 | 
        
           |  |  | 3575 |  * @param  int $from Fetch records from.
 | 
        
           |  |  | 3576 |  * @param  int $limit Number of records to fetch.
 | 
        
           |  |  | 3577 |  * @param  array $options Accepts:
 | 
        
           |  |  | 3578 |  *                        - (bool) includenotapproved. When false, includes the non-approved entries created by
 | 
        
           |  |  | 3579 |  *                          the current user. When true, also includes the ones that the user has the permission to approve.
 | 
        
           | 1441 | ariadna | 3580 |  * @return array The first element being the recordset (taking into account the limit), the second the number of entries the overall
 | 
        
           |  |  | 3581 |  *               array has.
 | 
        
           | 1 | efrain | 3582 |  * @since Moodle 3.1
 | 
        
           |  |  | 3583 |  */
 | 
        
           |  |  | 3584 | function glossary_get_entries_by_category($glossary, $context, $categoryid, $from, $limit, $options = array()) {
 | 
        
           |  |  | 3585 |   | 
        
           |  |  | 3586 |     $qb = new mod_glossary_entry_query_builder($glossary);
 | 
        
           |  |  | 3587 |     if (!empty($options['includenotapproved']) && has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 3588 |         $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_ALL);
 | 
        
           |  |  | 3589 |     } else {
 | 
        
           |  |  | 3590 |         $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_SELF);
 | 
        
           |  |  | 3591 |     }
 | 
        
           |  |  | 3592 |   | 
        
           |  |  | 3593 |     $qb->join_category($categoryid);
 | 
        
           |  |  | 3594 |     $qb->join_user();
 | 
        
           |  |  | 3595 |   | 
        
           |  |  | 3596 |     // The first field must be the relationship ID when viewing all categories.
 | 
        
           |  |  | 3597 |     if ($categoryid === GLOSSARY_SHOW_ALL_CATEGORIES) {
 | 
        
           |  |  | 3598 |         $qb->add_field('id', 'entries_categories', 'cid');
 | 
        
           |  |  | 3599 |     }
 | 
        
           |  |  | 3600 |   | 
        
           |  |  | 3601 |     $qb->add_field('*', 'entries');
 | 
        
           |  |  | 3602 |     $qb->add_field('categoryid', 'entries_categories');
 | 
        
           |  |  | 3603 |     $qb->add_user_fields();
 | 
        
           |  |  | 3604 |   | 
        
           |  |  | 3605 |     if ($categoryid === GLOSSARY_SHOW_ALL_CATEGORIES) {
 | 
        
           |  |  | 3606 |         $qb->add_field('name', 'categories', 'categoryname');
 | 
        
           |  |  | 3607 |         $qb->order_by('name', 'categories');
 | 
        
           |  |  | 3608 |   | 
        
           |  |  | 3609 |     } else if ($categoryid === GLOSSARY_SHOW_NOT_CATEGORISED) {
 | 
        
           |  |  | 3610 |         $qb->where('categoryid', 'entries_categories', null);
 | 
        
           |  |  | 3611 |     }
 | 
        
           |  |  | 3612 |   | 
        
           |  |  | 3613 |     // Sort on additional fields to avoid random ordering when entries share an ordering value.
 | 
        
           |  |  | 3614 |     $qb->order_by('concept', 'entries');
 | 
        
           |  |  | 3615 |     $qb->order_by('id', 'entries', 'ASC');
 | 
        
           |  |  | 3616 |     $qb->limit($from, $limit);
 | 
        
           |  |  | 3617 |   | 
        
           |  |  | 3618 |     // Fetching the entries.
 | 
        
           |  |  | 3619 |     $count = $qb->count_records();
 | 
        
           |  |  | 3620 |     $entries = $qb->get_records();
 | 
        
           |  |  | 3621 |   | 
        
           |  |  | 3622 |     return array($entries, $count);
 | 
        
           |  |  | 3623 | }
 | 
        
           |  |  | 3624 |   | 
        
           |  |  | 3625 | /**
 | 
        
           |  |  | 3626 |  * Returns the entries of a glossary by author.
 | 
        
           |  |  | 3627 |  *
 | 
        
           |  |  | 3628 |  * @param  object $glossary The glossary.
 | 
        
           |  |  | 3629 |  * @param  context $context The context of the glossary.
 | 
        
           |  |  | 3630 |  * @param  string $letter The letter
 | 
        
           |  |  | 3631 |  * @param  string $field The field to search: FIRSTNAME or LASTNAME.
 | 
        
           |  |  | 3632 |  * @param  string $sort The sorting: ASC or DESC.
 | 
        
           |  |  | 3633 |  * @param  int $from Fetch records from.
 | 
        
           |  |  | 3634 |  * @param  int $limit Number of records to fetch.
 | 
        
           |  |  | 3635 |  * @param  array $options Accepts:
 | 
        
           |  |  | 3636 |  *                        - (bool) includenotapproved. When false, includes the non-approved entries created by
 | 
        
           |  |  | 3637 |  *                          the current user. When true, also includes the ones that the user has the permission to approve.
 | 
        
           | 1441 | ariadna | 3638 |  * @return array The first element being the recordset (taking into account the limit), the second the number of entries the overall
 | 
        
           |  |  | 3639 |  *               array has.
 | 
        
           | 1 | efrain | 3640 |  * @since Moodle 3.1
 | 
        
           |  |  | 3641 |  */
 | 
        
           |  |  | 3642 | function glossary_get_entries_by_author($glossary, $context, $letter, $field, $sort, $from, $limit, $options = array()) {
 | 
        
           |  |  | 3643 |   | 
        
           |  |  | 3644 |     $firstnamefirst = $field === 'FIRSTNAME';
 | 
        
           |  |  | 3645 |     $qb = new mod_glossary_entry_query_builder($glossary);
 | 
        
           |  |  | 3646 |     if ($letter != 'ALL' && $letter != 'SPECIAL' && core_text::strlen($letter)) {
 | 
        
           |  |  | 3647 |         $qb->filter_by_author_letter($letter, $firstnamefirst);
 | 
        
           |  |  | 3648 |     }
 | 
        
           |  |  | 3649 |     if ($letter == 'SPECIAL') {
 | 
        
           |  |  | 3650 |         $qb->filter_by_author_non_letter($firstnamefirst);
 | 
        
           |  |  | 3651 |     }
 | 
        
           |  |  | 3652 |   | 
        
           |  |  | 3653 |     if (!empty($options['includenotapproved']) && has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 3654 |         $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_ALL);
 | 
        
           |  |  | 3655 |     } else {
 | 
        
           |  |  | 3656 |         $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_SELF);
 | 
        
           |  |  | 3657 |     }
 | 
        
           |  |  | 3658 |   | 
        
           |  |  | 3659 |     $qb->add_field('*', 'entries');
 | 
        
           |  |  | 3660 |     $qb->join_user(true);
 | 
        
           |  |  | 3661 |     $qb->add_user_fields();
 | 
        
           |  |  | 3662 |     $qb->order_by_author($firstnamefirst, $sort);
 | 
        
           |  |  | 3663 |     $qb->order_by('concept', 'entries');
 | 
        
           |  |  | 3664 |     $qb->order_by('id', 'entries', 'ASC'); // Sort on ID to avoid random ordering when entries share an ordering value.
 | 
        
           |  |  | 3665 |     $qb->limit($from, $limit);
 | 
        
           |  |  | 3666 |   | 
        
           |  |  | 3667 |     // Fetching the entries.
 | 
        
           |  |  | 3668 |     $count = $qb->count_records();
 | 
        
           |  |  | 3669 |     $entries = $qb->get_records();
 | 
        
           |  |  | 3670 |   | 
        
           |  |  | 3671 |     return array($entries, $count);
 | 
        
           |  |  | 3672 | }
 | 
        
           |  |  | 3673 |   | 
        
           |  |  | 3674 | /**
 | 
        
           |  |  | 3675 |  * Returns the entries of a glossary by category.
 | 
        
           |  |  | 3676 |  *
 | 
        
           |  |  | 3677 |  * @param  object $glossary The glossary.
 | 
        
           |  |  | 3678 |  * @param  context $context The context of the glossary.
 | 
        
           |  |  | 3679 |  * @param  int $authorid The author ID.
 | 
        
           |  |  | 3680 |  * @param  string $order The mode of ordering: CONCEPT, CREATION or UPDATE.
 | 
        
           |  |  | 3681 |  * @param  string $sort The direction of the ordering: ASC or DESC.
 | 
        
           |  |  | 3682 |  * @param  int $from Fetch records from.
 | 
        
           |  |  | 3683 |  * @param  int $limit Number of records to fetch.
 | 
        
           |  |  | 3684 |  * @param  array $options Accepts:
 | 
        
           |  |  | 3685 |  *                        - (bool) includenotapproved. When false, includes the non-approved entries created by
 | 
        
           |  |  | 3686 |  *                          the current user. When true, also includes the ones that the user has the permission to approve.
 | 
        
           | 1441 | ariadna | 3687 |  * @return array The first element being the recordset (taking into account the limit), the second the number of entries the overall
 | 
        
           |  |  | 3688 |  *               array has.
 | 
        
           | 1 | efrain | 3689 |  * @since Moodle 3.1
 | 
        
           |  |  | 3690 |  */
 | 
        
           |  |  | 3691 | function glossary_get_entries_by_author_id($glossary, $context, $authorid, $order, $sort, $from, $limit, $options = array()) {
 | 
        
           |  |  | 3692 |   | 
        
           |  |  | 3693 |     $qb = new mod_glossary_entry_query_builder($glossary);
 | 
        
           |  |  | 3694 |     if (!empty($options['includenotapproved']) && has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 3695 |         $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_ALL);
 | 
        
           |  |  | 3696 |     } else {
 | 
        
           |  |  | 3697 |         $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_SELF);
 | 
        
           |  |  | 3698 |     }
 | 
        
           |  |  | 3699 |   | 
        
           |  |  | 3700 |     $qb->add_field('*', 'entries');
 | 
        
           |  |  | 3701 |     $qb->join_user(true);
 | 
        
           |  |  | 3702 |     $qb->add_user_fields();
 | 
        
           |  |  | 3703 |     $qb->where('id', 'user', $authorid);
 | 
        
           |  |  | 3704 |   | 
        
           |  |  | 3705 |     if ($order == 'CREATION') {
 | 
        
           |  |  | 3706 |         $qb->order_by('timecreated', 'entries', $sort);
 | 
        
           |  |  | 3707 |     } else if ($order == 'UPDATE') {
 | 
        
           |  |  | 3708 |         $qb->order_by('timemodified', 'entries', $sort);
 | 
        
           |  |  | 3709 |     } else {
 | 
        
           |  |  | 3710 |         $qb->order_by('concept', 'entries', $sort);
 | 
        
           |  |  | 3711 |     }
 | 
        
           |  |  | 3712 |     $qb->order_by('id', 'entries', $sort); // Sort on ID to avoid random ordering when entries share an ordering value.
 | 
        
           |  |  | 3713 |   | 
        
           |  |  | 3714 |     $qb->limit($from, $limit);
 | 
        
           |  |  | 3715 |   | 
        
           |  |  | 3716 |     // Fetching the entries.
 | 
        
           |  |  | 3717 |     $count = $qb->count_records();
 | 
        
           |  |  | 3718 |     $entries = $qb->get_records();
 | 
        
           |  |  | 3719 |   | 
        
           |  |  | 3720 |     return array($entries, $count);
 | 
        
           |  |  | 3721 | }
 | 
        
           |  |  | 3722 |   | 
        
           |  |  | 3723 | /**
 | 
        
           |  |  | 3724 |  * Returns the authors in a glossary
 | 
        
           |  |  | 3725 |  *
 | 
        
           |  |  | 3726 |  * @param  object $glossary The glossary.
 | 
        
           |  |  | 3727 |  * @param  context $context The context of the glossary.
 | 
        
           |  |  | 3728 |  * @param  int $limit Number of records to fetch.
 | 
        
           |  |  | 3729 |  * @param  int $from Fetch records from.
 | 
        
           |  |  | 3730 |  * @param  array $options Accepts:
 | 
        
           |  |  | 3731 |  *                        - (bool) includenotapproved. When false, includes self even if all of their entries require approval.
 | 
        
           |  |  | 3732 |  *                          When true, also includes authors only having entries pending approval.
 | 
        
           | 1441 | ariadna | 3733 |  * @return array The first element being the recordset (taking into account the limit), the second the number of entries the overall
 | 
        
           |  |  | 3734 |  *               array has.
 | 
        
           | 1 | efrain | 3735 |  * @since Moodle 3.1
 | 
        
           |  |  | 3736 |  */
 | 
        
           |  |  | 3737 | function glossary_get_authors($glossary, $context, $limit, $from, $options = array()) {
 | 
        
           |  |  | 3738 |     global $DB, $USER;
 | 
        
           |  |  | 3739 |   | 
        
           |  |  | 3740 |     $params = array();
 | 
        
           |  |  | 3741 |     $userfieldsapi = \core_user\fields::for_userpic();
 | 
        
           |  |  | 3742 |     $userfields = $userfieldsapi->get_sql('u', false, '', '', false)->selects;
 | 
        
           |  |  | 3743 |   | 
        
           |  |  | 3744 |     $approvedsql = '(ge.approved <> 0 OR ge.userid = :myid)';
 | 
        
           |  |  | 3745 |     $params['myid'] = $USER->id;
 | 
        
           |  |  | 3746 |     if (!empty($options['includenotapproved']) && has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 3747 |         $approvedsql = '1 = 1';
 | 
        
           |  |  | 3748 |     }
 | 
        
           |  |  | 3749 |   | 
        
           |  |  | 3750 |     $sqlselectcount = "SELECT COUNT(DISTINCT(u.id))";
 | 
        
           |  |  | 3751 |     $sqlselect = "SELECT DISTINCT(u.id) AS userId, $userfields";
 | 
        
           |  |  | 3752 |     $sql = "  FROM {user} u
 | 
        
           |  |  | 3753 |               JOIN {glossary_entries} ge
 | 
        
           |  |  | 3754 |                 ON ge.userid = u.id
 | 
        
           |  |  | 3755 |                AND (ge.glossaryid = :gid1 OR ge.sourceglossaryid = :gid2)
 | 
        
           |  |  | 3756 |                AND $approvedsql";
 | 
        
           |  |  | 3757 |     $ordersql = " ORDER BY u.lastname, u.firstname";
 | 
        
           |  |  | 3758 |   | 
        
           |  |  | 3759 |     $params['gid1'] = $glossary->id;
 | 
        
           |  |  | 3760 |     $params['gid2'] = $glossary->id;
 | 
        
           |  |  | 3761 |   | 
        
           |  |  | 3762 |     $count = $DB->count_records_sql($sqlselectcount . $sql, $params);
 | 
        
           |  |  | 3763 |     $users = $DB->get_recordset_sql($sqlselect . $sql . $ordersql, $params, $from, $limit);
 | 
        
           |  |  | 3764 |   | 
        
           |  |  | 3765 |     return array($users, $count);
 | 
        
           |  |  | 3766 | }
 | 
        
           |  |  | 3767 |   | 
        
           |  |  | 3768 | /**
 | 
        
           |  |  | 3769 |  * Returns the categories of a glossary.
 | 
        
           |  |  | 3770 |  *
 | 
        
           |  |  | 3771 |  * @param  object $glossary The glossary.
 | 
        
           |  |  | 3772 |  * @param  int $from Fetch records from.
 | 
        
           |  |  | 3773 |  * @param  int $limit Number of records to fetch.
 | 
        
           | 1441 | ariadna | 3774 |  * @return array The first element being the recordset (taking into account the limit), the second the number of entries the overall
 | 
        
           |  |  | 3775 |  *               array has.
 | 
        
           | 1 | efrain | 3776 |  * @since Moodle 3.1
 | 
        
           |  |  | 3777 |  */
 | 
        
           |  |  | 3778 | function glossary_get_categories($glossary, $from, $limit) {
 | 
        
           |  |  | 3779 |     global $DB;
 | 
        
           |  |  | 3780 |   | 
        
           |  |  | 3781 |     $count = $DB->count_records('glossary_categories', array('glossaryid' => $glossary->id));
 | 
        
           |  |  | 3782 |     $categories = $DB->get_recordset('glossary_categories', array('glossaryid' => $glossary->id), 'name ASC', '*', $from, $limit);
 | 
        
           |  |  | 3783 |   | 
        
           |  |  | 3784 |     return array($categories, $count);
 | 
        
           |  |  | 3785 | }
 | 
        
           |  |  | 3786 |   | 
        
           |  |  | 3787 | /**
 | 
        
           |  |  | 3788 |  * Get the SQL where clause for searching terms.
 | 
        
           |  |  | 3789 |  *
 | 
        
           |  |  | 3790 |  * Note that this does not handle invalid or too short terms.
 | 
        
           |  |  | 3791 |  *
 | 
        
           |  |  | 3792 |  * @param array   $terms      Array of terms.
 | 
        
           |  |  | 3793 |  * @param bool    $fullsearch Whether or not full search should be enabled.
 | 
        
           |  |  | 3794 |  * @param int     $glossaryid The ID of a glossary to reduce the search results.
 | 
        
           |  |  | 3795 |  * @return array The first element being the where clause, the second array of parameters.
 | 
        
           |  |  | 3796 |  * @since Moodle 3.1
 | 
        
           |  |  | 3797 |  */
 | 
        
           |  |  | 3798 | function glossary_get_search_terms_sql(array $terms, $fullsearch = true, $glossaryid = null) {
 | 
        
           |  |  | 3799 |     global $DB;
 | 
        
           |  |  | 3800 |     static $i = 0;
 | 
        
           |  |  | 3801 |   | 
        
           |  |  | 3802 |     if ($DB->sql_regex_supported()) {
 | 
        
           |  |  | 3803 |         $regexp = $DB->sql_regex(true);
 | 
        
           |  |  | 3804 |         $notregexp = $DB->sql_regex(false);
 | 
        
           |  |  | 3805 |     }
 | 
        
           |  |  | 3806 |   | 
        
           |  |  | 3807 |     $params = array();
 | 
        
           |  |  | 3808 |     $conditions = array();
 | 
        
           |  |  | 3809 |   | 
        
           |  |  | 3810 |     foreach ($terms as $searchterm) {
 | 
        
           |  |  | 3811 |         $i++;
 | 
        
           |  |  | 3812 |   | 
        
           | 1441 | ariadna | 3813 |         $not = false; // Initially we aren't going to perform NOT LIKE searches, only MSSQL
 | 
        
           | 1 | efrain | 3814 |                       // will use it to simulate the "-" operator with LIKE clause.
 | 
        
           |  |  | 3815 |   | 
        
           |  |  | 3816 |         if (empty($fullsearch)) {
 | 
        
           |  |  | 3817 |             // With fullsearch disabled, look only within concepts and aliases.
 | 
        
           |  |  | 3818 |             $concat = $DB->sql_concat('ge.concept', "' '", "COALESCE(al.alias, :emptychar{$i})");
 | 
        
           |  |  | 3819 |         } else {
 | 
        
           |  |  | 3820 |             // With fullsearch enabled, look also within definitions.
 | 
        
           |  |  | 3821 |             $concat = $DB->sql_concat('ge.concept', "' '", 'ge.definition', "' '", "COALESCE(al.alias, :emptychar{$i})");
 | 
        
           |  |  | 3822 |         }
 | 
        
           |  |  | 3823 |         $params['emptychar' . $i] = '';
 | 
        
           |  |  | 3824 |   | 
        
           | 1441 | ariadna | 3825 |         // Under MSSQL, trim the + and - operators and perform simpler LIKE (or NOT LIKE) queries.
 | 
        
           | 1 | efrain | 3826 |         if (!$DB->sql_regex_supported()) {
 | 
        
           |  |  | 3827 |             if (substr($searchterm, 0, 1) === '-') {
 | 
        
           |  |  | 3828 |                 $not = true;
 | 
        
           |  |  | 3829 |             }
 | 
        
           |  |  | 3830 |             $searchterm = trim($searchterm, '+-');
 | 
        
           |  |  | 3831 |         }
 | 
        
           |  |  | 3832 |   | 
        
           |  |  | 3833 |         if (substr($searchterm, 0, 1) === '+') {
 | 
        
           |  |  | 3834 |             $searchterm = trim($searchterm, '+-');
 | 
        
           |  |  | 3835 |             $conditions[] = "$concat $regexp :searchterm{$i}";
 | 
        
           |  |  | 3836 |             $params['searchterm' . $i] = '(^|[^a-zA-Z0-9])' . preg_quote($searchterm, '|') . '([^a-zA-Z0-9]|$)';
 | 
        
           |  |  | 3837 |   | 
        
           |  |  | 3838 |         } else if (substr($searchterm, 0, 1) === "-") {
 | 
        
           |  |  | 3839 |             $searchterm = trim($searchterm, '+-');
 | 
        
           |  |  | 3840 |             $conditions[] = "$concat $notregexp :searchterm{$i}";
 | 
        
           |  |  | 3841 |             $params['searchterm' . $i] = '(^|[^a-zA-Z0-9])' . preg_quote($searchterm, '|') . '([^a-zA-Z0-9]|$)';
 | 
        
           |  |  | 3842 |   | 
        
           |  |  | 3843 |         } else {
 | 
        
           |  |  | 3844 |             $conditions[] = $DB->sql_like($concat, ":searchterm{$i}", false, true, $not);
 | 
        
           |  |  | 3845 |             $params['searchterm' . $i] = '%' . $DB->sql_like_escape($searchterm) . '%';
 | 
        
           |  |  | 3846 |         }
 | 
        
           |  |  | 3847 |     }
 | 
        
           |  |  | 3848 |   | 
        
           |  |  | 3849 |     // Reduce the search results by restricting it to one glossary.
 | 
        
           |  |  | 3850 |     if (isset($glossaryid)) {
 | 
        
           |  |  | 3851 |         $conditions[] = 'ge.glossaryid = :glossaryid';
 | 
        
           |  |  | 3852 |         $params['glossaryid'] = $glossaryid;
 | 
        
           |  |  | 3853 |     }
 | 
        
           |  |  | 3854 |   | 
        
           |  |  | 3855 |     // When there are no conditions we add a negative one to ensure that we don't return anything.
 | 
        
           |  |  | 3856 |     if (empty($conditions)) {
 | 
        
           |  |  | 3857 |         $conditions[] = '1 = 2';
 | 
        
           |  |  | 3858 |     }
 | 
        
           |  |  | 3859 |   | 
        
           |  |  | 3860 |     $where = implode(' AND ', $conditions);
 | 
        
           |  |  | 3861 |     return array($where, $params);
 | 
        
           |  |  | 3862 | }
 | 
        
           |  |  | 3863 |   | 
        
           |  |  | 3864 |   | 
        
           |  |  | 3865 | /**
 | 
        
           |  |  | 3866 |  * Returns the entries of a glossary by search.
 | 
        
           |  |  | 3867 |  *
 | 
        
           |  |  | 3868 |  * @param  object $glossary The glossary.
 | 
        
           |  |  | 3869 |  * @param  context $context The context of the glossary.
 | 
        
           |  |  | 3870 |  * @param  string $query The search query.
 | 
        
           |  |  | 3871 |  * @param  bool $fullsearch Whether or not full search is required.
 | 
        
           |  |  | 3872 |  * @param  string $order The mode of ordering: CONCEPT, CREATION or UPDATE.
 | 
        
           |  |  | 3873 |  * @param  string $sort The direction of the ordering: ASC or DESC.
 | 
        
           |  |  | 3874 |  * @param  int $from Fetch records from.
 | 
        
           |  |  | 3875 |  * @param  int $limit Number of records to fetch.
 | 
        
           |  |  | 3876 |  * @param  array $options Accepts:
 | 
        
           |  |  | 3877 |  *                        - (bool) includenotapproved. When false, includes the non-approved entries created by
 | 
        
           |  |  | 3878 |  *                          the current user. When true, also includes the ones that the user has the permission to approve.
 | 
        
           | 1441 | ariadna | 3879 |  * @return array The first element being the recordset (taking into account the limit), the second the number of entries the overall
 | 
        
           |  |  | 3880 |  *               array has.
 | 
        
           | 1 | efrain | 3881 |  * @since Moodle 3.1
 | 
        
           |  |  | 3882 |  */
 | 
        
           |  |  | 3883 | function glossary_get_entries_by_search($glossary, $context, $query, $fullsearch, $order, $sort, $from, $limit,
 | 
        
           |  |  | 3884 |                                         $options = array()) {
 | 
        
           |  |  | 3885 |     global $DB, $USER;
 | 
        
           |  |  | 3886 |   | 
        
           |  |  | 3887 |     // Clean terms.
 | 
        
           |  |  | 3888 |     $terms = explode(' ', $query);
 | 
        
           |  |  | 3889 |     foreach ($terms as $key => $term) {
 | 
        
           |  |  | 3890 |         if (strlen(trim($term, '+-')) < 1) {
 | 
        
           |  |  | 3891 |             unset($terms[$key]);
 | 
        
           |  |  | 3892 |         }
 | 
        
           |  |  | 3893 |     }
 | 
        
           |  |  | 3894 |   | 
        
           |  |  | 3895 |     list($searchcond, $params) = glossary_get_search_terms_sql($terms, $fullsearch, $glossary->id);
 | 
        
           |  |  | 3896 |   | 
        
           |  |  | 3897 |     $userfieldsapi = \core_user\fields::for_userpic();
 | 
        
           |  |  | 3898 |     $userfields = $userfieldsapi->get_sql('u', false, 'userdata', 'userdataid', false)->selects;
 | 
        
           |  |  | 3899 |   | 
        
           |  |  | 3900 |     // Need one inner view here to avoid distinct + text.
 | 
        
           |  |  | 3901 |     $sqlwrapheader = 'SELECT ge.*, ge.concept AS glossarypivot, ' . $userfields . '
 | 
        
           |  |  | 3902 |                         FROM {glossary_entries} ge
 | 
        
           |  |  | 3903 |                         LEFT JOIN {user} u ON u.id = ge.userid
 | 
        
           |  |  | 3904 |                         JOIN ( ';
 | 
        
           |  |  | 3905 |     $sqlwrapfooter = ' ) gei ON (ge.id = gei.id)';
 | 
        
           |  |  | 3906 |     $sqlselect  = "SELECT DISTINCT ge.id";
 | 
        
           |  |  | 3907 |     $sqlfrom    = "FROM {glossary_entries} ge
 | 
        
           |  |  | 3908 |                    LEFT JOIN {glossary_alias} al ON al.entryid = ge.id";
 | 
        
           |  |  | 3909 |   | 
        
           |  |  | 3910 |     if (!empty($options['includenotapproved']) && has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 3911 |         $approvedsql = '';
 | 
        
           |  |  | 3912 |     } else {
 | 
        
           |  |  | 3913 |         $approvedsql = 'AND (ge.approved <> 0 OR ge.userid = :myid)';
 | 
        
           |  |  | 3914 |         $params['myid'] = $USER->id;
 | 
        
           |  |  | 3915 |     }
 | 
        
           |  |  | 3916 |   | 
        
           |  |  | 3917 |     if ($order == 'CREATION') {
 | 
        
           |  |  | 3918 |         $sqlorderby = "ORDER BY ge.timecreated $sort";
 | 
        
           |  |  | 3919 |     } else if ($order == 'UPDATE') {
 | 
        
           |  |  | 3920 |         $sqlorderby = "ORDER BY ge.timemodified $sort";
 | 
        
           |  |  | 3921 |     } else {
 | 
        
           |  |  | 3922 |         $sqlorderby = "ORDER BY ge.concept $sort";
 | 
        
           |  |  | 3923 |     }
 | 
        
           |  |  | 3924 |     $sqlorderby .= " , ge.id ASC"; // Sort on ID to avoid random ordering when entries share an ordering value.
 | 
        
           |  |  | 3925 |   | 
        
           |  |  | 3926 |     $sqlwhere = "WHERE ($searchcond) $approvedsql";
 | 
        
           |  |  | 3927 |   | 
        
           |  |  | 3928 |     // Fetching the entries.
 | 
        
           |  |  | 3929 |     $count = $DB->count_records_sql("SELECT COUNT(DISTINCT(ge.id)) $sqlfrom $sqlwhere", $params);
 | 
        
           |  |  | 3930 |   | 
        
           |  |  | 3931 |     $query = "$sqlwrapheader $sqlselect $sqlfrom $sqlwhere $sqlwrapfooter $sqlorderby";
 | 
        
           |  |  | 3932 |     $entries = $DB->get_records_sql($query, $params, $from, $limit);
 | 
        
           |  |  | 3933 |   | 
        
           |  |  | 3934 |     return array($entries, $count);
 | 
        
           |  |  | 3935 | }
 | 
        
           |  |  | 3936 |   | 
        
           |  |  | 3937 | /**
 | 
        
           |  |  | 3938 |  * Returns the entries of a glossary by term.
 | 
        
           |  |  | 3939 |  *
 | 
        
           |  |  | 3940 |  * @param  object $glossary The glossary.
 | 
        
           |  |  | 3941 |  * @param  context $context The context of the glossary.
 | 
        
           |  |  | 3942 |  * @param  string $term The term we are searching for, a concept or alias.
 | 
        
           |  |  | 3943 |  * @param  int $from Fetch records from.
 | 
        
           |  |  | 3944 |  * @param  int $limit Number of records to fetch.
 | 
        
           |  |  | 3945 |  * @param  array $options Accepts:
 | 
        
           |  |  | 3946 |  *                        - (bool) includenotapproved. When false, includes the non-approved entries created by
 | 
        
           |  |  | 3947 |  *                          the current user. When true, also includes the ones that the user has the permission to approve.
 | 
        
           |  |  | 3948 |  * @return array The first element being the recordset, the second the number of entries.
 | 
        
           |  |  | 3949 |  * @since Moodle 3.1
 | 
        
           |  |  | 3950 |  */
 | 
        
           |  |  | 3951 | function glossary_get_entries_by_term($glossary, $context, $term, $from, $limit, $options = array()) {
 | 
        
           |  |  | 3952 |   | 
        
           |  |  | 3953 |     // Build the query.
 | 
        
           |  |  | 3954 |     $qb = new mod_glossary_entry_query_builder($glossary);
 | 
        
           |  |  | 3955 |     if (!empty($options['includenotapproved']) && has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 3956 |         $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_ALL);
 | 
        
           |  |  | 3957 |     } else {
 | 
        
           |  |  | 3958 |         $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_SELF);
 | 
        
           |  |  | 3959 |     }
 | 
        
           |  |  | 3960 |   | 
        
           |  |  | 3961 |     $qb->add_field('*', 'entries');
 | 
        
           | 1441 | ariadna | 3962 |     $qb->add_field('alias', 'alias');
 | 
        
           | 1 | efrain | 3963 |     $qb->join_alias();
 | 
        
           |  |  | 3964 |     $qb->join_user();
 | 
        
           |  |  | 3965 |     $qb->add_user_fields();
 | 
        
           |  |  | 3966 |     $qb->filter_by_term($term);
 | 
        
           |  |  | 3967 |   | 
        
           |  |  | 3968 |     $qb->order_by('concept', 'entries');
 | 
        
           |  |  | 3969 |     $qb->order_by('id', 'entries');     // Sort on ID to avoid random ordering when entries share an ordering value.
 | 
        
           |  |  | 3970 |   | 
        
           | 1441 | ariadna | 3971 |     // Fetching the entries. Those are all entries.
 | 
        
           | 1 | efrain | 3972 |     $entries = $qb->get_records();
 | 
        
           |  |  | 3973 |   | 
        
           | 1441 | ariadna | 3974 |     // Now sorting out the array.
 | 
        
           |  |  | 3975 |     $filteredentries = [];
 | 
        
           |  |  | 3976 |   | 
        
           |  |  | 3977 |     // Now sorting out the array.
 | 
        
           |  |  | 3978 |     foreach ($entries as $key => $entry) {
 | 
        
           |  |  | 3979 |         if (strtoupper(format_string($entry->concept)) === strtoupper($term)) {
 | 
        
           |  |  | 3980 |             // Add it when matching concept or alias.
 | 
        
           |  |  | 3981 |             $filteredentries[$key] = $entry;
 | 
        
           |  |  | 3982 |         }
 | 
        
           |  |  | 3983 |         if ((isset($entry->alias)) && (strtoupper(format_string($entry->alias)) === strtoupper($term))) {
 | 
        
           |  |  | 3984 |             // Add it when matching concept or alias.
 | 
        
           |  |  | 3985 |             $filteredentries[$key] = $entry;
 | 
        
           |  |  | 3986 |         }
 | 
        
           |  |  | 3987 |     }
 | 
        
           |  |  | 3988 |     $entries = $filteredentries;
 | 
        
           |  |  | 3989 |     // Check whether concept or alias match the term.
 | 
        
           |  |  | 3990 |   | 
        
           |  |  | 3991 |     // Now sort the array in regard to the current language.
 | 
        
           |  |  | 3992 |     usort($filteredentries, function($a, $b) {
 | 
        
           |  |  | 3993 |         return format_string($a->concept) <=> format_string($b->concept);
 | 
        
           |  |  | 3994 |     });
 | 
        
           |  |  | 3995 |   | 
        
           |  |  | 3996 |     // Size of the overall array.
 | 
        
           |  |  | 3997 |     $count = count($entries);
 | 
        
           |  |  | 3998 |   | 
        
           |  |  | 3999 |     // Now applying limit.
 | 
        
           |  |  | 4000 |     if (isset($limit)) {
 | 
        
           |  |  | 4001 |         if (isset($from)) {
 | 
        
           |  |  | 4002 |             $entries = array_slice($filteredentries, $from, $limit);
 | 
        
           |  |  | 4003 |         } else {
 | 
        
           |  |  | 4004 |             $entries = array_slice($filteredentries);
 | 
        
           |  |  | 4005 |         }
 | 
        
           |  |  | 4006 |     } else {
 | 
        
           |  |  | 4007 |         $entries = $filteredentries;
 | 
        
           |  |  | 4008 |     }
 | 
        
           |  |  | 4009 |   | 
        
           | 1 | efrain | 4010 |     return array($entries, $count);
 | 
        
           |  |  | 4011 | }
 | 
        
           |  |  | 4012 |   | 
        
           |  |  | 4013 | /**
 | 
        
           |  |  | 4014 |  * Returns the entries to be approved.
 | 
        
           |  |  | 4015 |  *
 | 
        
           |  |  | 4016 |  * @param  object $glossary The glossary.
 | 
        
           |  |  | 4017 |  * @param  context $context The context of the glossary.
 | 
        
           |  |  | 4018 |  * @param  string $letter The letter, or ALL, or SPECIAL.
 | 
        
           |  |  | 4019 |  * @param  string $order The mode of ordering: CONCEPT, CREATION or UPDATE.
 | 
        
           |  |  | 4020 |  * @param  string $sort The direction of the ordering: ASC or DESC.
 | 
        
           |  |  | 4021 |  * @param  int $from Fetch records from.
 | 
        
           |  |  | 4022 |  * @param  int $limit Number of records to fetch.
 | 
        
           |  |  | 4023 |  * @return array The first element being the recordset, the second the number of entries.
 | 
        
           |  |  | 4024 |  * @since Moodle 3.1
 | 
        
           |  |  | 4025 |  */
 | 
        
           |  |  | 4026 | function glossary_get_entries_to_approve($glossary, $context, $letter, $order, $sort, $from, $limit) {
 | 
        
           |  |  | 4027 |   | 
        
           |  |  | 4028 |     $qb = new mod_glossary_entry_query_builder($glossary);
 | 
        
           |  |  | 4029 |   | 
        
           |  |  | 4030 |     $qb->add_field('*', 'entries');
 | 
        
           |  |  | 4031 |     $qb->join_user();
 | 
        
           |  |  | 4032 |     $qb->add_user_fields();
 | 
        
           |  |  | 4033 |     $qb->filter_by_non_approved(mod_glossary_entry_query_builder::NON_APPROVED_ONLY);
 | 
        
           | 1441 | ariadna | 4034 |   | 
        
           |  |  | 4035 |     // Fetching the entries. Those are all non approved entries.
 | 
        
           |  |  | 4036 |     $entries = $qb->get_records();
 | 
        
           |  |  | 4037 |   | 
        
           |  |  | 4038 |     // Size of the overall array.
 | 
        
           |  |  | 4039 |     $count = count($entries);
 | 
        
           |  |  | 4040 |   | 
        
           |  |  | 4041 |     // If a some filter is set, restrict by that filter.
 | 
        
           |  |  | 4042 |     $filteredentries = [];
 | 
        
           |  |  | 4043 |   | 
        
           |  |  | 4044 |     if ($letter != 'ALL' && $letter != 'SPECIAL' && core_text::strlen($letter)) {
 | 
        
           |  |  | 4045 |         // Build a new array with the filtered entries.
 | 
        
           |  |  | 4046 |         foreach ($entries as $key => $entry) {
 | 
        
           |  |  | 4047 |             if (strtoupper(substr(format_string($entry->concept), 0, 1)) === strtoupper($letter)) {
 | 
        
           |  |  | 4048 |                 // Add it when starting with the correct letter.
 | 
        
           |  |  | 4049 |                 $filteredentries[$key] = $entry;
 | 
        
           |  |  | 4050 |             }
 | 
        
           |  |  | 4051 |         }
 | 
        
           |  |  | 4052 |     } else if ($letter == 'SPECIAL') {
 | 
        
           |  |  | 4053 |         // Build a new array with the filtered entries.
 | 
        
           |  |  | 4054 |         foreach ($entries as $key => $entry) {
 | 
        
           |  |  | 4055 |             if (!ctype_alpha(substr(format_string($entry->concept), 0, 1))) {
 | 
        
           |  |  | 4056 |                 // Add it when starting with a non-letter character.
 | 
        
           |  |  | 4057 |                 $filteredentries[$key] = $entry;
 | 
        
           |  |  | 4058 |             }
 | 
        
           |  |  | 4059 |         }
 | 
        
           |  |  | 4060 |     } else {
 | 
        
           |  |  | 4061 |         // No filtering needed (This means CONCEPT).
 | 
        
           |  |  | 4062 |         $filteredentries = $entries;
 | 
        
           |  |  | 4063 |     }
 | 
        
           |  |  | 4064 |   | 
        
           |  |  | 4065 |     // Now sort the array in regard to the current language.
 | 
        
           | 1 | efrain | 4066 |     if ($order == 'CREATION') {
 | 
        
           | 1441 | ariadna | 4067 |         if (strcasecmp($sort, 'DESC') === 0) {
 | 
        
           |  |  | 4068 |             usort($filteredentries, function($a, $b) {
 | 
        
           |  |  | 4069 |                 return $b->timecreated <=> $a->timecreated;
 | 
        
           |  |  | 4070 |             });
 | 
        
           |  |  | 4071 |         } else {
 | 
        
           |  |  | 4072 |             usort($filteredentries, function($a, $b) {
 | 
        
           |  |  | 4073 |                 return $a->timecreated <=> $b->timecreated;
 | 
        
           |  |  | 4074 |             });
 | 
        
           |  |  | 4075 |         }
 | 
        
           | 1 | efrain | 4076 |     } else if ($order == 'UPDATE') {
 | 
        
           | 1441 | ariadna | 4077 |         if (strcasecmp($sort, 'DESC') === 0) {
 | 
        
           |  |  | 4078 |             usort($filteredentries, function($a, $b) {
 | 
        
           |  |  | 4079 |                 return $b->timemodified <=> $a->timemodified;
 | 
        
           |  |  | 4080 |             });
 | 
        
           |  |  | 4081 |         } else {
 | 
        
           |  |  | 4082 |             usort($filteredentries, function($a, $b) {
 | 
        
           |  |  | 4083 |                 return $a->timemodified <=> $b->timemodified;
 | 
        
           |  |  | 4084 |             });
 | 
        
           |  |  | 4085 |         }
 | 
        
           | 1 | efrain | 4086 |     } else {
 | 
        
           | 1441 | ariadna | 4087 |         // This means CONCEPT.
 | 
        
           |  |  | 4088 |         if (strcasecmp($sort, 'DESC') === 0) {
 | 
        
           |  |  | 4089 |             usort($filteredentries, function($a, $b) {
 | 
        
           |  |  | 4090 |                 return format_string($b->concept) <=> format_string($a->concept);
 | 
        
           |  |  | 4091 |             });
 | 
        
           |  |  | 4092 |         } else {
 | 
        
           |  |  | 4093 |             usort($filteredentries, function($a, $b) {
 | 
        
           |  |  | 4094 |                 return format_string($a->concept) <=> format_string($b->concept);
 | 
        
           |  |  | 4095 |             });
 | 
        
           |  |  | 4096 |         }
 | 
        
           | 1 | efrain | 4097 |     }
 | 
        
           |  |  | 4098 |   | 
        
           | 1441 | ariadna | 4099 |     // Now applying limit.
 | 
        
           |  |  | 4100 |     if (isset($limit)) {
 | 
        
           |  |  | 4101 |         $count = count($filteredentries);
 | 
        
           |  |  | 4102 |         if (isset($from)) {
 | 
        
           |  |  | 4103 |             $filteredentries = array_slice($filteredentries, $from, $limit);
 | 
        
           |  |  | 4104 |         } else {
 | 
        
           |  |  | 4105 |             $filteredentries = array_slice($filteredentries, 0, $limit);
 | 
        
           |  |  | 4106 |         }
 | 
        
           |  |  | 4107 |     }
 | 
        
           | 1 | efrain | 4108 |   | 
        
           | 1441 | ariadna | 4109 |     return [$filteredentries, $count];
 | 
        
           | 1 | efrain | 4110 | }
 | 
        
           |  |  | 4111 |   | 
        
           |  |  | 4112 | /**
 | 
        
           |  |  | 4113 |  * Fetch an entry.
 | 
        
           |  |  | 4114 |  *
 | 
        
           |  |  | 4115 |  * @param  int $id The entry ID.
 | 
        
           |  |  | 4116 |  * @return object|false The entry, or false when not found.
 | 
        
           |  |  | 4117 |  * @since Moodle 3.1
 | 
        
           |  |  | 4118 |  */
 | 
        
           |  |  | 4119 | function glossary_get_entry_by_id($id) {
 | 
        
           |  |  | 4120 |   | 
        
           |  |  | 4121 |     // Build the query.
 | 
        
           |  |  | 4122 |     $qb = new mod_glossary_entry_query_builder();
 | 
        
           |  |  | 4123 |     $qb->add_field('*', 'entries');
 | 
        
           |  |  | 4124 |     $qb->join_user();
 | 
        
           |  |  | 4125 |     $qb->add_user_fields();
 | 
        
           |  |  | 4126 |     $qb->where('id', 'entries', $id);
 | 
        
           |  |  | 4127 |   | 
        
           |  |  | 4128 |     // Fetching the entries.
 | 
        
           |  |  | 4129 |     $entries = $qb->get_records();
 | 
        
           |  |  | 4130 |     if (empty($entries)) {
 | 
        
           |  |  | 4131 |         return false;
 | 
        
           |  |  | 4132 |     }
 | 
        
           |  |  | 4133 |     return array_pop($entries);
 | 
        
           |  |  | 4134 | }
 | 
        
           |  |  | 4135 |   | 
        
           |  |  | 4136 | /**
 | 
        
           |  |  | 4137 |  * Checks if the current user can see the glossary entry.
 | 
        
           |  |  | 4138 |  *
 | 
        
           |  |  | 4139 |  * @since Moodle 3.1
 | 
        
           |  |  | 4140 |  * @param stdClass $entry
 | 
        
           |  |  | 4141 |  * @param cm_info  $cminfo
 | 
        
           |  |  | 4142 |  * @return bool
 | 
        
           |  |  | 4143 |  */
 | 
        
           |  |  | 4144 | function glossary_can_view_entry($entry, $cminfo) {
 | 
        
           |  |  | 4145 |     global $USER;
 | 
        
           |  |  | 4146 |   | 
        
           |  |  | 4147 |     $cm = $cminfo->get_course_module_record();
 | 
        
           |  |  | 4148 |     $context = \context_module::instance($cm->id);
 | 
        
           |  |  | 4149 |   | 
        
           |  |  | 4150 |     // Recheck uservisible although it should have already been checked in core_search.
 | 
        
           |  |  | 4151 |     if ($cminfo->uservisible === false) {
 | 
        
           |  |  | 4152 |         return false;
 | 
        
           |  |  | 4153 |     }
 | 
        
           |  |  | 4154 |   | 
        
           |  |  | 4155 |     // Check approval.
 | 
        
           |  |  | 4156 |     if (empty($entry->approved) && $entry->userid != $USER->id && !has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 4157 |         return false;
 | 
        
           |  |  | 4158 |     }
 | 
        
           |  |  | 4159 |   | 
        
           |  |  | 4160 |     return true;
 | 
        
           |  |  | 4161 | }
 | 
        
           |  |  | 4162 |   | 
        
           |  |  | 4163 | /**
 | 
        
           |  |  | 4164 |  * Check if a concept exists in a glossary.
 | 
        
           |  |  | 4165 |  *
 | 
        
           |  |  | 4166 |  * @param  stdClass $glossary glossary object
 | 
        
           |  |  | 4167 |  * @param  string $concept the concept to check
 | 
        
           |  |  | 4168 |  * @return bool true if exists
 | 
        
           |  |  | 4169 |  * @since  Moodle 3.2
 | 
        
           |  |  | 4170 |  */
 | 
        
           |  |  | 4171 | function glossary_concept_exists($glossary, $concept) {
 | 
        
           |  |  | 4172 |     global $DB;
 | 
        
           |  |  | 4173 |   | 
        
           |  |  | 4174 |     return $DB->record_exists_select('glossary_entries', 'glossaryid = :glossaryid AND LOWER(concept) = :concept',
 | 
        
           |  |  | 4175 |         array(
 | 
        
           |  |  | 4176 |             'glossaryid' => $glossary->id,
 | 
        
           |  |  | 4177 |             'concept'    => core_text::strtolower($concept)
 | 
        
           |  |  | 4178 |         )
 | 
        
           |  |  | 4179 |     );
 | 
        
           |  |  | 4180 | }
 | 
        
           |  |  | 4181 |   | 
        
           |  |  | 4182 | /**
 | 
        
           |  |  | 4183 |  * Return the editor and attachment options when editing a glossary entry
 | 
        
           |  |  | 4184 |  *
 | 
        
           |  |  | 4185 |  * @param  stdClass $course  course object
 | 
        
           |  |  | 4186 |  * @param  stdClass $context context object
 | 
        
           |  |  | 4187 |  * @param  stdClass $entry   entry object
 | 
        
           |  |  | 4188 |  * @return array array containing the editor and attachment options
 | 
        
           |  |  | 4189 |  * @since  Moodle 3.2
 | 
        
           |  |  | 4190 |  */
 | 
        
           |  |  | 4191 | function glossary_get_editor_and_attachment_options($course, $context, $entry) {
 | 
        
           |  |  | 4192 |     $maxfiles = 99;                // TODO: add some setting.
 | 
        
           |  |  | 4193 |     $maxbytes = $course->maxbytes; // TODO: add some setting.
 | 
        
           |  |  | 4194 |   | 
        
           |  |  | 4195 |     $definitionoptions = array('trusttext' => true, 'maxfiles' => $maxfiles, 'maxbytes' => $maxbytes, 'context' => $context,
 | 
        
           |  |  | 4196 |         'subdirs' => file_area_contains_subdirs($context, 'mod_glossary', 'entry', $entry->id));
 | 
        
           |  |  | 4197 |     $attachmentoptions = array('subdirs' => false, 'maxfiles' => $maxfiles, 'maxbytes' => $maxbytes);
 | 
        
           |  |  | 4198 |     return array($definitionoptions, $attachmentoptions);
 | 
        
           |  |  | 4199 | }
 | 
        
           |  |  | 4200 |   | 
        
           |  |  | 4201 | /**
 | 
        
           |  |  | 4202 |  * Creates or updates a glossary entry
 | 
        
           |  |  | 4203 |  *
 | 
        
           |  |  | 4204 |  * @param  stdClass $entry entry data
 | 
        
           |  |  | 4205 |  * @param  stdClass $course course object
 | 
        
           |  |  | 4206 |  * @param  stdClass $cm course module object
 | 
        
           |  |  | 4207 |  * @param  stdClass $glossary glossary object
 | 
        
           |  |  | 4208 |  * @param  stdClass $context context object
 | 
        
           |  |  | 4209 |  * @return stdClass the complete new or updated entry
 | 
        
           |  |  | 4210 |  * @since  Moodle 3.2
 | 
        
           |  |  | 4211 |  */
 | 
        
           |  |  | 4212 | function glossary_edit_entry($entry, $course, $cm, $glossary, $context) {
 | 
        
           |  |  | 4213 |     global $DB, $USER;
 | 
        
           |  |  | 4214 |   | 
        
           |  |  | 4215 |     list($definitionoptions, $attachmentoptions) = glossary_get_editor_and_attachment_options($course, $context, $entry);
 | 
        
           |  |  | 4216 |   | 
        
           |  |  | 4217 |     $timenow = time();
 | 
        
           |  |  | 4218 |   | 
        
           |  |  | 4219 |     $categories = empty($entry->categories) ? array() : $entry->categories;
 | 
        
           |  |  | 4220 |     unset($entry->categories);
 | 
        
           |  |  | 4221 |     $aliases = trim($entry->aliases);
 | 
        
           |  |  | 4222 |     unset($entry->aliases);
 | 
        
           |  |  | 4223 |   | 
        
           |  |  | 4224 |     if (empty($entry->id)) {
 | 
        
           |  |  | 4225 |         $entry->glossaryid       = $glossary->id;
 | 
        
           |  |  | 4226 |         $entry->timecreated      = $timenow;
 | 
        
           |  |  | 4227 |         $entry->userid           = $USER->id;
 | 
        
           |  |  | 4228 |         $entry->timecreated      = $timenow;
 | 
        
           |  |  | 4229 |         $entry->sourceglossaryid = 0;
 | 
        
           |  |  | 4230 |         $entry->teacherentry     = has_capability('mod/glossary:manageentries', $context);
 | 
        
           |  |  | 4231 |         $isnewentry              = true;
 | 
        
           |  |  | 4232 |     } else {
 | 
        
           |  |  | 4233 |         $isnewentry              = false;
 | 
        
           |  |  | 4234 |     }
 | 
        
           |  |  | 4235 |   | 
        
           |  |  | 4236 |     $entry->concept          = trim($entry->concept);
 | 
        
           |  |  | 4237 |     $entry->definition       = '';          // Updated later.
 | 
        
           |  |  | 4238 |     $entry->definitionformat = FORMAT_HTML; // Updated later.
 | 
        
           |  |  | 4239 |     $entry->definitiontrust  = 0;           // Updated later.
 | 
        
           |  |  | 4240 |     $entry->timemodified     = $timenow;
 | 
        
           |  |  | 4241 |     $entry->approved         = 0;
 | 
        
           |  |  | 4242 |     $entry->usedynalink      = isset($entry->usedynalink) ? $entry->usedynalink : 0;
 | 
        
           |  |  | 4243 |     $entry->casesensitive    = isset($entry->casesensitive) ? $entry->casesensitive : 0;
 | 
        
           |  |  | 4244 |     $entry->fullmatch        = isset($entry->fullmatch) ? $entry->fullmatch : 0;
 | 
        
           |  |  | 4245 |   | 
        
           |  |  | 4246 |     if ($glossary->defaultapproval or has_capability('mod/glossary:approve', $context)) {
 | 
        
           |  |  | 4247 |         $entry->approved = 1;
 | 
        
           |  |  | 4248 |     }
 | 
        
           |  |  | 4249 |   | 
        
           |  |  | 4250 |     if ($isnewentry) {
 | 
        
           |  |  | 4251 |         // Add new entry.
 | 
        
           |  |  | 4252 |         $entry->id = $DB->insert_record('glossary_entries', $entry);
 | 
        
           |  |  | 4253 |     } else {
 | 
        
           |  |  | 4254 |         // Update existing entry.
 | 
        
           |  |  | 4255 |         $DB->update_record('glossary_entries', $entry);
 | 
        
           |  |  | 4256 |     }
 | 
        
           |  |  | 4257 |   | 
        
           |  |  | 4258 |     // Save and relink embedded images and save attachments.
 | 
        
           |  |  | 4259 |     if (!empty($entry->definition_editor)) {
 | 
        
           |  |  | 4260 |         $entry = file_postupdate_standard_editor($entry, 'definition', $definitionoptions, $context, 'mod_glossary', 'entry',
 | 
        
           |  |  | 4261 |             $entry->id);
 | 
        
           |  |  | 4262 |     }
 | 
        
           |  |  | 4263 |     if (!empty($entry->attachment_filemanager)) {
 | 
        
           |  |  | 4264 |         $entry = file_postupdate_standard_filemanager($entry, 'attachment', $attachmentoptions, $context, 'mod_glossary',
 | 
        
           |  |  | 4265 |             'attachment', $entry->id);
 | 
        
           |  |  | 4266 |     }
 | 
        
           |  |  | 4267 |   | 
        
           |  |  | 4268 |     // Store the updated value values.
 | 
        
           |  |  | 4269 |     $DB->update_record('glossary_entries', $entry);
 | 
        
           |  |  | 4270 |   | 
        
           |  |  | 4271 |     // Refetch complete entry.
 | 
        
           |  |  | 4272 |     $entry = $DB->get_record('glossary_entries', array('id' => $entry->id));
 | 
        
           |  |  | 4273 |   | 
        
           |  |  | 4274 |     // Update entry categories.
 | 
        
           |  |  | 4275 |     $DB->delete_records('glossary_entries_categories', array('entryid' => $entry->id));
 | 
        
           |  |  | 4276 |     // TODO: this deletes cats from both both main and secondary glossary :-(.
 | 
        
           |  |  | 4277 |     if (!empty($categories) and array_search(0, $categories) === false) {
 | 
        
           |  |  | 4278 |         foreach ($categories as $catid) {
 | 
        
           |  |  | 4279 |             $newcategory = new stdClass();
 | 
        
           |  |  | 4280 |             $newcategory->entryid    = $entry->id;
 | 
        
           |  |  | 4281 |             $newcategory->categoryid = $catid;
 | 
        
           |  |  | 4282 |             $DB->insert_record('glossary_entries_categories', $newcategory, false);
 | 
        
           |  |  | 4283 |         }
 | 
        
           |  |  | 4284 |     }
 | 
        
           |  |  | 4285 |   | 
        
           |  |  | 4286 |     // Update aliases.
 | 
        
           |  |  | 4287 |     $DB->delete_records('glossary_alias', array('entryid' => $entry->id));
 | 
        
           |  |  | 4288 |     if ($aliases !== '') {
 | 
        
           |  |  | 4289 |         $aliases = explode("\n", $aliases);
 | 
        
           |  |  | 4290 |         foreach ($aliases as $alias) {
 | 
        
           |  |  | 4291 |             $alias = trim($alias);
 | 
        
           |  |  | 4292 |             if ($alias !== '') {
 | 
        
           |  |  | 4293 |                 $newalias = new stdClass();
 | 
        
           |  |  | 4294 |                 $newalias->entryid = $entry->id;
 | 
        
           |  |  | 4295 |                 $newalias->alias   = $alias;
 | 
        
           |  |  | 4296 |                 $DB->insert_record('glossary_alias', $newalias, false);
 | 
        
           |  |  | 4297 |             }
 | 
        
           |  |  | 4298 |         }
 | 
        
           |  |  | 4299 |     }
 | 
        
           |  |  | 4300 |   | 
        
           |  |  | 4301 |     // Trigger event and update completion (if entry was created).
 | 
        
           |  |  | 4302 |     $eventparams = array(
 | 
        
           |  |  | 4303 |         'context' => $context,
 | 
        
           |  |  | 4304 |         'objectid' => $entry->id,
 | 
        
           |  |  | 4305 |         'other' => array('concept' => $entry->concept)
 | 
        
           |  |  | 4306 |     );
 | 
        
           |  |  | 4307 |     if ($isnewentry) {
 | 
        
           |  |  | 4308 |         $event = \mod_glossary\event\entry_created::create($eventparams);
 | 
        
           |  |  | 4309 |     } else {
 | 
        
           |  |  | 4310 |         $event = \mod_glossary\event\entry_updated::create($eventparams);
 | 
        
           |  |  | 4311 |     }
 | 
        
           |  |  | 4312 |     $event->add_record_snapshot('glossary_entries', $entry);
 | 
        
           |  |  | 4313 |     $event->trigger();
 | 
        
           |  |  | 4314 |     if ($isnewentry) {
 | 
        
           |  |  | 4315 |         // Update completion state.
 | 
        
           |  |  | 4316 |         $completion = new completion_info($course);
 | 
        
           |  |  | 4317 |         if ($completion->is_enabled($cm) == COMPLETION_TRACKING_AUTOMATIC && $glossary->completionentries && $entry->approved) {
 | 
        
           |  |  | 4318 |             $completion->update_state($cm, COMPLETION_COMPLETE);
 | 
        
           |  |  | 4319 |         }
 | 
        
           |  |  | 4320 |     }
 | 
        
           |  |  | 4321 |   | 
        
           |  |  | 4322 |     // Reset caches.
 | 
        
           |  |  | 4323 |     if ($isnewentry) {
 | 
        
           |  |  | 4324 |         if ($entry->usedynalink and $entry->approved) {
 | 
        
           |  |  | 4325 |             \mod_glossary\local\concept_cache::reset_glossary($glossary);
 | 
        
           |  |  | 4326 |         }
 | 
        
           |  |  | 4327 |     } else {
 | 
        
           |  |  | 4328 |         // So many things may affect the linking, let's just purge the cache always on edit.
 | 
        
           |  |  | 4329 |         \mod_glossary\local\concept_cache::reset_glossary($glossary);
 | 
        
           |  |  | 4330 |     }
 | 
        
           |  |  | 4331 |     return $entry;
 | 
        
           |  |  | 4332 | }
 | 
        
           |  |  | 4333 |   | 
        
           |  |  | 4334 | /**
 | 
        
           |  |  | 4335 |  * Check if the module has any update that affects the current user since a given time.
 | 
        
           |  |  | 4336 |  *
 | 
        
           |  |  | 4337 |  * @param  cm_info $cm course module data
 | 
        
           |  |  | 4338 |  * @param  int $from the time to check updates from
 | 
        
           |  |  | 4339 |  * @param  array $filter  if we need to check only specific updates
 | 
        
           |  |  | 4340 |  * @return stdClass an object with the different type of areas indicating if they were updated or not
 | 
        
           |  |  | 4341 |  * @since Moodle 3.2
 | 
        
           |  |  | 4342 |  */
 | 
        
           |  |  | 4343 | function glossary_check_updates_since(cm_info $cm, $from, $filter = array()) {
 | 
        
           |  |  | 4344 |     global $DB;
 | 
        
           |  |  | 4345 |   | 
        
           |  |  | 4346 |     $updates = course_check_module_updates_since($cm, $from, array('attachment', 'entry'), $filter);
 | 
        
           |  |  | 4347 |   | 
        
           |  |  | 4348 |     $updates->entries = (object) array('updated' => false);
 | 
        
           |  |  | 4349 |     $select = 'glossaryid = :id AND (timecreated > :since1 OR timemodified > :since2)';
 | 
        
           |  |  | 4350 |     $params = array('id' => $cm->instance, 'since1' => $from, 'since2' => $from);
 | 
        
           |  |  | 4351 |     if (!has_capability('mod/glossary:approve', $cm->context)) {
 | 
        
           |  |  | 4352 |         $select .= ' AND approved = 1';
 | 
        
           |  |  | 4353 |     }
 | 
        
           |  |  | 4354 |   | 
        
           |  |  | 4355 |     $entries = $DB->get_records_select('glossary_entries', $select, $params, '', 'id');
 | 
        
           |  |  | 4356 |     if (!empty($entries)) {
 | 
        
           |  |  | 4357 |         $updates->entries->updated = true;
 | 
        
           |  |  | 4358 |         $updates->entries->itemids = array_keys($entries);
 | 
        
           |  |  | 4359 |     }
 | 
        
           |  |  | 4360 |   | 
        
           |  |  | 4361 |     return $updates;
 | 
        
           |  |  | 4362 | }
 | 
        
           |  |  | 4363 |   | 
        
           |  |  | 4364 | /**
 | 
        
           |  |  | 4365 |  * Get icon mapping for font-awesome.
 | 
        
           |  |  | 4366 |  *
 | 
        
           |  |  | 4367 |  * @return array
 | 
        
           |  |  | 4368 |  */
 | 
        
           |  |  | 4369 | function mod_glossary_get_fontawesome_icon_map() {
 | 
        
           |  |  | 4370 |     return [
 | 
        
           | 1441 | ariadna | 4371 |         'mod_glossary:asc' => 'fa-sort-down',
 | 
        
           |  |  | 4372 |         'mod_glossary:desc' => 'fa-sort-up',
 | 
        
           |  |  | 4373 |         'mod_glossary:export' => 'fa-arrow-turn-up',
 | 
        
           |  |  | 4374 |         'mod_glossary:minus' => 'fa-minus',
 | 
        
           | 1 | efrain | 4375 |     ];
 | 
        
           |  |  | 4376 | }
 | 
        
           |  |  | 4377 |   | 
        
           |  |  | 4378 | /**
 | 
        
           |  |  | 4379 |  * This function receives a calendar event and returns the action associated with it, or null if there is none.
 | 
        
           |  |  | 4380 |  *
 | 
        
           |  |  | 4381 |  * This is used by block_myoverview in order to display the event appropriately. If null is returned then the event
 | 
        
           |  |  | 4382 |  * is not displayed on the block.
 | 
        
           |  |  | 4383 |  *
 | 
        
           |  |  | 4384 |  * @param calendar_event $event
 | 
        
           |  |  | 4385 |  * @param \core_calendar\action_factory $factory
 | 
        
           |  |  | 4386 |  * @param int $userid User id to use for all capability checks, etc. Set to 0 for current user (default).
 | 
        
           |  |  | 4387 |  * @return \core_calendar\local\event\entities\action_interface|null
 | 
        
           |  |  | 4388 |  */
 | 
        
           |  |  | 4389 | function mod_glossary_core_calendar_provide_event_action(calendar_event $event,
 | 
        
           |  |  | 4390 |                                                          \core_calendar\action_factory $factory,
 | 
        
           |  |  | 4391 |                                                          int $userid = 0) {
 | 
        
           |  |  | 4392 |     global $USER;
 | 
        
           |  |  | 4393 |   | 
        
           |  |  | 4394 |     if (!$userid) {
 | 
        
           |  |  | 4395 |         $userid = $USER->id;
 | 
        
           |  |  | 4396 |     }
 | 
        
           |  |  | 4397 |   | 
        
           |  |  | 4398 |     $cm = get_fast_modinfo($event->courseid, $userid)->instances['glossary'][$event->instance];
 | 
        
           |  |  | 4399 |   | 
        
           |  |  | 4400 |     if (!$cm->uservisible) {
 | 
        
           |  |  | 4401 |         // The module is not visible to the user for any reason.
 | 
        
           |  |  | 4402 |         return null;
 | 
        
           |  |  | 4403 |     }
 | 
        
           |  |  | 4404 |   | 
        
           |  |  | 4405 |     $completion = new \completion_info($cm->get_course());
 | 
        
           |  |  | 4406 |   | 
        
           |  |  | 4407 |     $completiondata = $completion->get_data($cm, false, $userid);
 | 
        
           |  |  | 4408 |   | 
        
           |  |  | 4409 |     if ($completiondata->completionstate != COMPLETION_INCOMPLETE) {
 | 
        
           |  |  | 4410 |         return null;
 | 
        
           |  |  | 4411 |     }
 | 
        
           |  |  | 4412 |   | 
        
           |  |  | 4413 |     return $factory->create_instance(
 | 
        
           |  |  | 4414 |         get_string('view'),
 | 
        
           |  |  | 4415 |         new \moodle_url('/mod/glossary/view.php', ['id' => $cm->id]),
 | 
        
           |  |  | 4416 |         1,
 | 
        
           |  |  | 4417 |         true
 | 
        
           |  |  | 4418 |     );
 | 
        
           |  |  | 4419 | }
 | 
        
           |  |  | 4420 |   | 
        
           |  |  | 4421 | /**
 | 
        
           |  |  | 4422 |  * Add a get_coursemodule_info function in case any glossary type wants to add 'extra' information
 | 
        
           |  |  | 4423 |  * for the course (see resource).
 | 
        
           |  |  | 4424 |  *
 | 
        
           |  |  | 4425 |  * Given a course_module object, this function returns any "extra" information that may be needed
 | 
        
           |  |  | 4426 |  * when printing this activity in a course listing.  See get_array_of_activities() in course/lib.php.
 | 
        
           |  |  | 4427 |  *
 | 
        
           |  |  | 4428 |  * @param stdClass $coursemodule The coursemodule object (record).
 | 
        
           |  |  | 4429 |  * @return cached_cm_info An object on information that the courses
 | 
        
           |  |  | 4430 |  *                        will know about (most noticeably, an icon).
 | 
        
           |  |  | 4431 |  */
 | 
        
           |  |  | 4432 | function glossary_get_coursemodule_info($coursemodule) {
 | 
        
           |  |  | 4433 |     global $DB;
 | 
        
           |  |  | 4434 |   | 
        
           |  |  | 4435 |     $dbparams = ['id' => $coursemodule->instance];
 | 
        
           |  |  | 4436 |     $fields = 'id, name, intro, introformat, completionentries';
 | 
        
           |  |  | 4437 |     if (!$glossary = $DB->get_record('glossary', $dbparams, $fields)) {
 | 
        
           |  |  | 4438 |         return false;
 | 
        
           |  |  | 4439 |     }
 | 
        
           |  |  | 4440 |   | 
        
           |  |  | 4441 |     $result = new cached_cm_info();
 | 
        
           |  |  | 4442 |     $result->name = $glossary->name;
 | 
        
           |  |  | 4443 |   | 
        
           |  |  | 4444 |     if ($coursemodule->showdescription) {
 | 
        
           |  |  | 4445 |         // Convert intro to html. Do not filter cached version, filters run at display time.
 | 
        
           |  |  | 4446 |         $result->content = format_module_intro('glossary', $glossary, $coursemodule->id, false);
 | 
        
           |  |  | 4447 |     }
 | 
        
           |  |  | 4448 |   | 
        
           |  |  | 4449 |     // Populate the custom completion rules as key => value pairs, but only if the completion mode is 'automatic'.
 | 
        
           |  |  | 4450 |     if ($coursemodule->completion == COMPLETION_TRACKING_AUTOMATIC) {
 | 
        
           |  |  | 4451 |         $result->customdata['customcompletionrules']['completionentries'] = $glossary->completionentries;
 | 
        
           |  |  | 4452 |     }
 | 
        
           |  |  | 4453 |   | 
        
           |  |  | 4454 |     return $result;
 | 
        
           |  |  | 4455 | }
 | 
        
           |  |  | 4456 |   | 
        
           |  |  | 4457 | /**
 | 
        
           |  |  | 4458 |  * Callback which returns human-readable strings describing the active completion custom rules for the module instance.
 | 
        
           |  |  | 4459 |  *
 | 
        
           |  |  | 4460 |  * @param cm_info|stdClass $cm object with fields ->completion and ->customdata['customcompletionrules']
 | 
        
           |  |  | 4461 |  * @return array $descriptions the array of descriptions for the custom rules.
 | 
        
           |  |  | 4462 |  */
 | 
        
           |  |  | 4463 | function mod_glossary_get_completion_active_rule_descriptions($cm) {
 | 
        
           |  |  | 4464 |     // Values will be present in cm_info, and we assume these are up to date.
 | 
        
           |  |  | 4465 |     if (empty($cm->customdata['customcompletionrules'])
 | 
        
           |  |  | 4466 |         || $cm->completion != COMPLETION_TRACKING_AUTOMATIC) {
 | 
        
           |  |  | 4467 |         return [];
 | 
        
           |  |  | 4468 |     }
 | 
        
           |  |  | 4469 |   | 
        
           |  |  | 4470 |     $descriptions = [];
 | 
        
           |  |  | 4471 |     foreach ($cm->customdata['customcompletionrules'] as $key => $val) {
 | 
        
           |  |  | 4472 |         switch ($key) {
 | 
        
           |  |  | 4473 |             case 'completionentries':
 | 
        
           |  |  | 4474 |                 if (!empty($val)) {
 | 
        
           |  |  | 4475 |                     $descriptions[] = get_string('completionentriesdesc', 'glossary', $val);
 | 
        
           |  |  | 4476 |                 }
 | 
        
           |  |  | 4477 |                 break;
 | 
        
           |  |  | 4478 |             default:
 | 
        
           |  |  | 4479 |                 break;
 | 
        
           |  |  | 4480 |         }
 | 
        
           |  |  | 4481 |     }
 | 
        
           |  |  | 4482 |     return $descriptions;
 | 
        
           |  |  | 4483 | }
 | 
        
           |  |  | 4484 |   | 
        
           |  |  | 4485 | /**
 | 
        
           |  |  | 4486 |  * Checks if the current user can delete the given glossary entry.
 | 
        
           |  |  | 4487 |  *
 | 
        
           |  |  | 4488 |  * @since Moodle 3.10
 | 
        
           |  |  | 4489 |  * @param stdClass $entry the entry database object
 | 
        
           |  |  | 4490 |  * @param stdClass $glossary the glossary database object
 | 
        
           |  |  | 4491 |  * @param stdClass $context the glossary context
 | 
        
           |  |  | 4492 |  * @param bool $return Whether to return a boolean value or stop the execution (exception)
 | 
        
           |  |  | 4493 |  * @return bool if the user can delete the entry
 | 
        
           |  |  | 4494 |  * @throws moodle_exception
 | 
        
           |  |  | 4495 |  */
 | 
        
           |  |  | 4496 | function mod_glossary_can_delete_entry($entry, $glossary, $context, $return = true) {
 | 
        
           |  |  | 4497 |     global $USER, $CFG;
 | 
        
           |  |  | 4498 |   | 
        
           |  |  | 4499 |     $manageentries = has_capability('mod/glossary:manageentries', $context);
 | 
        
           |  |  | 4500 |   | 
        
           |  |  | 4501 |     if ($manageentries) {   // Users with the capability will always be able to delete entries.
 | 
        
           |  |  | 4502 |         return true;
 | 
        
           |  |  | 4503 |     }
 | 
        
           |  |  | 4504 |   | 
        
           |  |  | 4505 |     if ($entry->userid != $USER->id) { // Guest id is never matched, no need for special check here.
 | 
        
           |  |  | 4506 |         if ($return) {
 | 
        
           |  |  | 4507 |             return false;
 | 
        
           |  |  | 4508 |         }
 | 
        
           |  |  | 4509 |         throw new moodle_exception('nopermissiontodelentry');
 | 
        
           |  |  | 4510 |     }
 | 
        
           |  |  | 4511 |   | 
        
           |  |  | 4512 |     $ineditperiod = ((time() - $entry->timecreated < $CFG->maxeditingtime) || $glossary->editalways);
 | 
        
           |  |  | 4513 |   | 
        
           |  |  | 4514 |     if (!$ineditperiod) {
 | 
        
           |  |  | 4515 |         if ($return) {
 | 
        
           |  |  | 4516 |             return false;
 | 
        
           |  |  | 4517 |         }
 | 
        
           |  |  | 4518 |         throw new moodle_exception('errdeltimeexpired', 'glossary');
 | 
        
           |  |  | 4519 |     }
 | 
        
           |  |  | 4520 |   | 
        
           |  |  | 4521 |     return true;
 | 
        
           |  |  | 4522 | }
 | 
        
           |  |  | 4523 |   | 
        
           |  |  | 4524 | /**
 | 
        
           |  |  | 4525 |  * Deletes the given entry, this function does not perform capabilities/permission checks.
 | 
        
           |  |  | 4526 |  *
 | 
        
           |  |  | 4527 |  * @since Moodle 3.10
 | 
        
           |  |  | 4528 |  * @param stdClass $entry the entry database object
 | 
        
           |  |  | 4529 |  * @param stdClass $glossary the glossary database object
 | 
        
           |  |  | 4530 |  * @param stdClass $cm the glossary course moduule object
 | 
        
           |  |  | 4531 |  * @param stdClass $context the glossary context
 | 
        
           |  |  | 4532 |  * @param stdClass $course the glossary course
 | 
        
           |  |  | 4533 |  * @param string $hook the hook, usually type of filtering, value
 | 
        
           |  |  | 4534 |  * @param string $prevmode the previsualisation mode
 | 
        
           |  |  | 4535 |  * @throws moodle_exception
 | 
        
           |  |  | 4536 |  */
 | 
        
           |  |  | 4537 | function mod_glossary_delete_entry($entry, $glossary, $cm, $context, $course, $hook = '', $prevmode = '') {
 | 
        
           |  |  | 4538 |     global $CFG, $DB;
 | 
        
           |  |  | 4539 |   | 
        
           |  |  | 4540 |     $origentry = fullclone($entry);
 | 
        
           |  |  | 4541 |   | 
        
           |  |  | 4542 |     // If it is an imported entry, just delete the relation.
 | 
        
           |  |  | 4543 |     if ($entry->sourceglossaryid) {
 | 
        
           |  |  | 4544 |         if (!$newcm = get_coursemodule_from_instance('glossary', $entry->sourceglossaryid)) {
 | 
        
           |  |  | 4545 |             throw new \moodle_exception('invalidcoursemodule');
 | 
        
           |  |  | 4546 |         }
 | 
        
           |  |  | 4547 |         $newcontext = context_module::instance($newcm->id);
 | 
        
           |  |  | 4548 |   | 
        
           |  |  | 4549 |         $entry->glossaryid       = $entry->sourceglossaryid;
 | 
        
           |  |  | 4550 |         $entry->sourceglossaryid = 0;
 | 
        
           |  |  | 4551 |         $DB->update_record('glossary_entries', $entry);
 | 
        
           |  |  | 4552 |   | 
        
           |  |  | 4553 |         // Move attachments too.
 | 
        
           |  |  | 4554 |         $fs = get_file_storage();
 | 
        
           |  |  | 4555 |   | 
        
           |  |  | 4556 |         if ($oldfiles = $fs->get_area_files($context->id, 'mod_glossary', 'attachment', $entry->id)) {
 | 
        
           |  |  | 4557 |             foreach ($oldfiles as $oldfile) {
 | 
        
           |  |  | 4558 |                 $filerecord = new stdClass();
 | 
        
           |  |  | 4559 |                 $filerecord->contextid = $newcontext->id;
 | 
        
           |  |  | 4560 |                 $fs->create_file_from_storedfile($filerecord, $oldfile);
 | 
        
           |  |  | 4561 |             }
 | 
        
           |  |  | 4562 |             $fs->delete_area_files($context->id, 'mod_glossary', 'attachment', $entry->id);
 | 
        
           |  |  | 4563 |             $entry->attachment = '1';
 | 
        
           |  |  | 4564 |         } else {
 | 
        
           |  |  | 4565 |             $entry->attachment = '0';
 | 
        
           |  |  | 4566 |         }
 | 
        
           |  |  | 4567 |         $DB->update_record('glossary_entries', $entry);
 | 
        
           |  |  | 4568 |   | 
        
           |  |  | 4569 |     } else {
 | 
        
           |  |  | 4570 |         $fs = get_file_storage();
 | 
        
           |  |  | 4571 |         $fs->delete_area_files($context->id, 'mod_glossary', 'attachment', $entry->id);
 | 
        
           |  |  | 4572 |         $DB->delete_records("comments",
 | 
        
           |  |  | 4573 |             ['itemid' => $entry->id, 'commentarea' => 'glossary_entry', 'contextid' => $context->id]);
 | 
        
           |  |  | 4574 |         $DB->delete_records("glossary_alias", ["entryid" => $entry->id]);
 | 
        
           |  |  | 4575 |         $DB->delete_records("glossary_entries", ["id" => $entry->id]);
 | 
        
           |  |  | 4576 |   | 
        
           |  |  | 4577 |         // Update completion state.
 | 
        
           |  |  | 4578 |         $completion = new completion_info($course);
 | 
        
           |  |  | 4579 |         if ($completion->is_enabled($cm) == COMPLETION_TRACKING_AUTOMATIC && $glossary->completionentries) {
 | 
        
           |  |  | 4580 |             $completion->update_state($cm, COMPLETION_INCOMPLETE, $entry->userid);
 | 
        
           |  |  | 4581 |         }
 | 
        
           |  |  | 4582 |   | 
        
           |  |  | 4583 |         // Delete glossary entry ratings.
 | 
        
           |  |  | 4584 |         require_once($CFG->dirroot.'/rating/lib.php');
 | 
        
           |  |  | 4585 |         $delopt = new stdClass;
 | 
        
           |  |  | 4586 |         $delopt->contextid = $context->id;
 | 
        
           |  |  | 4587 |         $delopt->component = 'mod_glossary';
 | 
        
           |  |  | 4588 |         $delopt->ratingarea = 'entry';
 | 
        
           |  |  | 4589 |         $delopt->itemid = $entry->id;
 | 
        
           |  |  | 4590 |         $rm = new rating_manager();
 | 
        
           |  |  | 4591 |         $rm->delete_ratings($delopt);
 | 
        
           |  |  | 4592 |     }
 | 
        
           |  |  | 4593 |   | 
        
           |  |  | 4594 |     // Delete cached RSS feeds.
 | 
        
           |  |  | 4595 |     if (!empty($CFG->enablerssfeeds)) {
 | 
        
           |  |  | 4596 |         require_once($CFG->dirroot . '/mod/glossary/rsslib.php');
 | 
        
           |  |  | 4597 |         glossary_rss_delete_file($glossary);
 | 
        
           |  |  | 4598 |     }
 | 
        
           |  |  | 4599 |   | 
        
           |  |  | 4600 |     core_tag_tag::remove_all_item_tags('mod_glossary', 'glossary_entries', $origentry->id);
 | 
        
           |  |  | 4601 |   | 
        
           |  |  | 4602 |     $event = \mod_glossary\event\entry_deleted::create(
 | 
        
           |  |  | 4603 |         [
 | 
        
           |  |  | 4604 |             'context' => $context,
 | 
        
           |  |  | 4605 |             'objectid' => $origentry->id,
 | 
        
           |  |  | 4606 |             'other' => [
 | 
        
           |  |  | 4607 |                 'mode' => $prevmode,
 | 
        
           |  |  | 4608 |                 'hook' => $hook,
 | 
        
           |  |  | 4609 |                 'concept' => $origentry->concept
 | 
        
           |  |  | 4610 |             ]
 | 
        
           |  |  | 4611 |         ]
 | 
        
           |  |  | 4612 |     );
 | 
        
           |  |  | 4613 |     $event->add_record_snapshot('glossary_entries', $origentry);
 | 
        
           |  |  | 4614 |     $event->trigger();
 | 
        
           |  |  | 4615 |   | 
        
           |  |  | 4616 |     // Reset caches.
 | 
        
           |  |  | 4617 |     if ($entry->usedynalink and $entry->approved) {
 | 
        
           |  |  | 4618 |         \mod_glossary\local\concept_cache::reset_glossary($glossary);
 | 
        
           |  |  | 4619 |     }
 | 
        
           |  |  | 4620 | }
 | 
        
           |  |  | 4621 |   | 
        
           |  |  | 4622 | /**
 | 
        
           |  |  | 4623 |  * Checks if the current user can update the given glossary entry.
 | 
        
           |  |  | 4624 |  *
 | 
        
           |  |  | 4625 |  * @since Moodle 3.10
 | 
        
           |  |  | 4626 |  * @param stdClass $entry the entry database object
 | 
        
           |  |  | 4627 |  * @param stdClass $glossary the glossary database object
 | 
        
           |  |  | 4628 |  * @param stdClass $context the glossary context
 | 
        
           |  |  | 4629 |  * @param object $cm the course module object (cm record or cm_info instance)
 | 
        
           |  |  | 4630 |  * @param bool $return Whether to return a boolean value or stop the execution (exception)
 | 
        
           |  |  | 4631 |  * @return bool if the user can update the entry
 | 
        
           |  |  | 4632 |  * @throws moodle_exception
 | 
        
           |  |  | 4633 |  */
 | 
        
           |  |  | 4634 | function mod_glossary_can_update_entry(stdClass $entry, stdClass $glossary, stdClass $context, object $cm,
 | 
        
           |  |  | 4635 |         bool $return = true): bool {
 | 
        
           |  |  | 4636 |   | 
        
           |  |  | 4637 |     global $USER, $CFG;
 | 
        
           |  |  | 4638 |   | 
        
           |  |  | 4639 |     $ineditperiod = ((time() - $entry->timecreated < $CFG->maxeditingtime) || $glossary->editalways);
 | 
        
           |  |  | 4640 |     if (!has_capability('mod/glossary:manageentries', $context) and
 | 
        
           |  |  | 4641 |             !($entry->userid == $USER->id and ($ineditperiod and has_capability('mod/glossary:write', $context)))) {
 | 
        
           |  |  | 4642 |   | 
        
           |  |  | 4643 |         if ($USER->id != $entry->userid) {
 | 
        
           |  |  | 4644 |             if ($return) {
 | 
        
           |  |  | 4645 |                 return false;
 | 
        
           |  |  | 4646 |             }
 | 
        
           |  |  | 4647 |             throw new moodle_exception('errcannoteditothers', 'glossary', "view.php?id=$cm->id&mode=entry&hook=$entry->id");
 | 
        
           |  |  | 4648 |         } else if (!$ineditperiod) {
 | 
        
           |  |  | 4649 |             if ($return) {
 | 
        
           |  |  | 4650 |                 return false;
 | 
        
           |  |  | 4651 |             }
 | 
        
           |  |  | 4652 |             throw new moodle_exception('erredittimeexpired', 'glossary', "view.php?id=$cm->id&mode=entry&hook=$entry->id");
 | 
        
           |  |  | 4653 |         }
 | 
        
           |  |  | 4654 |     }
 | 
        
           |  |  | 4655 |   | 
        
           |  |  | 4656 |     return true;
 | 
        
           |  |  | 4657 | }
 | 
        
           |  |  | 4658 |   | 
        
           |  |  | 4659 | /**
 | 
        
           |  |  | 4660 |  * Prepares an entry for editing, adding aliases and category information.
 | 
        
           |  |  | 4661 |  *
 | 
        
           |  |  | 4662 |  * @param  stdClass $entry the entry being edited
 | 
        
           |  |  | 4663 |  * @return stdClass the entry with the additional data
 | 
        
           |  |  | 4664 |  */
 | 
        
           |  |  | 4665 | function mod_glossary_prepare_entry_for_edition(stdClass $entry): stdClass {
 | 
        
           |  |  | 4666 |     global $DB;
 | 
        
           |  |  | 4667 |   | 
        
           |  |  | 4668 |     if ($aliases = $DB->get_records_menu("glossary_alias", ["entryid" => $entry->id], '', 'id, alias')) {
 | 
        
           |  |  | 4669 |         $entry->aliases = implode("\n", $aliases) . "\n";
 | 
        
           |  |  | 4670 |     }
 | 
        
           |  |  | 4671 |     if ($categoriesarr = $DB->get_records_menu("glossary_entries_categories", ['entryid' => $entry->id], '', 'id, categoryid')) {
 | 
        
           |  |  | 4672 |         // TODO: this fetches cats from both main and secondary glossary :-(
 | 
        
           |  |  | 4673 |         $entry->categories = array_values($categoriesarr);
 | 
        
           |  |  | 4674 |     }
 | 
        
           |  |  | 4675 |   | 
        
           |  |  | 4676 |     return $entry;
 | 
        
           |  |  | 4677 | }
 |