Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Blog tags block.
  19   *
  20   * @package    block_blog_tags
  21   * @copyright  2006 Shane Elliott
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  define('BLOCK_BLOG_TAGS_DEFAULTTIMEWITHIN', 90);
  28  define('BLOCK_BLOG_TAGS_DEFAULTNUMBEROFTAGS', 20);
  29  define('BLOCK_BLOG_TAGS_DEFAULTSORT', 'name');
  30  
  31  class block_blog_tags extends block_base {
  32      function init() {
  33          $this->title = get_string('pluginname', 'block_blog_tags');
  34      }
  35  
  36      function instance_allow_multiple() {
  37          return true;
  38      }
  39  
  40      function has_config() {
  41          return false;
  42      }
  43  
  44      function applicable_formats() {
  45          return array('all' => true, 'my' => false, 'tag' => false);
  46      }
  47  
  48      function instance_allow_config() {
  49          return true;
  50      }
  51  
  52      function specialization() {
  53  
  54          // load userdefined title and make sure it's never empty
  55          if (empty($this->config->title)) {
  56              $this->title = get_string('pluginname', 'block_blog_tags');
  57          } else {
  58              $this->title = $this->config->title;
  59          }
  60      }
  61  
  62      function get_content() {
  63          global $CFG, $SITE, $USER, $DB, $OUTPUT;
  64  
  65          if ($this->content !== NULL) {
  66              return $this->content;
  67          }
  68  
  69          // make sure blog and tags are actually enabled
  70          if (empty($CFG->bloglevel)) {
  71              $this->content = new stdClass();
  72              $this->content->text = '';
  73              if ($this->page->user_is_editing()) {
  74                  $this->content->text = get_string('blogdisable', 'blog');
  75              }
  76              return $this->content;
  77  
  78          } else if (!core_tag_tag::is_enabled('core', 'post')) {
  79              $this->content = new stdClass();
  80              $this->content->text = '';
  81              if ($this->page->user_is_editing()) {
  82                  $this->content->text = get_string('tagsaredisabled', 'tag');
  83              }
  84              return $this->content;
  85  
  86          } else if ($CFG->bloglevel < BLOG_GLOBAL_LEVEL and (!isloggedin() or isguestuser())) {
  87              $this->content = new stdClass();
  88              $this->content->text = '';
  89              return $this->content;
  90          }
  91  
  92          // require the libs and do the work
  93          require_once($CFG->dirroot .'/blog/lib.php');
  94  
  95          if (empty($this->config)) {
  96              $this->config = new stdClass();
  97          }
  98  
  99          if (empty($this->config->timewithin)) {
 100              $this->config->timewithin = BLOCK_BLOG_TAGS_DEFAULTTIMEWITHIN;
 101          }
 102          if (empty($this->config->numberoftags)) {
 103              $this->config->numberoftags = BLOCK_BLOG_TAGS_DEFAULTNUMBEROFTAGS;
 104          }
 105          if (empty($this->config->sort)) {
 106              $this->config->sort = BLOCK_BLOG_TAGS_DEFAULTSORT;
 107          }
 108  
 109          $this->content = new stdClass();
 110          $this->content->text = '';
 111          $this->content->footer = '';
 112  
 113          /// Get a list of tags
 114          $timewithin = time() - $this->config->timewithin * 24 * 60 * 60; /// convert to seconds
 115  
 116          $context = $this->page->context;
 117  
 118          // admins should be able to read all tags
 119          $type = '';
 120          if (!has_capability('moodle/user:readuserblogs', context_system::instance())) {
 121              $type = " AND (p.publishstate = 'site' or p.publishstate='public')";
 122          }
 123  
 124          $sql  = "SELECT t.id, t.isstandard, t.rawname, t.name, COUNT(DISTINCT ti.id) AS ct
 125                     FROM {tag} t, {tag_instance} ti, {post} p, {blog_association} ba
 126                    WHERE t.id = ti.tagid AND p.id = ti.itemid
 127                          $type
 128                          AND ti.itemtype = 'post'
 129                          AND ti.component = 'core'
 130                          AND ti.timemodified > $timewithin";
 131  
 132          if ($context->contextlevel == CONTEXT_MODULE) {
 133              $sql .= " AND ba.contextid = $context->id AND p.id = ba.blogid ";
 134          } else if ($context->contextlevel == CONTEXT_COURSE) {
 135              $sql .= " AND ba.contextid = $context->id AND p.id = ba.blogid ";
 136          }
 137  
 138          $sql .= "
 139                 GROUP BY t.id, t.isstandard, t.name, t.rawname
 140                 ORDER BY ct DESC, t.name ASC";
 141  
 142          if ($tags = $DB->get_records_sql($sql, null, 0, $this->config->numberoftags)) {
 143  
 144          /// There are 2 things to do:
 145          /// 1. tags with the same count should have the same size class
 146          /// 2. however many tags we have should be spread evenly over the
 147          ///    20 size classes
 148  
 149              $totaltags  = count($tags);
 150              $currenttag = 0;
 151  
 152              $size = 20;
 153              $lasttagct = -1;
 154  
 155              $etags = array();
 156              foreach ($tags as $tag) {
 157  
 158                  $currenttag++;
 159  
 160                  if ($currenttag == 1) {
 161                      $lasttagct = $tag->ct;
 162                      $size = 20;
 163                  } else if ($tag->ct != $lasttagct) {
 164                      $lasttagct = $tag->ct;
 165                      $size = 20 - ( (int)((($currenttag - 1) / $totaltags) * 20) );
 166                  }
 167  
 168                  $tag->class = ($tag->isstandard ? "standardtag " : "") . "s$size";
 169                  $etags[] = $tag;
 170  
 171              }
 172  
 173          /// Now we sort the tag display order
 174              $CFG->tagsort = $this->config->sort;
 175              usort($etags, "block_blog_tags_sort");
 176  
 177          /// Finally we create the output
 178          /// Accessibility: markup as a list.
 179              $this->content->text .= "\n<ul class='inline-list'>\n";
 180              foreach ($etags as $tag) {
 181                  $blogurl = new moodle_url('/blog/index.php');
 182  
 183                  switch ($CFG->bloglevel) {
 184                      case BLOG_USER_LEVEL:
 185                          $blogurl->param('userid', $USER->id);
 186                      break;
 187  
 188                      default:
 189                          if ($context->contextlevel == CONTEXT_MODULE) {
 190                              $blogurl->param('modid', $context->instanceid);
 191                          } else if ($context->contextlevel == CONTEXT_COURSE) {
 192                              $blogurl->param('courseid', $context->instanceid);
 193                          }
 194  
 195                      break;
 196                  }
 197  
 198                  $blogurl->param('tagid', $tag->id);
 199                  $link = html_writer::link($blogurl, core_tag_tag::make_display_name($tag),
 200                          array('class' => $tag->class,
 201                              'title' => get_string('numberofentries', 'blog', $tag->ct)));
 202                  $this->content->text .= '<li>' . $link . '</li> ';
 203              }
 204              $this->content->text .= "\n</ul>\n";
 205  
 206          }
 207          return $this->content;
 208      }
 209  
 210      /**
 211       * Return the plugin config settings for external functions.
 212       *
 213       * @return stdClass the configs for both the block instance and plugin
 214       * @since Moodle 3.8
 215       */
 216      public function get_config_for_external() {
 217          // Return all settings for all users since it is safe (no private keys, etc..).
 218          $configs = !empty($this->config) ? $this->config : new stdClass();
 219  
 220          return (object) [
 221              'instance' => $configs,
 222              'plugin' => new stdClass(),
 223          ];
 224      }
 225  }
 226  
 227  function block_blog_tags_sort($a, $b) {
 228      global $CFG;
 229  
 230      if (empty($CFG->tagsort)) {
 231          return 0;
 232      } else {
 233          $tagsort = $CFG->tagsort;
 234      }
 235  
 236      if (is_numeric($a->$tagsort)) {
 237          return (($a->$tagsort == $b->$tagsort) ? 0 : ($a->$tagsort > $b->$tagsort)) ? 1 : -1;
 238      } elseif (is_string($a->$tagsort)) {
 239          return strcmp($a->$tagsort, $b->$tagsort); //TODO: this is not compatible with UTF-8!!
 240      } else {
 241          return 0;
 242      }
 243  }
 244  
 245