[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/question/classes/bank/ -> column_base.php (source)

   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   *
  19   * @package    moodlecore
  20   * @subpackage questionbank
  21   * @copyright  1999 onwards Martin Dougiamas and others {@link http://moodle.com}
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  
  26  namespace core_question\bank;
  27  
  28  /**
  29   * Base class for representing a column in a {@link question_bank_view}.
  30   *
  31   * @copyright  2009 Tim Hunt
  32   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   */
  34  
  35  abstract class column_base {
  36      /**
  37       * @var question_bank_view
  38       */
  39      protected $qbank;
  40  
  41      /** @var bool determine whether the column is td or th. */
  42      protected $isheading = false;
  43  
  44      /**
  45       * Constructor.
  46       * @param $qbank the question_bank_view we are helping to render.
  47       */
  48      public function __construct(view $qbank) {
  49          $this->qbank = $qbank;
  50          $this->init();
  51      }
  52  
  53      /**
  54       * A chance for subclasses to initialise themselves, for example to load lang strings,
  55       * without having to override the constructor.
  56       */
  57      protected function init() {
  58      }
  59  
  60      /**
  61       * Set the column as heading
  62       */
  63      public function set_as_heading() {
  64          $this->isheading = true;
  65      }
  66  
  67      public function is_extra_row() {
  68          return false;
  69      }
  70  
  71      /**
  72       * Output the column header cell.
  73       */
  74      public function display_header() {
  75          echo '<th class="header ' . $this->get_classes() . '" scope="col">';
  76          $sortable = $this->is_sortable();
  77          $name = get_class($this);
  78          $title = $this->get_title();
  79          $tip = $this->get_title_tip();
  80          if (is_array($sortable)) {
  81              if ($title) {
  82                  echo '<div class="title">' . $title . '</div>';
  83              }
  84              $links = array();
  85              foreach ($sortable as $subsort => $details) {
  86                  $links[] = $this->make_sort_link($name . '-' . $subsort,
  87                          $details['title'], '', !empty($details['reverse']));
  88              }
  89              echo '<div class="sorters">' . implode(' / ', $links) . '</div>';
  90          } else if ($sortable) {
  91              echo $this->make_sort_link($name, $title, $tip);
  92          } else {
  93              if ($tip) {
  94                  echo '<span title="' . $tip . '">';
  95              }
  96              echo $title;
  97              if ($tip) {
  98                  echo '</span>';
  99              }
 100          }
 101          echo "</th>\n";
 102      }
 103  
 104      /**
 105       * Title for this column. Not used if is_sortable returns an array.
 106       * @param object $question the row from the $question table, augmented with extra information.
 107       * @param string $rowclasses CSS class names that should be applied to this row of output.
 108       */
 109      protected abstract function get_title();
 110  
 111      /**
 112       * @return string a fuller version of the name. Use this when get_title() returns
 113       * something very short, and you want a longer version as a tool tip.
 114       */
 115      protected function get_title_tip() {
 116          return '';
 117      }
 118  
 119      /**
 120       * Get a link that changes the sort order, and indicates the current sort state.
 121       * @param $name internal name used for this type of sorting.
 122       * @param $currentsort the current sort order -1, 0, 1 for descending, none, ascending.
 123       * @param $title the link text.
 124       * @param $defaultreverse whether the default sort order for this column is descending, rather than ascending.
 125       * @return string HTML fragment.
 126       */
 127      protected function make_sort_link($sort, $title, $tip, $defaultreverse = false) {
 128          $currentsort = $this->qbank->get_primary_sort_order($sort);
 129          $newsortreverse = $defaultreverse;
 130          if ($currentsort) {
 131              $newsortreverse = $currentsort > 0;
 132          }
 133          if (!$tip) {
 134              $tip = $title;
 135          }
 136          if ($newsortreverse) {
 137              $tip = get_string('sortbyxreverse', '', $tip);
 138          } else {
 139              $tip = get_string('sortbyx', '', $tip);
 140          }
 141          $link = '<a href="' . $this->qbank->new_sort_url($sort, $newsortreverse) . '" title="' . $tip . '">';
 142          $link .= $title;
 143          if ($currentsort) {
 144              $link .= $this->get_sort_icon($currentsort < 0);
 145          }
 146          $link .= '</a>';
 147          return $link;
 148      }
 149  
 150      /**
 151       * Get an icon representing the corrent sort state.
 152       * @param $reverse sort is descending, not ascending.
 153       * @return string HTML image tag.
 154       */
 155      protected function get_sort_icon($reverse) {
 156          global $OUTPUT;
 157          if ($reverse) {
 158              return $OUTPUT->pix_icon('t/sort_desc', get_string('desc'), '', array('class' => 'iconsort'));
 159          } else {
 160              return $OUTPUT->pix_icon('t/sort_asc', get_string('asc'), '', array('class' => 'iconsort'));
 161          }
 162      }
 163  
 164      /**
 165       * Output this column.
 166       * @param object $question the row from the $question table, augmented with extra information.
 167       * @param string $rowclasses CSS class names that should be applied to this row of output.
 168       */
 169      public function display($question, $rowclasses) {
 170          $this->display_start($question, $rowclasses);
 171          $this->display_content($question, $rowclasses);
 172          $this->display_end($question, $rowclasses);
 173      }
 174  
 175      /**
 176       * Output the opening column tag.  If it is set as heading, it will use <th> tag instead of <td>
 177       *
 178       * @param stdClass $question
 179       * @param array $rowclasses
 180       */
 181      protected function display_start($question, $rowclasses) {
 182          $tag = 'td';
 183          $attr = array('class' => $this->get_classes());
 184          if ($this->isheading) {
 185              $tag = 'th';
 186              $attr['scope'] = 'row';
 187          }
 188          echo \html_writer::start_tag($tag, $attr);
 189      }
 190  
 191      /**
 192       * @return string the CSS classes to apply to every cell in this column.
 193       */
 194      protected function get_classes() {
 195          $classes = $this->get_extra_classes();
 196          $classes[] = $this->get_name();
 197          return implode(' ', $classes);
 198      }
 199  
 200      /**
 201       * @param object $question the row from the $question table, augmented with extra information.
 202       * @return string internal name for this column. Used as a CSS class name,
 203       *     and to store information about the current sort. Must match PARAM_ALPHA.
 204       */
 205      public abstract function get_name();
 206  
 207      /**
 208       * @return array any extra class names you would like applied to every cell in this column.
 209       */
 210      public function get_extra_classes() {
 211          return array();
 212      }
 213  
 214      /**
 215       * Output the contents of this column.
 216       * @param object $question the row from the $question table, augmented with extra information.
 217       * @param string $rowclasses CSS class names that should be applied to this row of output.
 218       */
 219      protected abstract function display_content($question, $rowclasses);
 220  
 221      /**
 222       * Output the closing column tag
 223       *
 224       * @param object $question
 225       * @param string $rowclasses
 226       */
 227      protected function display_end($question, $rowclasses) {
 228          $tag = 'td';
 229          if ($this->isheading) {
 230              $tag = 'th';
 231          }
 232          echo \html_writer::end_tag($tag);
 233      }
 234  
 235      /**
 236       * Return an array 'table_alias' => 'JOIN clause' to bring in any data that
 237       * this column required.
 238       *
 239       * The return values for all the columns will be checked. It is OK if two
 240       * columns join in the same table with the same alias and identical JOIN clauses.
 241       * If to columns try to use the same alias with different joins, you get an error.
 242       * The only table included by default is the question table, which is aliased to 'q'.
 243       *
 244       * It is importnat that your join simply adds additional data (or NULLs) to the
 245       * existing rows of the query. It must not cause additional rows.
 246       *
 247       * @return array 'table_alias' => 'JOIN clause'
 248       */
 249      public function get_extra_joins() {
 250          return array();
 251      }
 252  
 253      /**
 254       * @return array fields required. use table alias 'q' for the question table, or one of the
 255       * ones from get_extra_joins. Every field requested must specify a table prefix.
 256       */
 257      public function get_required_fields() {
 258          return array();
 259      }
 260  
 261      /**
 262       * Can this column be sorted on? You can return either:
 263       *  + false for no (the default),
 264       *  + a field name, if sorting this column corresponds to sorting on that datbase field.
 265       *  + an array of subnames to sort on as follows
 266       *  return array(
 267       *      'firstname' => array('field' => 'uc.firstname', 'title' => get_string('firstname')),
 268       *      'lastname' => array('field' => 'uc.lastname', 'field' => get_string('lastname')),
 269       *  );
 270       * As well as field, and field, you can also add 'revers' => 1 if you want the default sort
 271       * order to be DESC.
 272       * @return mixed as above.
 273       */
 274      public function is_sortable() {
 275          return false;
 276      }
 277  
 278      /**
 279       * Helper method for building sort clauses.
 280       * @param bool $reverse whether the normal direction should be reversed.
 281       * @param string $normaldir 'ASC' or 'DESC'
 282       * @return string 'ASC' or 'DESC'
 283       */
 284      protected function sortorder($reverse) {
 285          if ($reverse) {
 286              return ' DESC';
 287          } else {
 288              return ' ASC';
 289          }
 290      }
 291  
 292      /**
 293       * @param $reverse Whether to sort in the reverse of the default sort order.
 294       * @param $subsort if is_sortable returns an array of subnames, then this will be
 295       *      one of those. Otherwise will be empty.
 296       * @return string some SQL to go in the order by clause.
 297       */
 298      public function sort_expression($reverse, $subsort) {
 299          $sortable = $this->is_sortable();
 300          if (is_array($sortable)) {
 301              if (array_key_exists($subsort, $sortable)) {
 302                  return $sortable[$subsort]['field'] . $this->sortorder($reverse, !empty($sortable[$subsort]['reverse']));
 303              } else {
 304                  throw new coding_exception('Unexpected $subsort type: ' . $subsort);
 305              }
 306          } else if ($sortable) {
 307              return $sortable . $this->sortorder($reverse);
 308          } else {
 309              throw new coding_exception('sort_expression called on a non-sortable column.');
 310          }
 311      }
 312  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1