[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/feedback/classes/ -> responses_table.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   * Contains class mod_feedback_responses_table
  19   *
  20   * @package   mod_feedback
  21   * @copyright 2016 Marina Glancy
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  global $CFG;
  28  require_once($CFG->libdir . '/tablelib.php');
  29  
  30  /**
  31   * Class mod_feedback_responses_table
  32   *
  33   * @package   mod_feedback
  34   * @copyright 2016 Marina Glancy
  35   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class mod_feedback_responses_table extends table_sql {
  38  
  39      /** @var mod_feedback_structure */
  40      protected $feedbackstructure;
  41  
  42      /** @var int */
  43      protected $grandtotal = null;
  44  
  45      /** @var bool */
  46      protected $showall = false;
  47  
  48      /** @var string */
  49      protected $showallparamname = 'showall';
  50  
  51      /** @var string */
  52      protected $downloadparamname = 'download';
  53  
  54      /**
  55       * Constructor
  56       *
  57       * @param mod_feedback_structure $feedbackstructure
  58       */
  59      public function __construct(mod_feedback_structure $feedbackstructure) {
  60          $this->feedbackstructure = $feedbackstructure;
  61  
  62          parent::__construct('feedback-showentry-list-' . $feedbackstructure->get_cm()->instance);
  63  
  64          $this->showall = optional_param($this->showallparamname, 0, PARAM_BOOL);
  65          $this->define_baseurl(new moodle_url('/mod/feedback/show_entries.php',
  66              ['id' => $this->feedbackstructure->get_cm()->id]));
  67          if ($courseid = $this->feedbackstructure->get_courseid()) {
  68              $this->baseurl->param('courseid', $courseid);
  69          }
  70          if ($this->showall) {
  71              $this->baseurl->param($this->showallparamname, $this->showall);
  72          }
  73  
  74          $name = format_string($feedbackstructure->get_feedback()->name);
  75          $this->is_downloadable(true);
  76          $this->is_downloading(optional_param($this->downloadparamname, 0, PARAM_ALPHA),
  77                  $name, get_string('responses', 'feedback'));
  78          $this->useridfield = 'userid';
  79          $this->init();
  80      }
  81  
  82      /**
  83       * Initialises table
  84       */
  85      protected function init() {
  86  
  87          $tablecolumns = array('userpic', 'fullname');
  88          $tableheaders = array(get_string('userpic'), get_string('fullnameuser'));
  89  
  90          $extrafields = get_extra_user_fields($this->get_context());
  91          $ufields = user_picture::fields('u', $extrafields, $this->useridfield);
  92          $fields = 'c.id, c.timemodified as completed_timemodified, c.courseid, '.$ufields;
  93          $from = '{feedback_completed} c '
  94                  . 'JOIN {user} u ON u.id = c.userid AND u.deleted = :notdeleted';
  95          $where = 'c.anonymous_response = :anon
  96                  AND c.feedback = :instance';
  97          if ($this->feedbackstructure->get_courseid()) {
  98              $where .= ' AND c.courseid = :courseid';
  99          }
 100  
 101          if ($this->is_downloading()) {
 102              // When downloading data:
 103              // Remove 'userpic' from downloaded data.
 104              array_shift($tablecolumns);
 105              array_shift($tableheaders);
 106  
 107              // Add all identity fields as separate columns.
 108              foreach ($extrafields as $field) {
 109                  $fields .= ", u.{$field}";
 110                  $tablecolumns[] = $field;
 111                  $tableheaders[] = get_user_field_name($field);
 112              }
 113          }
 114  
 115          if ($this->feedbackstructure->get_feedback()->course == SITEID && !$this->feedbackstructure->get_courseid()) {
 116              $tablecolumns[] = 'courseid';
 117              $tableheaders[] = get_string('course');
 118          }
 119  
 120          $tablecolumns[] = 'completed_timemodified';
 121          $tableheaders[] = get_string('date');
 122  
 123          $this->define_columns($tablecolumns);
 124          $this->define_headers($tableheaders);
 125  
 126          $this->sortable(true, 'lastname', SORT_ASC);
 127          $this->collapsible(true);
 128          $this->set_attribute('id', 'showentrytable');
 129  
 130          $params = array();
 131          $params['anon'] = FEEDBACK_ANONYMOUS_NO;
 132          $params['instance'] = $this->feedbackstructure->get_feedback()->id;
 133          $params['notdeleted'] = 0;
 134          $params['courseid'] = $this->feedbackstructure->get_courseid();
 135  
 136          $group = groups_get_activity_group($this->feedbackstructure->get_cm(), true);
 137          if ($group) {
 138              $where .= ' AND c.userid IN (SELECT g.userid FROM {groups_members} g WHERE g.groupid = :group)';
 139              $params['group'] = $group;
 140          }
 141  
 142          $this->set_sql($fields, $from, $where, $params);
 143          $this->set_count_sql("SELECT COUNT(c.id) FROM $from WHERE $where", $params);
 144      }
 145  
 146      /**
 147       * Current context
 148       * @return context_module
 149       */
 150      protected function get_context() {
 151          return context_module::instance($this->feedbackstructure->get_cm()->id);
 152      }
 153  
 154      /**
 155       * Allows to set the display column value for all columns without "col_xxxxx" method.
 156       * @param string $column column name
 157       * @param stdClass $row current record result of SQL query
 158       */
 159      public function other_cols($column, $row) {
 160          if (preg_match('/^val(\d+)$/', $column, $matches)) {
 161              $items = $this->feedbackstructure->get_items();
 162              $itemobj = feedback_get_item_class($items[$matches[1]]->typ);
 163              return trim($itemobj->get_printval($items[$matches[1]], (object) ['value' => $row->$column] ));
 164          }
 165          return $row->$column;
 166      }
 167  
 168      /**
 169       * Prepares column userpic for display
 170       * @param stdClass $row
 171       * @return string
 172       */
 173      public function col_userpic($row) {
 174          global $OUTPUT;
 175          $user = user_picture::unalias($row, [], $this->useridfield);
 176          return $OUTPUT->user_picture($user, array('courseid' => $this->feedbackstructure->get_cm()->course));
 177      }
 178  
 179      /**
 180       * Prepares column deleteentry for display
 181       * @param stdClass $row
 182       * @return string
 183       */
 184      public function col_deleteentry($row) {
 185          global $OUTPUT;
 186          $deleteentryurl = new moodle_url($this->baseurl, ['delete' => $row->id, 'sesskey' => sesskey()]);
 187          $deleteaction = new confirm_action(get_string('confirmdeleteentry', 'feedback'));
 188          return $OUTPUT->action_icon($deleteentryurl,
 189              new pix_icon('t/delete', get_string('delete_entry', 'feedback')), $deleteaction);
 190      }
 191  
 192      /**
 193       * Returns a link for viewing a single response
 194       * @param stdClass $row
 195       * @return \moodle_url
 196       */
 197      protected function get_link_single_entry($row) {
 198          return new moodle_url($this->baseurl, ['userid' => $row->{$this->useridfield}, 'showcompleted' => $row->id]);
 199      }
 200  
 201      /**
 202       * Prepares column completed_timemodified for display
 203       * @param stdClass $student
 204       * @return string
 205       */
 206      public function col_completed_timemodified($student) {
 207          if ($this->is_downloading()) {
 208              return userdate($student->completed_timemodified);
 209          } else {
 210              return html_writer::link($this->get_link_single_entry($student),
 211                      userdate($student->completed_timemodified));
 212          }
 213      }
 214  
 215      /**
 216       * Prepares column courseid for display
 217       * @param array $row
 218       * @return string
 219       */
 220      public function col_courseid($row) {
 221          $courses = $this->feedbackstructure->get_completed_courses();
 222          $name = '';
 223          if (isset($courses[$row->courseid])) {
 224              $name = $courses[$row->courseid];
 225              if (!$this->is_downloading()) {
 226                  $name = html_writer::link(course_get_url($row->courseid), $name);
 227              }
 228          }
 229          return $name;
 230      }
 231  
 232      /**
 233       * Adds common values to the table that do not change the number or order of entries and
 234       * are only needed when outputting or downloading data.
 235       */
 236      protected function add_all_values_to_output() {
 237          $tablecolumns = array_keys($this->columns);
 238          $tableheaders = $this->headers;
 239  
 240          // Add all feedback response values.
 241          $items = $this->feedbackstructure->get_items(true);
 242          foreach ($items as $nr => $item) {
 243              $this->sql->fields .= ", v{$nr}.value AS val{$nr}";
 244              $this->sql->from .= " LEFT OUTER JOIN {feedback_value} v{$nr} " .
 245                  "ON v{$nr}.completed = c.id AND v{$nr}.item = :itemid{$nr}";
 246              $this->sql->params["itemid{$nr}"] = $item->id;
 247              $tablecolumns[] = "val{$nr}";
 248              $itemobj = feedback_get_item_class($item->typ);
 249              $tableheaders[] = $itemobj->get_display_name($item);
 250          }
 251  
 252          // Add 'Delete entry' column.
 253          if (!$this->is_downloading() && has_capability('mod/feedback:deletesubmissions', $this->get_context())) {
 254              $tablecolumns[] = 'deleteentry';
 255              $tableheaders[] = '';
 256          }
 257  
 258          $this->define_columns($tablecolumns);
 259          $this->define_headers($tableheaders);
 260      }
 261  
 262      /**
 263       * Query the db. Store results in the table object for use by build_table.
 264       *
 265       * @param int $pagesize size of page for paginated displayed table.
 266       * @param bool $useinitialsbar do you want to use the initials bar. Bar
 267       * will only be used if there is a fullname column defined for the table.
 268       */
 269      public function query_db($pagesize, $useinitialsbar=true) {
 270          global $DB;
 271          $this->totalrows = $grandtotal = $this->get_total_responses_count();
 272          if (!$this->is_downloading()) {
 273              $this->initialbars($useinitialsbar);
 274  
 275              list($wsql, $wparams) = $this->get_sql_where();
 276              if ($wsql) {
 277                  $this->countsql .= ' AND '.$wsql;
 278                  $this->countparams = array_merge($this->countparams, $wparams);
 279  
 280                  $this->sql->where .= ' AND '.$wsql;
 281                  $this->sql->params = array_merge($this->sql->params, $wparams);
 282  
 283                  $this->totalrows  = $DB->count_records_sql($this->countsql, $this->countparams);
 284              }
 285  
 286              if ($this->totalrows > $pagesize) {
 287                  $this->pagesize($pagesize, $this->totalrows);
 288              }
 289          }
 290  
 291          if ($sort = $this->get_sql_sort()) {
 292              $sort = "ORDER BY $sort";
 293          }
 294          $sql = "SELECT
 295                  {$this->sql->fields}
 296                  FROM {$this->sql->from}
 297                  WHERE {$this->sql->where}
 298                  {$sort}";
 299  
 300          if (!$this->is_downloading()) {
 301              $this->rawdata = $DB->get_recordset_sql($sql, $this->sql->params, $this->get_page_start(), $this->get_page_size());
 302          } else {
 303              $this->rawdata = $DB->get_recordset_sql($sql, $this->sql->params);
 304          }
 305      }
 306  
 307      /**
 308       * Returns total number of reponses (without any filters applied)
 309       * @return int
 310       */
 311      public function get_total_responses_count() {
 312          global $DB;
 313          if ($this->grandtotal === null) {
 314              $this->grandtotal = $DB->count_records_sql($this->countsql, $this->countparams);
 315          }
 316          return $this->grandtotal;
 317      }
 318  
 319      /**
 320       * Defines columns
 321       * @param array $columns an array of identifying names for columns. If
 322       * columns are sorted then column names must correspond to a field in sql.
 323       */
 324      public function define_columns($columns) {
 325          parent::define_columns($columns);
 326          foreach ($this->columns as $column => $column) {
 327              // Automatically assign classes to columns.
 328              $this->column_class[$column] = ' ' . $column;
 329          }
 330      }
 331  
 332      /**
 333       * Convenience method to call a number of methods for you to display the
 334       * table.
 335       * @param int $pagesize
 336       * @param bool $useinitialsbar
 337       * @param string $downloadhelpbutton
 338       */
 339      public function out($pagesize, $useinitialsbar, $downloadhelpbutton='') {
 340          $this->add_all_values_to_output();
 341          parent::out($pagesize, $useinitialsbar, $downloadhelpbutton);
 342      }
 343  
 344      /**
 345       * Displays the table
 346       */
 347      public function display() {
 348          global $OUTPUT;
 349          groups_print_activity_menu($this->feedbackstructure->get_cm(), $this->baseurl->out());
 350          $grandtotal = $this->get_total_responses_count();
 351          if (!$grandtotal) {
 352              echo $OUTPUT->box(get_string('nothingtodisplay'), 'generalbox nothingtodisplay');
 353              return;
 354          }
 355          $this->out($this->showall ? $grandtotal : FEEDBACK_DEFAULT_PAGE_COUNT,
 356                  $grandtotal > FEEDBACK_DEFAULT_PAGE_COUNT);
 357  
 358          // Toggle 'Show all' link.
 359          if ($this->totalrows > FEEDBACK_DEFAULT_PAGE_COUNT) {
 360              if (!$this->use_pages) {
 361                  echo html_writer::div(html_writer::link(new moodle_url($this->baseurl, [$this->showallparamname => 0]),
 362                          get_string('showperpage', '', FEEDBACK_DEFAULT_PAGE_COUNT)), 'showall');
 363              } else {
 364                  echo html_writer::div(html_writer::link(new moodle_url($this->baseurl, [$this->showallparamname => 1]),
 365                          get_string('showall', '', $this->totalrows)), 'showall');
 366              }
 367          }
 368      }
 369  
 370      /**
 371       * Returns links to previous/next responses in the list
 372       * @param stdClass $record
 373       * @return array array of three elements [$prevresponseurl, $returnurl, $nextresponseurl]
 374       */
 375      public function get_reponse_navigation_links($record) {
 376          $this->setup();
 377          $grandtotal = $this->get_total_responses_count();
 378          $this->query_db($grandtotal);
 379          $lastrow = $thisrow = $nextrow = null;
 380          $counter = 0;
 381          $page = 0;
 382          while ($this->rawdata->valid()) {
 383              $row = $this->rawdata->current();
 384              if ($row->id == $record->id) {
 385                  $page = $this->showall ? 0 : floor($counter / FEEDBACK_DEFAULT_PAGE_COUNT);
 386                  $thisrow = $row;
 387                  $this->rawdata->next();
 388                  $nextrow = $this->rawdata->valid() ? $this->rawdata->current() : null;
 389                  break;
 390              }
 391              $lastrow = $row;
 392              $this->rawdata->next();
 393              $counter++;
 394          }
 395          $this->rawdata->close();
 396          if (!$thisrow) {
 397              $lastrow = null;
 398          }
 399          return [
 400              $lastrow ? $this->get_link_single_entry($lastrow) : null,
 401              new moodle_url($this->baseurl, [$this->request[TABLE_VAR_PAGE] => $page]),
 402              $nextrow ? $this->get_link_single_entry($nextrow) : null,
 403          ];
 404      }
 405  
 406      /**
 407       * Download the data.
 408       */
 409      public function download() {
 410          \core\session\manager::write_close();
 411          $this->out($this->get_total_responses_count(), false);
 412          exit;
 413      }
 414  
 415      /**
 416       * Returns html code for displaying "Download" button if applicable.
 417       */
 418      public function download_buttons() {
 419          global $OUTPUT;
 420  
 421          if ($this->is_downloadable() && !$this->is_downloading()) {
 422              return $OUTPUT->download_dataformat_selector(get_string('downloadas', 'table'),
 423                      $this->baseurl->out_omit_querystring(), $this->downloadparamname, $this->baseurl->params());
 424          } else {
 425              return '';
 426          }
 427      }
 428  }


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