Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   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   * This filter provides automatic linking to
  20   * activities when its name (title) is found inside every Moodle text
  21   *
  22   * @package    filter
  23   * @subpackage activitynames
  24   * @copyright  2004 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
  25   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  26   */
  27  
  28  defined('MOODLE_INTERNAL') || die();
  29  
  30  /**
  31   * Activity name filtering
  32   */
  33  class filter_activitynames extends moodle_text_filter {
  34  
  35      function filter($text, array $options = array()) {
  36          $coursectx = $this->context->get_course_context(false);
  37          if (!$coursectx) {
  38              return $text;
  39          }
  40          $courseid = $coursectx->instanceid;
  41  
  42          $activitylist = $this->get_cached_activity_list($courseid);
  43  
  44          $filterslist = array();
  45          if (!empty($activitylist)) {
  46              $cmid = $this->context->instanceid;
  47              if ($this->context->contextlevel == CONTEXT_MODULE && isset($activitylist[$cmid])) {
  48                  // remove filterobjects for the current module
  49                  $filterslist = array_values(array_diff_key($activitylist, array($cmid => 1, $cmid.'-e' => 1)));
  50              } else {
  51                  $filterslist = array_values($activitylist);
  52              }
  53          }
  54  
  55          if ($filterslist) {
  56              return $text = filter_phrases($text, $filterslist);
  57          } else {
  58              return $text;
  59          }
  60      }
  61  
  62      /**
  63       * Get all the cached activity list for a course
  64       *
  65       * @param int $courseid id of the course
  66       * @return filterobject[] the activities
  67       */
  68      protected function get_cached_activity_list($courseid) {
  69          global $USER;
  70          $cached = cache::make_from_params(cache_store::MODE_REQUEST, 'filter', 'activitynames');
  71  
  72          // Return cached activity list.
  73          if ($cached->get('cachecourseid') == $courseid && $cached->get('cacheuserid') == $USER->id) {
  74              return $cached->get('activitylist');
  75          }
  76  
  77          // Not cached yet, get activity list and set cache.
  78          $activitylist = $this->get_activity_list($courseid);
  79          $cached->set('cacheuserid', $USER->id);
  80          $cached->set('cachecourseid', $courseid);
  81          $cached->set('activitylist', $activitylist);
  82          return $activitylist;
  83      }
  84  
  85      /**
  86       * Get all the activity list for a course
  87       *
  88       * @param int $courseid id of the course
  89       * @return filterobject[] the activities
  90       */
  91      protected function get_activity_list($courseid) {
  92          $activitylist = array();
  93  
  94          $modinfo = get_fast_modinfo($courseid);
  95          if (!empty($modinfo->cms)) {
  96              $activitylist = array(); // We will store all the created filters here.
  97  
  98              // Create array of visible activities sorted by the name length (we are only interested in properties name and url).
  99              $sortedactivities = array();
 100              foreach ($modinfo->cms as $cm) {
 101                  // Use normal access control and visibility, but exclude labels and hidden activities.
 102                  if ($cm->visible and $cm->has_view() and $cm->uservisible) {
 103                      $sortedactivities[] = (object)array(
 104                          'name' => $cm->name,
 105                          'url' => $cm->url,
 106                          'id' => $cm->id,
 107                          'namelen' => -strlen($cm->name), // Negative value for reverse sorting.
 108                      );
 109                  }
 110              }
 111              // Sort activities by the length of the activity name in reverse order.
 112              core_collator::asort_objects_by_property($sortedactivities, 'namelen', core_collator::SORT_NUMERIC);
 113  
 114              foreach ($sortedactivities as $cm) {
 115                  $title = s(trim(strip_tags($cm->name)));
 116                  $currentname = trim($cm->name);
 117                  $entitisedname  = s($currentname);
 118                  // Avoid empty or unlinkable activity names.
 119                  if (!empty($title)) {
 120                      $hreftagbegin = html_writer::start_tag('a',
 121                          array('class' => 'autolink', 'title' => $title,
 122                              'href' => $cm->url));
 123                      $activitylist[$cm->id] = new filterobject($currentname, $hreftagbegin, '</a>', false, true);
 124                      if ($currentname != $entitisedname) {
 125                          // If name has some entity (&amp; &quot; &lt; &gt;) add that filter too. MDL-17545.
 126                          $activitylist[$cm->id.'-e'] = new filterobject($entitisedname, $hreftagbegin, '</a>', false, true);
 127                      }
 128                  }
 129              }
 130          }
 131          return $activitylist;
 132      }
 133  }