Search moodle.org's
Developer Documentation

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
  • Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 37 and 311] [Versions 38 and 311] [Versions 39 and 311]

       1  <?php
       2  
       3  /// This page prints a particular instance of glossary
       4  require_once("../../config.php");
       5  require_once ("lib.php");
       6  require_once($CFG->libdir . '/completionlib.php');
       7  require_once("$CFG->libdir/rsslib.php");
       8  
       9  $id = optional_param('id', 0, PARAM_INT);           // Course Module ID
      10  $g  = optional_param('g', 0, PARAM_INT);            // Glossary ID
      11  
      12  $tab  = optional_param('tab', GLOSSARY_NO_VIEW, PARAM_ALPHA);    // browsing entries by categories?
      13  $displayformat = optional_param('displayformat',-1, PARAM_INT);  // override of the glossary display format
      14  
      15  $mode       = optional_param('mode', '', PARAM_ALPHA);           // term entry cat date letter search author approval
      16  $hook       = optional_param('hook', '', PARAM_CLEAN);           // the term, entry, cat, etc... to look for based on mode
      17  $fullsearch = optional_param('fullsearch', 0,PARAM_INT);         // full search (concept and definition) when searching?
      18  $sortkey    = optional_param('sortkey', '', PARAM_ALPHA);// Sorted view: CREATION | UPDATE | FIRSTNAME | LASTNAME...
      19  $sortorder  = optional_param('sortorder', 'ASC', PARAM_ALPHA);   // it defines the order of the sorting (ASC or DESC)
      20  $offset     = optional_param('offset', 0,PARAM_INT);             // entries to bypass (for paging purposes)
      21  $page       = optional_param('page', 0,PARAM_INT);               // Page to show (for paging purposes)
      22  $show       = optional_param('show', '', PARAM_ALPHA);           // [ concept | alias ] => mode=term hook=$show
      23  
      24  if (!empty($id)) {
      25      if (! $cm = get_coursemodule_from_id('glossary', $id)) {
      26          print_error('invalidcoursemodule');
      27      }
      28      if (! $course = $DB->get_record("course", array("id"=>$cm->course))) {
      29          print_error('coursemisconf');
      30      }
      31      if (! $glossary = $DB->get_record("glossary", array("id"=>$cm->instance))) {
      32          print_error('invalidid', 'glossary');
      33      }
      34  
      35  } else if (!empty($g)) {
      36      if (! $glossary = $DB->get_record("glossary", array("id"=>$g))) {
      37          print_error('invalidid', 'glossary');
      38      }
      39      if (! $course = $DB->get_record("course", array("id"=>$glossary->course))) {
      40          print_error('invalidcourseid');
      41      }
      42      if (!$cm = get_coursemodule_from_instance("glossary", $glossary->id, $course->id)) {
      43          print_error('invalidcoursemodule');
      44      }
      45      $id = $cm->id;
      46  } else {
      47      print_error('invalidid', 'glossary');
      48  }
      49  $cm = cm_info::create($cm);
      50  
      51  require_course_login($course->id, true, $cm);
      52  $context = context_module::instance($cm->id);
      53  require_capability('mod/glossary:view', $context);
      54  
      55  // Prepare format_string/text options
      56  $fmtoptions = array(
      57      'context' => $context);
      58  
      59  require_once($CFG->dirroot . '/comment/lib.php');
      60  comment::init();
      61  
      62  /// redirecting if adding a new entry
      63  if ($tab == GLOSSARY_ADDENTRY_VIEW ) {
      64      redirect("edit.php?cmid=$cm->id&amp;mode=$mode");
      65  }
      66  
      67  /// setting the defaut number of entries per page if not set
      68  if ( !$entriesbypage = $glossary->entbypage ) {
      69      $entriesbypage = $CFG->glossary_entbypage;
      70  }
      71  
      72  // If we have received a page, recalculate offset and page size.
      73  $pagelimit = $entriesbypage;
      74  if ($page > 0 && $offset == 0) {
      75      $offset = $page * $entriesbypage;
      76  } else if ($page < 0) {
      77      $offset = 0;
      78      $pagelimit = 0;
      79  }
      80  
      81  /// setting the default values for the display mode of the current glossary
      82  /// only if the glossary is viewed by the first time
      83  if ( $dp = $DB->get_record('glossary_formats', array('name'=>$glossary->displayformat)) ) {
      84  /// Based on format->defaultmode, we build the defaulttab to be showed sometimes
      85      $showtabs = glossary_get_visible_tabs($dp);
      86      switch ($dp->defaultmode) {
      87          case 'cat':
      88              $defaulttab = GLOSSARY_CATEGORY_VIEW;
      89  
      90              // Handle defaultmode if 'category' tab is disabled. Fallback to 'standard' tab.
      91              if (!in_array(GLOSSARY_CATEGORY, $showtabs)) {
      92                  $defaulttab = GLOSSARY_STANDARD_VIEW;
      93              }
      94  
      95              break;
      96          case 'date':
      97              $defaulttab = GLOSSARY_DATE_VIEW;
      98  
      99              // Handle defaultmode if 'date' tab is disabled. Fallback to 'standard' tab.
     100              if (!in_array(GLOSSARY_DATE, $showtabs)) {
     101                  $defaulttab = GLOSSARY_STANDARD_VIEW;
     102              }
     103  
     104              break;
     105          case 'author':
     106              $defaulttab = GLOSSARY_AUTHOR_VIEW;
     107  
     108              // Handle defaultmode if 'author' tab is disabled. Fallback to 'standard' tab.
     109              if (!in_array(GLOSSARY_AUTHOR, $showtabs)) {
     110                  $defaulttab = GLOSSARY_STANDARD_VIEW;
     111              }
     112  
     113              break;
     114          default:
     115              $defaulttab = GLOSSARY_STANDARD_VIEW;
     116      }
     117  /// Fetch the rest of variables
     118      $printpivot = $dp->showgroup;
     119      if ( $mode == '' and $hook == '' and $show == '') {
     120          $mode      = $dp->defaultmode;
     121          $hook      = $dp->defaulthook;
     122          $sortkey   = $dp->sortkey;
     123          $sortorder = $dp->sortorder;
     124      }
     125  } else {
     126      $defaulttab = GLOSSARY_STANDARD_VIEW;
     127      $showtabs = array($defaulttab);
     128      $printpivot = 1;
     129      if ( $mode == '' and $hook == '' and $show == '') {
     130          $mode = 'letter';
     131          $hook = 'ALL';
     132      }
     133  }
     134  
     135  if ( $displayformat == -1 ) {
     136       $displayformat = $glossary->displayformat;
     137  }
     138  
     139  if ( $show ) {
     140      $mode = 'term';
     141      $hook = $show;
     142      $show = '';
     143  }
     144  
     145  /// stablishing flag variables
     146  if ( $sortorder = strtolower($sortorder) ) {
     147      if ($sortorder != 'asc' and $sortorder != 'desc') {
     148          $sortorder = '';
     149      }
     150  }
     151  if ( $sortkey = strtoupper($sortkey) ) {
     152      if ($sortkey != 'CREATION' and
     153          $sortkey != 'UPDATE' and
     154          $sortkey != 'FIRSTNAME' and
     155          $sortkey != 'LASTNAME'
     156          ) {
     157          $sortkey = '';
     158      }
     159  }
     160  
     161  switch ( $mode = strtolower($mode) ) {
     162  case 'search': /// looking for terms containing certain word(s)
     163      $tab = GLOSSARY_STANDARD_VIEW;
     164  
     165      //Clean a bit the search string
     166      $hook = trim(strip_tags($hook));
     167  
     168  break;
     169  
     170  case 'entry':  /// Looking for a certain entry id
     171      $tab = GLOSSARY_STANDARD_VIEW;
     172      if ( $dp = $DB->get_record("glossary_formats", array("name"=>$glossary->displayformat)) ) {
     173          $displayformat = $dp->popupformatname;
     174      }
     175  break;
     176  
     177  case 'cat':    /// Looking for a certain cat
     178      $tab = GLOSSARY_CATEGORY_VIEW;
     179  
     180      // Validation - we don't want to display 'category' tab if it is disabled.
     181      if (!in_array(GLOSSARY_CATEGORY, $showtabs)) {
     182          $tab = GLOSSARY_STANDARD_VIEW;
     183      }
     184  
     185      if ( $hook > 0 ) {
     186          $category = $DB->get_record("glossary_categories", array("id"=>$hook));
     187      }
     188  break;
     189  
     190  case 'approval':    /// Looking for entries waiting for approval
     191      $tab = GLOSSARY_APPROVAL_VIEW;
     192      // Override the display format with the approvaldisplayformat
     193      if ($glossary->approvaldisplayformat !== 'default' && ($df = $DB->get_record("glossary_formats",
     194              array("name" => $glossary->approvaldisplayformat)))) {
     195          $displayformat = $df->popupformatname;
     196      }
     197      if ( !$hook and !$sortkey and !$sortorder) {
     198          $hook = 'ALL';
     199      }
     200  break;
     201  
     202  case 'term':   /// Looking for entries that include certain term in its concept, definition or aliases
     203      $tab = GLOSSARY_STANDARD_VIEW;
     204  break;
     205  
     206  case 'date':
     207      $tab = GLOSSARY_DATE_VIEW;
     208  
     209      // Validation - we dont want to display 'date' tab if it is disabled.
     210      if (!in_array(GLOSSARY_DATE, $showtabs)) {
     211          $tab = GLOSSARY_STANDARD_VIEW;
     212      }
     213  
     214      if ( !$sortkey ) {
     215          $sortkey = 'UPDATE';
     216      }
     217      if ( !$sortorder ) {
     218          $sortorder = 'desc';
     219      }
     220  break;
     221  
     222  case 'author':  /// Looking for entries, browsed by author
     223      $tab = GLOSSARY_AUTHOR_VIEW;
     224  
     225      // Validation - we dont want to display 'author' tab if it is disabled.
     226      if (!in_array(GLOSSARY_AUTHOR, $showtabs)) {
     227          $tab = GLOSSARY_STANDARD_VIEW;
     228      }
     229  
     230      if ( !$hook ) {
     231          $hook = 'ALL';
     232      }
     233      if ( !$sortkey ) {
     234          $sortkey = 'FIRSTNAME';
     235      }
     236      if ( !$sortorder ) {
     237          $sortorder = 'asc';
     238      }
     239  break;
     240  
     241  case 'letter':  /// Looking for entries that begin with a certain letter, ALL or SPECIAL characters
     242  default:
     243      $tab = GLOSSARY_STANDARD_VIEW;
     244      if ( !$hook ) {
     245          $hook = 'ALL';
     246      }
     247  break;
     248  }
     249  
     250  switch ( $tab ) {
     251  case GLOSSARY_IMPORT_VIEW:
     252  case GLOSSARY_EXPORT_VIEW:
     253  case GLOSSARY_APPROVAL_VIEW:
     254      $showcommonelements = 0;
     255  break;
     256  
     257  default:
     258      $showcommonelements = 1;
     259  break;
     260  }
     261  
     262  // Trigger module viewed event.
     263  glossary_view($glossary, $course, $cm, $context, $mode);
     264  
     265  /// Printing the heading
     266  $strglossaries = get_string("modulenameplural", "glossary");
     267  $strglossary = get_string("modulename", "glossary");
     268  $strallcategories = get_string("allcategories", "glossary");
     269  $straddentry = get_string("addentry", "glossary");
     270  $strnoentries = get_string("noentries", "glossary");
     271  $strsearchindefinition = get_string("searchindefinition", "glossary");
     272  $strsearch = get_string("search");
     273  $strwaitingapproval = get_string('waitingapproval', 'glossary');
     274  
     275  /// If we are in approval mode, prit special header
     276  $PAGE->set_title($glossary->name);
     277  $PAGE->set_heading($course->fullname);
     278  $url = new moodle_url('/mod/glossary/view.php', array('id'=>$cm->id));
     279  if (isset($mode)) {
     280      $url->param('mode', $mode);
     281  }
     282  $PAGE->set_url($url);
     283  $PAGE->force_settings_menu();
     284  
     285  if (!empty($CFG->enablerssfeeds) && !empty($CFG->glossary_enablerssfeeds)
     286      && $glossary->rsstype && $glossary->rssarticles) {
     287  
     288      $rsstitle = format_string($course->shortname, true, array('context' => context_course::instance($course->id))) . ': '. format_string($glossary->name);
     289      rss_add_http_header($context, 'mod_glossary', $glossary, $rsstitle);
     290  }
     291  
     292  if ($tab == GLOSSARY_APPROVAL_VIEW) {
     293      require_capability('mod/glossary:approve', $context);
     294      $PAGE->navbar->add($strwaitingapproval);
     295      echo $OUTPUT->header();
     296      echo $OUTPUT->heading($strwaitingapproval);
     297  } else { /// Print standard header
     298      echo $OUTPUT->header();
     299  }
     300  echo $OUTPUT->heading(format_string($glossary->name), 2);
     301  
     302  // Render the activity information.
     303  $completiondetails = \core_completion\cm_completion_details::get_instance($cm, $USER->id);
     304  $activitydates = \core\activity_dates::get_dates_for_module($cm, $USER->id);
     305  echo $OUTPUT->activity_information($cm, $completiondetails, $activitydates);
     306  
     307  /// All this depends if whe have $showcommonelements
     308  if ($showcommonelements) {
     309  /// To calculate available options
     310      $availableoptions = '';
     311  
     312  /// Decide about to print the import link
     313      /*if (has_capability('mod/glossary:import', $context)) {
     314          $availableoptions = '<span class="helplink">' .
     315                              '<a href="' . $CFG->wwwroot . '/mod/glossary/import.php?id=' . $cm->id . '"' .
     316                              '  title="' . s(get_string('importentries', 'glossary')) . '">' .
     317                              get_string('importentries', 'glossary') . '</a>' .
     318                              '</span>';
     319      }
     320  /// Decide about to print the export link
     321      if (has_capability('mod/glossary:export', $context)) {
     322          if ($availableoptions) {
     323              $availableoptions .= '&nbsp;/&nbsp;';
     324          }
     325          $availableoptions .='<span class="helplink">' .
     326                              '<a href="' . $CFG->wwwroot . '/mod/glossary/export.php?id=' . $cm->id .
     327                              '&amp;mode='.$mode . '&amp;hook=' . urlencode($hook) . '"' .
     328                              '  title="' . s(get_string('exportentries', 'glossary')) . '">' .
     329                              get_string('exportentries', 'glossary') . '</a>' .
     330                              '</span>';
     331      }*/
     332  
     333  /// Decide about to print the approval link
     334      if (has_capability('mod/glossary:approve', $context)) {
     335      /// Check we have pending entries
     336          if ($hiddenentries = $DB->count_records('glossary_entries', array('glossaryid'=>$glossary->id, 'approved'=>0))) {
     337              if ($availableoptions) {
     338                  $availableoptions .= '<br />';
     339              }
     340              $availableoptions .='<span class="helplink">' .
     341                                  '<a href="' . $CFG->wwwroot . '/mod/glossary/view.php?id=' . $cm->id .
     342                                  '&amp;mode=approval' . '"' .
     343                                  '  title="' . s(get_string('waitingapproval', 'glossary')) . '">' .
     344                                  get_string('waitingapproval', 'glossary') . ' ('.$hiddenentries.')</a>' .
     345                                  '</span>';
     346          }
     347      }
     348  
     349  /// Start to print glossary controls
     350  //        print_box_start('glossarycontrol clearfix');
     351      echo '<div class="glossarycontrol" style="text-align: right">';
     352      echo $availableoptions;
     353  
     354  /// The print icon
     355      if ( $showcommonelements and $mode != 'search') {
     356          if (has_capability('mod/glossary:manageentries', $context) or $glossary->allowprintview) {
     357              $params = array(
     358                  'id'        => $cm->id,
     359                  'mode'      => $mode,
     360                  'hook'      => $hook,
     361                  'sortkey'   => $sortkey,
     362                  'sortorder' => $sortorder,
     363                  'offset'    => $offset,
     364                  'pagelimit' => $pagelimit
     365              );
     366              $printurl = new moodle_url('/mod/glossary/print.php', $params);
     367              $printtitle = get_string('printerfriendly', 'glossary');
     368              $printattributes = array(
     369                  'class' => 'printicon',
     370                  'title' => $printtitle
     371              );
     372              echo html_writer::link($printurl, $printtitle, $printattributes);
     373          }
     374      }
     375  /// End glossary controls
     376  //        print_box_end(); /// glossarycontrol
     377      echo '</div><br />';
     378  
     379  //        print_box('&nbsp;', 'clearer');
     380  }
     381  
     382  /// Info box
     383  if ($glossary->intro && $showcommonelements) {
     384      echo $OUTPUT->box(format_module_intro('glossary', $glossary, $cm->id), 'generalbox', 'intro');
     385  }
     386  
     387  /// Search box
     388  if ($showcommonelements ) {
     389      $fullsearchchecked = false;
     390      if ($fullsearch || $mode != 'search') {
     391          $fullsearchchecked = true;
     392      }
     393  
     394      $check = [
     395          'name' => 'fullsearch',
     396          'id' => 'fullsearch',
     397          'value' => '1',
     398          'checked' => $fullsearchchecked,
     399          'label' => $strsearchindefinition
     400      ];
     401  
     402      $checkbox = $OUTPUT->render_from_template('core/checkbox', $check);
     403  
     404      $hiddenfields = [
     405          (object) ['name' => 'id', 'value' => $cm->id],
     406          (object) ['name' => 'mode', 'value' => 'search'],
     407      ];
     408      $data = [
     409          'action' => new moodle_url('/mod/glossary/view.php'),
     410          'hiddenfields' => $hiddenfields,
     411          'otherfields' => $checkbox,
     412          'inputname' => 'hook',
     413          'query' => ($mode == 'search') ? s($hook) : '',
     414          'searchstring' => get_string('search'),
     415          'extraclasses' => 'my-2'
     416      ];
     417      echo $OUTPUT->render_from_template('core/search_input', $data);
     418  }
     419  
     420  /// Show the add entry button if allowed
     421  if (has_capability('mod/glossary:write', $context) && $showcommonelements ) {
     422      echo '<div class="singlebutton glossaryaddentry">';
     423      echo "<form class=\"form form-inline mb-1\" id=\"newentryform\" method=\"get\" action=\"$CFG->wwwroot/mod/glossary/edit.php\">";
     424      echo '<div>';
     425      echo "<input type=\"hidden\" name=\"cmid\" value=\"$cm->id\" />";
     426      echo '<input type="submit" value="'.get_string('addentry', 'glossary').'" class="btn btn-secondary" />';
     427      echo '</div>';
     428      echo '</form>';
     429      echo "</div>\n";
     430  }
     431  
     432  
     433  require ("tabs.php");
     434  
     435  require ("sql.php");
     436  
     437  /// printing the entries
     438  $entriesshown = 0;
     439  $currentpivot = '';
     440  $paging = NULL;
     441  
     442  if ($allentries) {
     443  
     444      //Decide if we must show the ALL link in the pagebar
     445      $specialtext = '';
     446      if ($glossary->showall) {
     447          $specialtext = get_string("allentries","glossary");
     448      }
     449  
     450      //Build paging bar
     451      $baseurl = new moodle_url('/mod/glossary/view.php', ['id' => $id, 'mode' => $mode, 'hook' => $hook,
     452          'sortkey' => $sortkey, 'sortorder' => $sortorder, 'fullsearch' => $fullsearch]);
     453      $paging = glossary_get_paging_bar($count, $page, $entriesbypage, $baseurl->out() . '&amp;',
     454          9999, 10, '&nbsp;&nbsp;', $specialtext, -1);
     455  
     456      echo '<div class="paging">';
     457      echo $paging;
     458      echo '</div>';
     459  
     460      //load ratings
     461      require_once($CFG->dirroot.'/rating/lib.php');
     462      if ($glossary->assessed != RATING_AGGREGATE_NONE) {
     463          $ratingoptions = new stdClass;
     464          $ratingoptions->context = $context;
     465          $ratingoptions->component = 'mod_glossary';
     466          $ratingoptions->ratingarea = 'entry';
     467          $ratingoptions->items = $allentries;
     468          $ratingoptions->aggregate = $glossary->assessed;//the aggregation method
     469          $ratingoptions->scaleid = $glossary->scale;
     470          $ratingoptions->userid = $USER->id;
     471          $ratingoptions->returnurl = $CFG->wwwroot.'/mod/glossary/view.php?id='.$cm->id;
     472          $ratingoptions->assesstimestart = $glossary->assesstimestart;
     473          $ratingoptions->assesstimefinish = $glossary->assesstimefinish;
     474  
     475          $rm = new rating_manager();
     476          $allentries = $rm->get_ratings($ratingoptions);
     477      }
     478  
     479      foreach ($allentries as $entry) {
     480  
     481          // Setting the pivot for the current entry
     482          if ($printpivot) {
     483              $pivot = $entry->{$pivotkey};
     484              $upperpivot = core_text::strtoupper($pivot);
     485              $pivottoshow = core_text::strtoupper(format_string($pivot, true, $fmtoptions));
     486  
     487              // Reduce pivot to 1cc if necessary.
     488              if (!$fullpivot) {
     489                  $upperpivot = core_text::substr($upperpivot, 0, 1);
     490                  $pivottoshow = core_text::substr($pivottoshow, 0, 1);
     491              }
     492  
     493              // If there's a group break.
     494              if ($currentpivot != $upperpivot) {
     495                  $currentpivot = $upperpivot;
     496  
     497                  // print the group break if apply
     498  
     499                  echo '<div>';
     500                  echo '<table cellspacing="0" class="glossarycategoryheader">';
     501  
     502                  echo '<tr>';
     503                  if ($userispivot) {
     504                  // printing the user icon if defined (only when browsing authors)
     505                      echo '<th align="left">';
     506                      $user = mod_glossary_entry_query_builder::get_user_from_record($entry);
     507                      echo $OUTPUT->user_picture($user, array('courseid'=>$course->id));
     508                      $pivottoshow = fullname($user, has_capability('moodle/site:viewfullnames', context_course::instance($course->id)));
     509                  } else {
     510                      echo '<th >';
     511                  }
     512  
     513                  echo $OUTPUT->heading($pivottoshow, 3);
     514                  echo "</th></tr></table></div>\n";
     515              }
     516          }
     517  
     518          /// highlight the term if necessary
     519          if ($mode == 'search') {
     520              //We have to strip any word starting by + and take out words starting by -
     521              //to make highlight works properly
     522              $searchterms = explode(' ', $hook);    // Search for words independently
     523              foreach ($searchterms as $key => $searchterm) {
     524                  if (preg_match('/^\-/',$searchterm)) {
     525                      unset($searchterms[$key]);
     526                  } else {
     527                      $searchterms[$key] = preg_replace('/^\+/','',$searchterm);
     528                  }
     529                  //Avoid highlight of <2 len strings. It's a well known hilight limitation.
     530                  if (strlen($searchterm) < 2) {
     531                      unset($searchterms[$key]);
     532                  }
     533              }
     534              $strippedsearch = implode(' ', $searchterms);    // Rebuild the string
     535              $entry->highlight = $strippedsearch;
     536          }
     537  
     538          /// and finally print the entry.
     539          glossary_print_entry($course, $cm, $glossary, $entry, $mode, $hook,1,$displayformat);
     540          $entriesshown++;
     541      }
     542      // The all entries value may be a recordset or an array.
     543      if ($allentries instanceof moodle_recordset) {
     544          $allentries->close();
     545      }
     546  }
     547  if ( !$entriesshown ) {
     548      echo $OUTPUT->box(get_string("noentries","glossary"), "generalbox boxaligncenter boxwidthwide");
     549  }
     550  
     551  if (!empty($formsent)) {
     552      // close the form properly if used
     553      echo "</div>";
     554      echo "</form>";
     555  }
     556  
     557  if ( $paging ) {
     558      echo '<hr />';
     559      echo '<div class="paging">';
     560      echo $paging;
     561      echo '</div>';
     562  }
     563  echo '<br />';
     564  glossary_print_tabbed_table_end();
     565  
     566  /// Finish the page
     567  echo $OUTPUT->footer();