[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/workshop/ -> renderer.php (source)

   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   * Workshop module renderering methods are defined here
  20   *
  21   * @package    mod_workshop
  22   * @copyright  2009 David Mudrak <david.mudrak@gmail.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  /**
  29   * Workshop module renderer class
  30   *
  31   * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
  32   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   */
  34  class mod_workshop_renderer extends plugin_renderer_base {
  35  
  36      ////////////////////////////////////////////////////////////////////////////
  37      // External API - methods to render workshop renderable components
  38      ////////////////////////////////////////////////////////////////////////////
  39  
  40      /**
  41       * Renders workshop message
  42       *
  43       * @param workshop_message $message to display
  44       * @return string html code
  45       */
  46      protected function render_workshop_message(workshop_message $message) {
  47  
  48          $text   = $message->get_message();
  49          $url    = $message->get_action_url();
  50          $label  = $message->get_action_label();
  51  
  52          if (empty($text) and empty($label)) {
  53              return '';
  54          }
  55  
  56          switch ($message->get_type()) {
  57          case workshop_message::TYPE_OK:
  58              $sty = 'ok';
  59              break;
  60          case workshop_message::TYPE_ERROR:
  61              $sty = 'error';
  62              break;
  63          default:
  64              $sty = 'info';
  65          }
  66  
  67          $o = html_writer::tag('span', $message->get_message());
  68  
  69          if (!is_null($url) and !is_null($label)) {
  70              $o .= $this->output->single_button($url, $label, 'get');
  71          }
  72  
  73          return $this->output->container($o, array('message', $sty));
  74      }
  75  
  76  
  77      /**
  78       * Renders full workshop submission
  79       *
  80       * @param workshop_submission $submission
  81       * @return string HTML
  82       */
  83      protected function render_workshop_submission(workshop_submission $submission) {
  84          global $CFG;
  85  
  86          $o  = '';    // output HTML code
  87          $anonymous = $submission->is_anonymous();
  88          $classes = 'submission-full';
  89          if ($anonymous) {
  90              $classes .= ' anonymous';
  91          }
  92          $o .= $this->output->container_start($classes);
  93          $o .= $this->output->container_start('header');
  94  
  95          $title = format_string($submission->title);
  96  
  97          if ($this->page->url != $submission->url) {
  98              $title = html_writer::link($submission->url, $title);
  99          }
 100  
 101          $o .= $this->output->heading($title, 3, 'title');
 102  
 103          if (!$anonymous) {
 104              $author = new stdclass();
 105              $additionalfields = explode(',', user_picture::fields());
 106              $author = username_load_fields_from_object($author, $submission, 'author', $additionalfields);
 107              $userpic            = $this->output->user_picture($author, array('courseid' => $this->page->course->id, 'size' => 64));
 108              $userurl            = new moodle_url('/user/view.php',
 109                                              array('id' => $author->id, 'course' => $this->page->course->id));
 110              $a                  = new stdclass();
 111              $a->name            = fullname($author);
 112              $a->url             = $userurl->out();
 113              $byfullname         = get_string('byfullname', 'workshop', $a);
 114              $oo  = $this->output->container($userpic, 'picture');
 115              $oo .= $this->output->container($byfullname, 'fullname');
 116  
 117              $o .= $this->output->container($oo, 'author');
 118          }
 119  
 120          $created = get_string('userdatecreated', 'workshop', userdate($submission->timecreated));
 121          $o .= $this->output->container($created, 'userdate created');
 122  
 123          if ($submission->timemodified > $submission->timecreated) {
 124              $modified = get_string('userdatemodified', 'workshop', userdate($submission->timemodified));
 125              $o .= $this->output->container($modified, 'userdate modified');
 126          }
 127  
 128          $o .= $this->output->container_end(); // end of header
 129  
 130          $content = file_rewrite_pluginfile_urls($submission->content, 'pluginfile.php', $this->page->context->id,
 131                                                          'mod_workshop', 'submission_content', $submission->id);
 132          $content = format_text($content, $submission->contentformat, array('overflowdiv'=>true));
 133          if (!empty($content)) {
 134              if (!empty($CFG->enableplagiarism)) {
 135                  require_once($CFG->libdir.'/plagiarismlib.php');
 136                  $content .= plagiarism_get_links(array('userid' => $submission->authorid,
 137                      'content' => $submission->content,
 138                      'cmid' => $this->page->cm->id,
 139                      'course' => $this->page->course));
 140              }
 141          }
 142          $o .= $this->output->container($content, 'content');
 143  
 144          $o .= $this->helper_submission_attachments($submission->id, 'html');
 145  
 146          $o .= $this->output->container_end(); // end of submission-full
 147  
 148          return $o;
 149      }
 150  
 151      /**
 152       * Renders short summary of the submission
 153       *
 154       * @param workshop_submission_summary $summary
 155       * @return string text to be echo'ed
 156       */
 157      protected function render_workshop_submission_summary(workshop_submission_summary $summary) {
 158  
 159          $o  = '';    // output HTML code
 160          $anonymous = $summary->is_anonymous();
 161          $classes = 'submission-summary';
 162  
 163          if ($anonymous) {
 164              $classes .= ' anonymous';
 165          }
 166  
 167          $gradestatus = '';
 168  
 169          if ($summary->status == 'notgraded') {
 170              $classes    .= ' notgraded';
 171              $gradestatus = $this->output->container(get_string('nogradeyet', 'workshop'), 'grade-status');
 172  
 173          } else if ($summary->status == 'graded') {
 174              $classes    .= ' graded';
 175              $gradestatus = $this->output->container(get_string('alreadygraded', 'workshop'), 'grade-status');
 176          }
 177  
 178          $o .= $this->output->container_start($classes);  // main wrapper
 179          $o .= html_writer::link($summary->url, format_string($summary->title), array('class' => 'title'));
 180  
 181          if (!$anonymous) {
 182              $author             = new stdClass();
 183              $additionalfields = explode(',', user_picture::fields());
 184              $author = username_load_fields_from_object($author, $summary, 'author', $additionalfields);
 185              $userpic            = $this->output->user_picture($author, array('courseid' => $this->page->course->id, 'size' => 35));
 186              $userurl            = new moodle_url('/user/view.php',
 187                                              array('id' => $author->id, 'course' => $this->page->course->id));
 188              $a                  = new stdClass();
 189              $a->name            = fullname($author);
 190              $a->url             = $userurl->out();
 191              $byfullname         = get_string('byfullname', 'workshop', $a);
 192  
 193              $oo  = $this->output->container($userpic, 'picture');
 194              $oo .= $this->output->container($byfullname, 'fullname');
 195              $o  .= $this->output->container($oo, 'author');
 196          }
 197  
 198          $created = get_string('userdatecreated', 'workshop', userdate($summary->timecreated));
 199          $o .= $this->output->container($created, 'userdate created');
 200  
 201          if ($summary->timemodified > $summary->timecreated) {
 202              $modified = get_string('userdatemodified', 'workshop', userdate($summary->timemodified));
 203              $o .= $this->output->container($modified, 'userdate modified');
 204          }
 205  
 206          $o .= $gradestatus;
 207          $o .= $this->output->container_end(); // end of the main wrapper
 208          return $o;
 209      }
 210  
 211      /**
 212       * Renders full workshop example submission
 213       *
 214       * @param workshop_example_submission $example
 215       * @return string HTML
 216       */
 217      protected function render_workshop_example_submission(workshop_example_submission $example) {
 218  
 219          $o  = '';    // output HTML code
 220          $classes = 'submission-full example';
 221          $o .= $this->output->container_start($classes);
 222          $o .= $this->output->container_start('header');
 223          $o .= $this->output->container(format_string($example->title), array('class' => 'title'));
 224          $o .= $this->output->container_end(); // end of header
 225  
 226          $content = file_rewrite_pluginfile_urls($example->content, 'pluginfile.php', $this->page->context->id,
 227                                                          'mod_workshop', 'submission_content', $example->id);
 228          $content = format_text($content, $example->contentformat, array('overflowdiv'=>true));
 229          $o .= $this->output->container($content, 'content');
 230  
 231          $o .= $this->helper_submission_attachments($example->id, 'html');
 232  
 233          $o .= $this->output->container_end(); // end of submission-full
 234  
 235          return $o;
 236      }
 237  
 238      /**
 239       * Renders short summary of the example submission
 240       *
 241       * @param workshop_example_submission_summary $summary
 242       * @return string text to be echo'ed
 243       */
 244      protected function render_workshop_example_submission_summary(workshop_example_submission_summary $summary) {
 245  
 246          $o  = '';    // output HTML code
 247  
 248          // wrapping box
 249          $o .= $this->output->box_start('generalbox example-summary ' . $summary->status);
 250  
 251          // title
 252          $o .= $this->output->container_start('example-title');
 253          $o .= html_writer::link($summary->url, format_string($summary->title), array('class' => 'title'));
 254  
 255          if ($summary->editable) {
 256              $o .= $this->output->action_icon($summary->editurl, new pix_icon('i/edit', get_string('edit')));
 257          }
 258          $o .= $this->output->container_end();
 259  
 260          // additional info
 261          if ($summary->status == 'notgraded') {
 262              $o .= $this->output->container(get_string('nogradeyet', 'workshop'), 'example-info nograde');
 263          } else {
 264              $o .= $this->output->container(get_string('gradeinfo', 'workshop' , $summary->gradeinfo), 'example-info grade');
 265          }
 266  
 267          // button to assess
 268          $button = new single_button($summary->assessurl, $summary->assesslabel, 'get');
 269          $o .= $this->output->container($this->output->render($button), 'example-actions');
 270  
 271          // end of wrapping box
 272          $o .= $this->output->box_end();
 273  
 274          return $o;
 275      }
 276  
 277      /**
 278       * Renders the user plannner tool
 279       *
 280       * @param workshop_user_plan $plan prepared for the user
 281       * @return string html code to be displayed
 282       */
 283      protected function render_workshop_user_plan(workshop_user_plan $plan) {
 284          $table = new html_table();
 285          $table->attributes['class'] = 'userplan';
 286          $table->attributes['role'] = 'section';
 287          $numberofphases = count($plan->phases);
 288          $table->attributes['aria-label'] = get_string('userplanaccessibilitytitle', 'workshop', $numberofphases);
 289          $table->head = array();
 290          $table->colclasses = array();
 291          $row = new html_table_row();
 292          $row->attributes['class'] = 'phasetasks';
 293          foreach ($plan->phases as $phasecode => $phase) {
 294              $title = html_writer::tag('span', $phase->title);
 295              if ($phase->active) {
 296                  $title .= ' ' . html_writer::tag('span', get_string('userplancurrentphase', 'workshop'),
 297                      array('class' => 'accesshide'));
 298              }
 299              $actions = '';
 300              foreach ($phase->actions as $action) {
 301                  switch ($action->type) {
 302                  case 'switchphase':
 303                      $icon = 'i/marker';
 304                      if ($phasecode == workshop::PHASE_ASSESSMENT
 305                              and $plan->workshop->phase == workshop::PHASE_SUBMISSION
 306                              and $plan->workshop->phaseswitchassessment) {
 307                          $icon = 'i/scheduled';
 308                      }
 309                      $actions .= $this->output->action_icon($action->url, new pix_icon($icon, get_string('switchphase', 'workshop')));
 310                      break;
 311                  }
 312              }
 313              if (!empty($actions)) {
 314                  $actions = $this->output->container($actions, 'actions');
 315              }
 316              $table->head[] = $this->output->container($title . $actions);
 317              $classes = 'phase' . $phasecode;
 318              if ($phase->active) {
 319                  $classes .= ' active';
 320              } else {
 321                  $classes .= ' nonactive';
 322              }
 323              $table->colclasses[] = $classes;
 324              $cell = new html_table_cell();
 325              $cell->text = $this->helper_user_plan_tasks($phase->tasks);
 326              $row->cells[] = $cell;
 327          }
 328          $table->data = array($row);
 329  
 330          return html_writer::table($table);
 331      }
 332  
 333      /**
 334       * Renders the result of the submissions allocation process
 335       *
 336       * @param workshop_allocation_result $result as returned by the allocator's init() method
 337       * @return string HTML to be echoed
 338       */
 339      protected function render_workshop_allocation_result(workshop_allocation_result $result) {
 340          global $CFG;
 341  
 342          $status = $result->get_status();
 343  
 344          if (is_null($status) or $status == workshop_allocation_result::STATUS_VOID) {
 345              debugging('Attempt to render workshop_allocation_result with empty status', DEBUG_DEVELOPER);
 346              return '';
 347          }
 348  
 349          switch ($status) {
 350          case workshop_allocation_result::STATUS_FAILED:
 351              if ($message = $result->get_message()) {
 352                  $message = new workshop_message($message, workshop_message::TYPE_ERROR);
 353              } else {
 354                  $message = new workshop_message(get_string('allocationerror', 'workshop'), workshop_message::TYPE_ERROR);
 355              }
 356              break;
 357  
 358          case workshop_allocation_result::STATUS_CONFIGURED:
 359              if ($message = $result->get_message()) {
 360                  $message = new workshop_message($message, workshop_message::TYPE_INFO);
 361              } else {
 362                  $message = new workshop_message(get_string('allocationconfigured', 'workshop'), workshop_message::TYPE_INFO);
 363              }
 364              break;
 365  
 366          case workshop_allocation_result::STATUS_EXECUTED:
 367              if ($message = $result->get_message()) {
 368                  $message = new workshop_message($message, workshop_message::TYPE_OK);
 369              } else {
 370                  $message = new workshop_message(get_string('allocationdone', 'workshop'), workshop_message::TYPE_OK);
 371              }
 372              break;
 373  
 374          default:
 375              throw new coding_exception('Unknown allocation result status', $status);
 376          }
 377  
 378          // start with the message
 379          $o = $this->render($message);
 380  
 381          // display the details about the process if available
 382          $logs = $result->get_logs();
 383          if (is_array($logs) and !empty($logs)) {
 384              $o .= html_writer::start_tag('ul', array('class' => 'allocation-init-results'));
 385              foreach ($logs as $log) {
 386                  if ($log->type == 'debug' and !$CFG->debugdeveloper) {
 387                      // display allocation debugging messages for developers only
 388                      continue;
 389                  }
 390                  $class = $log->type;
 391                  if ($log->indent) {
 392                      $class .= ' indent';
 393                  }
 394                  $o .= html_writer::tag('li', $log->message, array('class' => $class)).PHP_EOL;
 395              }
 396              $o .= html_writer::end_tag('ul');
 397          }
 398  
 399          return $o;
 400      }
 401  
 402      /**
 403       * Renders the workshop grading report
 404       *
 405       * @param workshop_grading_report $gradingreport
 406       * @return string html code
 407       */
 408      protected function render_workshop_grading_report(workshop_grading_report $gradingreport) {
 409  
 410          $data       = $gradingreport->get_data();
 411          $options    = $gradingreport->get_options();
 412          $grades     = $data->grades;
 413          $userinfo   = $data->userinfo;
 414  
 415          if (empty($grades)) {
 416              return '';
 417          }
 418  
 419          $table = new html_table();
 420          $table->attributes['class'] = 'grading-report';
 421  
 422          $sortbyfirstname = $this->helper_sortable_heading(get_string('firstname'), 'firstname', $options->sortby, $options->sorthow);
 423          $sortbylastname = $this->helper_sortable_heading(get_string('lastname'), 'lastname', $options->sortby, $options->sorthow);
 424          if (self::fullname_format() == 'lf') {
 425              $sortbyname = $sortbylastname . ' / ' . $sortbyfirstname;
 426          } else {
 427              $sortbyname = $sortbyfirstname . ' / ' . $sortbylastname;
 428          }
 429  
 430          $sortbysubmisstiontitle = $this->helper_sortable_heading(get_string('submission', 'workshop'), 'submissiontitle',
 431                  $options->sortby, $options->sorthow);
 432          $sortbysubmisstionlastmodified = $this->helper_sortable_heading(get_string('submissionlastmodified', 'workshop'),
 433                  'submissionmodified', $options->sortby, $options->sorthow);
 434          $sortbysubmisstion = $sortbysubmisstiontitle . ' / ' . $sortbysubmisstionlastmodified;
 435  
 436          $table->head = array();
 437          $table->head[] = $sortbyname;
 438          $table->head[] = $sortbysubmisstion;
 439  
 440          // If we are in submission phase ignore the following headers (columns).
 441          if ($options->workshopphase != workshop::PHASE_SUBMISSION) {
 442              $table->head[] = $this->helper_sortable_heading(get_string('receivedgrades', 'workshop'));
 443              if ($options->showsubmissiongrade) {
 444                  $table->head[] = $this->helper_sortable_heading(get_string('submissiongradeof', 'workshop', $data->maxgrade),
 445                          'submissiongrade', $options->sortby, $options->sorthow);
 446              }
 447              $table->head[] = $this->helper_sortable_heading(get_string('givengrades', 'workshop'));
 448              if ($options->showgradinggrade) {
 449                  $table->head[] = $this->helper_sortable_heading(get_string('gradinggradeof', 'workshop', $data->maxgradinggrade),
 450                          'gradinggrade', $options->sortby, $options->sorthow);
 451              }
 452          }
 453          $table->rowclasses  = array();
 454          $table->colclasses  = array();
 455          $table->data        = array();
 456  
 457          foreach ($grades as $participant) {
 458              $numofreceived  = count($participant->reviewedby);
 459              $numofgiven     = count($participant->reviewerof);
 460              $published      = $participant->submissionpublished;
 461  
 462              // compute the number of <tr> table rows needed to display this participant
 463              if ($numofreceived > 0 and $numofgiven > 0) {
 464                  $numoftrs       = workshop::lcm($numofreceived, $numofgiven);
 465                  $spanreceived   = $numoftrs / $numofreceived;
 466                  $spangiven      = $numoftrs / $numofgiven;
 467              } elseif ($numofreceived == 0 and $numofgiven > 0) {
 468                  $numoftrs       = $numofgiven;
 469                  $spanreceived   = $numoftrs;
 470                  $spangiven      = $numoftrs / $numofgiven;
 471              } elseif ($numofreceived > 0 and $numofgiven == 0) {
 472                  $numoftrs       = $numofreceived;
 473                  $spanreceived   = $numoftrs / $numofreceived;
 474                  $spangiven      = $numoftrs;
 475              } else {
 476                  $numoftrs       = 1;
 477                  $spanreceived   = 1;
 478                  $spangiven      = 1;
 479              }
 480  
 481              for ($tr = 0; $tr < $numoftrs; $tr++) {
 482                  $row = new html_table_row();
 483                  if ($published) {
 484                      $row->attributes['class'] = 'published';
 485                  }
 486                  // column #1 - participant - spans over all rows
 487                  if ($tr == 0) {
 488                      $cell = new html_table_cell();
 489                      $cell->text = $this->helper_grading_report_participant($participant, $userinfo);
 490                      $cell->rowspan = $numoftrs;
 491                      $cell->attributes['class'] = 'participant';
 492                      $row->cells[] = $cell;
 493                  }
 494                  // column #2 - submission - spans over all rows
 495                  if ($tr == 0) {
 496                      $cell = new html_table_cell();
 497                      $cell->text = $this->helper_grading_report_submission($participant);
 498                      $cell->rowspan = $numoftrs;
 499                      $cell->attributes['class'] = 'submission';
 500                      $row->cells[] = $cell;
 501                  }
 502  
 503                  // If we are in submission phase ignore the following columns.
 504                  if ($options->workshopphase == workshop::PHASE_SUBMISSION) {
 505                      $table->data[] = $row;
 506                      continue;
 507                  }
 508  
 509                  // column #3 - received grades
 510                  if ($tr % $spanreceived == 0) {
 511                      $idx = intval($tr / $spanreceived);
 512                      $assessment = self::array_nth($participant->reviewedby, $idx);
 513                      $cell = new html_table_cell();
 514                      $cell->text = $this->helper_grading_report_assessment($assessment, $options->showreviewernames, $userinfo,
 515                              get_string('gradereceivedfrom', 'workshop'));
 516                      $cell->rowspan = $spanreceived;
 517                      $cell->attributes['class'] = 'receivedgrade';
 518                      if (is_null($assessment) or is_null($assessment->grade)) {
 519                          $cell->attributes['class'] .= ' null';
 520                      } else {
 521                          $cell->attributes['class'] .= ' notnull';
 522                      }
 523                      $row->cells[] = $cell;
 524                  }
 525                  // column #4 - total grade for submission
 526                  if ($options->showsubmissiongrade and $tr == 0) {
 527                      $cell = new html_table_cell();
 528                      $cell->text = $this->helper_grading_report_grade($participant->submissiongrade, $participant->submissiongradeover);
 529                      $cell->rowspan = $numoftrs;
 530                      $cell->attributes['class'] = 'submissiongrade';
 531                      $row->cells[] = $cell;
 532                  }
 533                  // column #5 - given grades
 534                  if ($tr % $spangiven == 0) {
 535                      $idx = intval($tr / $spangiven);
 536                      $assessment = self::array_nth($participant->reviewerof, $idx);
 537                      $cell = new html_table_cell();
 538                      $cell->text = $this->helper_grading_report_assessment($assessment, $options->showauthornames, $userinfo,
 539                              get_string('gradegivento', 'workshop'));
 540                      $cell->rowspan = $spangiven;
 541                      $cell->attributes['class'] = 'givengrade';
 542                      if (is_null($assessment) or is_null($assessment->grade)) {
 543                          $cell->attributes['class'] .= ' null';
 544                      } else {
 545                          $cell->attributes['class'] .= ' notnull';
 546                      }
 547                      $row->cells[] = $cell;
 548                  }
 549                  // column #6 - total grade for assessment
 550                  if ($options->showgradinggrade and $tr == 0) {
 551                      $cell = new html_table_cell();
 552                      $cell->text = $this->helper_grading_report_grade($participant->gradinggrade);
 553                      $cell->rowspan = $numoftrs;
 554                      $cell->attributes['class'] = 'gradinggrade';
 555                      $row->cells[] = $cell;
 556                  }
 557  
 558                  $table->data[] = $row;
 559              }
 560          }
 561  
 562          return html_writer::table($table);
 563      }
 564  
 565      /**
 566       * Renders the feedback for the author of the submission
 567       *
 568       * @param workshop_feedback_author $feedback
 569       * @return string HTML
 570       */
 571      protected function render_workshop_feedback_author(workshop_feedback_author $feedback) {
 572          return $this->helper_render_feedback($feedback);
 573      }
 574  
 575      /**
 576       * Renders the feedback for the reviewer of the submission
 577       *
 578       * @param workshop_feedback_reviewer $feedback
 579       * @return string HTML
 580       */
 581      protected function render_workshop_feedback_reviewer(workshop_feedback_reviewer $feedback) {
 582          return $this->helper_render_feedback($feedback);
 583      }
 584  
 585      /**
 586       * Helper method to rendering feedback
 587       *
 588       * @param workshop_feedback_author|workshop_feedback_reviewer $feedback
 589       * @return string HTML
 590       */
 591      private function helper_render_feedback($feedback) {
 592  
 593          $o  = '';    // output HTML code
 594          $o .= $this->output->container_start('feedback feedbackforauthor');
 595          $o .= $this->output->container_start('header');
 596          $o .= $this->output->heading(get_string('feedbackby', 'workshop', s(fullname($feedback->get_provider()))), 3, 'title');
 597  
 598          $userpic = $this->output->user_picture($feedback->get_provider(), array('courseid' => $this->page->course->id, 'size' => 32));
 599          $o .= $this->output->container($userpic, 'picture');
 600          $o .= $this->output->container_end(); // end of header
 601  
 602          $content = format_text($feedback->get_content(), $feedback->get_format(), array('overflowdiv' => true));
 603          $o .= $this->output->container($content, 'content');
 604  
 605          $o .= $this->output->container_end();
 606  
 607          return $o;
 608      }
 609  
 610      /**
 611       * Renders the full assessment
 612       *
 613       * @param workshop_assessment $assessment
 614       * @return string HTML
 615       */
 616      protected function render_workshop_assessment(workshop_assessment $assessment) {
 617  
 618          $o = ''; // output HTML code
 619          $anonymous = is_null($assessment->reviewer);
 620          $classes = 'assessment-full';
 621          if ($anonymous) {
 622              $classes .= ' anonymous';
 623          }
 624  
 625          $o .= $this->output->container_start($classes);
 626          $o .= $this->output->container_start('header');
 627  
 628          if (!empty($assessment->title)) {
 629              $title = s($assessment->title);
 630          } else {
 631              $title = get_string('assessment', 'workshop');
 632          }
 633          if (($assessment->url instanceof moodle_url) and ($this->page->url != $assessment->url)) {
 634              $o .= $this->output->container(html_writer::link($assessment->url, $title), 'title');
 635          } else {
 636              $o .= $this->output->container($title, 'title');
 637          }
 638  
 639          if (!$anonymous) {
 640              $reviewer   = $assessment->reviewer;
 641              $userpic    = $this->output->user_picture($reviewer, array('courseid' => $this->page->course->id, 'size' => 32));
 642  
 643              $userurl    = new moodle_url('/user/view.php',
 644                                         array('id' => $reviewer->id, 'course' => $this->page->course->id));
 645              $a          = new stdClass();
 646              $a->name    = fullname($reviewer);
 647              $a->url     = $userurl->out();
 648              $byfullname = get_string('assessmentby', 'workshop', $a);
 649              $oo         = $this->output->container($userpic, 'picture');
 650              $oo        .= $this->output->container($byfullname, 'fullname');
 651  
 652              $o .= $this->output->container($oo, 'reviewer');
 653          }
 654  
 655          if (is_null($assessment->realgrade)) {
 656              $o .= $this->output->container(
 657                  get_string('notassessed', 'workshop'),
 658                  'grade nograde'
 659              );
 660          } else {
 661              $a              = new stdClass();
 662              $a->max         = $assessment->maxgrade;
 663              $a->received    = $assessment->realgrade;
 664              $o .= $this->output->container(
 665                  get_string('gradeinfo', 'workshop', $a),
 666                  'grade'
 667              );
 668  
 669              if (!is_null($assessment->weight) and $assessment->weight != 1) {
 670                  $o .= $this->output->container(
 671                      get_string('weightinfo', 'workshop', $assessment->weight),
 672                      'weight'
 673                  );
 674              }
 675          }
 676  
 677          $o .= $this->output->container_start('actions');
 678          foreach ($assessment->actions as $action) {
 679              $o .= $this->output->single_button($action->url, $action->label, $action->method);
 680          }
 681          $o .= $this->output->container_end(); // actions
 682  
 683          $o .= $this->output->container_end(); // header
 684  
 685          if (!is_null($assessment->form)) {
 686              $o .= print_collapsible_region_start('assessment-form-wrapper', uniqid('workshop-assessment'),
 687                      get_string('assessmentform', 'workshop'), '', false, true);
 688              $o .= $this->output->container(self::moodleform($assessment->form), 'assessment-form');
 689              $o .= print_collapsible_region_end(true);
 690  
 691              if (!$assessment->form->is_editable()) {
 692                  $o .= $this->overall_feedback($assessment);
 693              }
 694          }
 695  
 696          $o .= $this->output->container_end(); // main wrapper
 697  
 698          return $o;
 699      }
 700  
 701      /**
 702       * Renders the assessment of an example submission
 703       *
 704       * @param workshop_example_assessment $assessment
 705       * @return string HTML
 706       */
 707      protected function render_workshop_example_assessment(workshop_example_assessment $assessment) {
 708          return $this->render_workshop_assessment($assessment);
 709      }
 710  
 711      /**
 712       * Renders the reference assessment of an example submission
 713       *
 714       * @param workshop_example_reference_assessment $assessment
 715       * @return string HTML
 716       */
 717      protected function render_workshop_example_reference_assessment(workshop_example_reference_assessment $assessment) {
 718          return $this->render_workshop_assessment($assessment);
 719      }
 720  
 721      /**
 722       * Renders the overall feedback for the author of the submission
 723       *
 724       * @param workshop_assessment $assessment
 725       * @return string HTML
 726       */
 727      protected function overall_feedback(workshop_assessment $assessment) {
 728  
 729          $content = $assessment->get_overall_feedback_content();
 730  
 731          if ($content === false) {
 732              return '';
 733          }
 734  
 735          $o = '';
 736  
 737          if (!is_null($content)) {
 738              $o .= $this->output->container($content, 'content');
 739          }
 740  
 741          $attachments = $assessment->get_overall_feedback_attachments();
 742  
 743          if (!empty($attachments)) {
 744              $o .= $this->output->container_start('attachments');
 745              $images = '';
 746              $files = '';
 747              foreach ($attachments as $attachment) {
 748                  $icon = $this->output->pix_icon(file_file_icon($attachment), get_mimetype_description($attachment),
 749                      'moodle', array('class' => 'icon'));
 750                  $link = html_writer::link($attachment->fileurl, $icon.' '.substr($attachment->filepath.$attachment->filename, 1));
 751                  if (file_mimetype_in_typegroup($attachment->mimetype, 'web_image')) {
 752                      $preview = html_writer::empty_tag('img', array('src' => $attachment->previewurl, 'alt' => '', 'class' => 'preview'));
 753                      $preview = html_writer::tag('a', $preview, array('href' => $attachment->fileurl));
 754                      $images .= $this->output->container($preview);
 755                  } else {
 756                      $files .= html_writer::tag('li', $link, array('class' => $attachment->mimetype));
 757                  }
 758              }
 759              if ($images) {
 760                  $images = $this->output->container($images, 'images');
 761              }
 762  
 763              if ($files) {
 764                  $files = html_writer::tag('ul', $files, array('class' => 'files'));
 765              }
 766  
 767              $o .= $images.$files;
 768              $o .= $this->output->container_end();
 769          }
 770  
 771          if ($o === '') {
 772              return '';
 773          }
 774  
 775          $o = $this->output->box($o, 'overallfeedback');
 776          $o = print_collapsible_region($o, 'overall-feedback-wrapper', uniqid('workshop-overall-feedback'),
 777              get_string('overallfeedback', 'workshop'), '', false, true);
 778  
 779          return $o;
 780      }
 781  
 782      /**
 783       * Renders a perpage selector for workshop listings
 784       *
 785       * The scripts using this have to define the $PAGE->url prior to calling this
 786       * and deal with eventually submitted value themselves.
 787       *
 788       * @param int $current current value of the perpage parameter
 789       * @return string HTML
 790       */
 791      public function perpage_selector($current=10) {
 792  
 793          $options = array();
 794          foreach (array(10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 1000) as $option) {
 795              if ($option != $current) {
 796                  $options[$option] = $option;
 797              }
 798          }
 799          $select = new single_select($this->page->url, 'perpage', $options, '', array('' => get_string('showingperpagechange', 'mod_workshop')));
 800          $select->label = get_string('showingperpage', 'mod_workshop', $current);
 801          $select->method = 'post';
 802  
 803          return $this->output->container($this->output->render($select), 'perpagewidget');
 804      }
 805  
 806      /**
 807       * Renders the user's final grades
 808       *
 809       * @param workshop_final_grades $grades with the info about grades in the gradebook
 810       * @return string HTML
 811       */
 812      protected function render_workshop_final_grades(workshop_final_grades $grades) {
 813  
 814          $out = html_writer::start_tag('div', array('class' => 'finalgrades'));
 815  
 816          if (!empty($grades->submissiongrade)) {
 817              $cssclass = 'grade submissiongrade';
 818              if ($grades->submissiongrade->hidden) {
 819                  $cssclass .= ' hiddengrade';
 820              }
 821              $out .= html_writer::tag(
 822                  'div',
 823                  html_writer::tag('div', get_string('submissiongrade', 'mod_workshop'), array('class' => 'gradetype')) .
 824                  html_writer::tag('div', $grades->submissiongrade->str_long_grade, array('class' => 'gradevalue')),
 825                  array('class' => $cssclass)
 826              );
 827          }
 828  
 829          if (!empty($grades->assessmentgrade)) {
 830              $cssclass = 'grade assessmentgrade';
 831              if ($grades->assessmentgrade->hidden) {
 832                  $cssclass .= ' hiddengrade';
 833              }
 834              $out .= html_writer::tag(
 835                  'div',
 836                  html_writer::tag('div', get_string('gradinggrade', 'mod_workshop'), array('class' => 'gradetype')) .
 837                  html_writer::tag('div', $grades->assessmentgrade->str_long_grade, array('class' => 'gradevalue')),
 838                  array('class' => $cssclass)
 839              );
 840          }
 841  
 842          $out .= html_writer::end_tag('div');
 843  
 844          return $out;
 845      }
 846  
 847      ////////////////////////////////////////////////////////////////////////////
 848      // Internal rendering helper methods
 849      ////////////////////////////////////////////////////////////////////////////
 850  
 851      /**
 852       * Renders a list of files attached to the submission
 853       *
 854       * If format==html, then format a html string. If format==text, then format a text-only string.
 855       * Otherwise, returns html for non-images and html to display the image inline.
 856       *
 857       * @param int $submissionid submission identifier
 858       * @param string format the format of the returned string - html|text
 859       * @return string formatted text to be echoed
 860       */
 861      protected function helper_submission_attachments($submissionid, $format = 'html') {
 862          global $CFG;
 863          require_once($CFG->libdir.'/filelib.php');
 864  
 865          $fs     = get_file_storage();
 866          $ctx    = $this->page->context;
 867          $files  = $fs->get_area_files($ctx->id, 'mod_workshop', 'submission_attachment', $submissionid);
 868  
 869          $outputimgs     = '';   // images to be displayed inline
 870          $outputfiles    = '';   // list of attachment files
 871  
 872          foreach ($files as $file) {
 873              if ($file->is_directory()) {
 874                  continue;
 875              }
 876  
 877              $filepath   = $file->get_filepath();
 878              $filename   = $file->get_filename();
 879              $fileurl    = moodle_url::make_pluginfile_url($ctx->id, 'mod_workshop', 'submission_attachment',
 880                              $submissionid, $filepath, $filename, true);
 881              $embedurl   = moodle_url::make_pluginfile_url($ctx->id, 'mod_workshop', 'submission_attachment',
 882                              $submissionid, $filepath, $filename, false);
 883              $embedurl   = new moodle_url($embedurl, array('preview' => 'bigthumb'));
 884              $type       = $file->get_mimetype();
 885              $image      = $this->output->pix_icon(file_file_icon($file), get_mimetype_description($file), 'moodle', array('class' => 'icon'));
 886  
 887              $linkhtml   = html_writer::link($fileurl, $image . substr($filepath, 1) . $filename);
 888              $linktxt    = "$filename [$fileurl]";
 889  
 890              if ($format == 'html') {
 891                  if (file_mimetype_in_typegroup($type, 'web_image')) {
 892                      $preview     = html_writer::empty_tag('img', array('src' => $embedurl, 'alt' => '', 'class' => 'preview'));
 893                      $preview     = html_writer::tag('a', $preview, array('href' => $fileurl));
 894                      $outputimgs .= $this->output->container($preview);
 895  
 896                  } else {
 897                      $outputfiles .= html_writer::tag('li', $linkhtml, array('class' => $type));
 898                  }
 899  
 900              } else if ($format == 'text') {
 901                  $outputfiles .= $linktxt . PHP_EOL;
 902              }
 903  
 904              if (!empty($CFG->enableplagiarism)) {
 905                  require_once($CFG->libdir.'/plagiarismlib.php');
 906                  $outputfiles .= plagiarism_get_links(array('userid' => $file->get_userid(),
 907                      'file' => $file,
 908                      'cmid' => $this->page->cm->id,
 909                      'course' => $this->page->course->id));
 910              }
 911          }
 912  
 913          if ($format == 'html') {
 914              if ($outputimgs) {
 915                  $outputimgs = $this->output->container($outputimgs, 'images');
 916              }
 917  
 918              if ($outputfiles) {
 919                  $outputfiles = html_writer::tag('ul', $outputfiles, array('class' => 'files'));
 920              }
 921  
 922              return $this->output->container($outputimgs . $outputfiles, 'attachments');
 923  
 924          } else {
 925              return $outputfiles;
 926          }
 927      }
 928  
 929      /**
 930       * Renders the tasks for the single phase in the user plan
 931       *
 932       * @param stdClass $tasks
 933       * @return string html code
 934       */
 935      protected function helper_user_plan_tasks(array $tasks) {
 936          $out = '';
 937          foreach ($tasks as $taskcode => $task) {
 938              $classes = '';
 939              $icon = null;
 940              if ($task->completed === true) {
 941                  $classes .= ' completed';
 942              } elseif ($task->completed === false) {
 943                  $classes .= ' fail';
 944              } elseif ($task->completed === 'info') {
 945                  $classes .= ' info';
 946              }
 947              if (is_null($task->link)) {
 948                  $title = $task->title;
 949              } else {
 950                  $title = html_writer::link($task->link, $task->title);
 951              }
 952              $title = $this->output->container($title, 'title');
 953              $details = $this->output->container($task->details, 'details');
 954              $out .= html_writer::tag('li', $title . $details, array('class' => $classes));
 955          }
 956          if ($out) {
 957              $out = html_writer::tag('ul', $out, array('class' => 'tasks'));
 958          }
 959          return $out;
 960      }
 961  
 962      /**
 963       * Renders a text with icons to sort by the given column
 964       *
 965       * This is intended for table headings.
 966       *
 967       * @param string $text    The heading text
 968       * @param string $sortid  The column id used for sorting
 969       * @param string $sortby  Currently sorted by (column id)
 970       * @param string $sorthow Currently sorted how (ASC|DESC)
 971       *
 972       * @return string
 973       */
 974      protected function helper_sortable_heading($text, $sortid=null, $sortby=null, $sorthow=null) {
 975          global $PAGE;
 976  
 977          $out = html_writer::tag('span', $text, array('class'=>'text'));
 978  
 979          if (!is_null($sortid)) {
 980              if ($sortby !== $sortid or $sorthow !== 'ASC') {
 981                  $url = new moodle_url($PAGE->url);
 982                  $url->params(array('sortby' => $sortid, 'sorthow' => 'ASC'));
 983                  $out .= $this->output->action_icon($url, new pix_icon('t/sort_asc', get_string('sortasc', 'workshop')),
 984                      null, array('class' => 'iconsort sort asc'));
 985              }
 986              if ($sortby !== $sortid or $sorthow !== 'DESC') {
 987                  $url = new moodle_url($PAGE->url);
 988                  $url->params(array('sortby' => $sortid, 'sorthow' => 'DESC'));
 989                  $out .= $this->output->action_icon($url, new pix_icon('t/sort_desc', get_string('sortdesc', 'workshop')),
 990                      null, array('class' => 'iconsort sort desc'));
 991              }
 992          }
 993          return $out;
 994  }
 995  
 996      /**
 997       * @param stdClass $participant
 998       * @param array $userinfo
 999       * @return string
1000       */
1001      protected function helper_grading_report_participant(stdclass $participant, array $userinfo) {
1002          $userid = $participant->userid;
1003          $out  = $this->output->user_picture($userinfo[$userid], array('courseid' => $this->page->course->id, 'size' => 35));
1004          $out .= html_writer::tag('span', fullname($userinfo[$userid]));
1005  
1006          return $out;
1007      }
1008  
1009      /**
1010       * @param stdClass $participant
1011       * @return string
1012       */
1013      protected function helper_grading_report_submission(stdclass $participant) {
1014          global $CFG;
1015  
1016          if (is_null($participant->submissionid)) {
1017              $out = $this->output->container(get_string('nosubmissionfound', 'workshop'), 'info');
1018          } else {
1019              $url = new moodle_url('/mod/workshop/submission.php',
1020                                    array('cmid' => $this->page->context->instanceid, 'id' => $participant->submissionid));
1021              $out = html_writer::link($url, format_string($participant->submissiontitle), array('class'=>'title'));
1022  
1023              $lastmodified = get_string('userdatemodified', 'workshop', userdate($participant->submissionmodified));
1024              $out .= html_writer::tag('div', $lastmodified, array('class' => 'lastmodified'));
1025          }
1026  
1027          return $out;
1028      }
1029  
1030      /**
1031       * @todo Highlight the nulls
1032       * @param stdClass|null $assessment
1033       * @param bool $shownames
1034       * @param string $separator between the grade and the reviewer/author
1035       * @return string
1036       */
1037      protected function helper_grading_report_assessment($assessment, $shownames, array $userinfo, $separator) {
1038          global $CFG;
1039  
1040          if (is_null($assessment)) {
1041              return get_string('nullgrade', 'workshop');
1042          }
1043          $a = new stdclass();
1044          $a->grade = is_null($assessment->grade) ? get_string('nullgrade', 'workshop') : $assessment->grade;
1045          $a->gradinggrade = is_null($assessment->gradinggrade) ? get_string('nullgrade', 'workshop') : $assessment->gradinggrade;
1046          $a->weight = $assessment->weight;
1047          // grrr the following logic should really be handled by a future language pack feature
1048          if (is_null($assessment->gradinggradeover)) {
1049              if ($a->weight == 1) {
1050                  $grade = get_string('formatpeergrade', 'workshop', $a);
1051              } else {
1052                  $grade = get_string('formatpeergradeweighted', 'workshop', $a);
1053              }
1054          } else {
1055              $a->gradinggradeover = $assessment->gradinggradeover;
1056              if ($a->weight == 1) {
1057                  $grade = get_string('formatpeergradeover', 'workshop', $a);
1058              } else {
1059                  $grade = get_string('formatpeergradeoverweighted', 'workshop', $a);
1060              }
1061          }
1062          $url = new moodle_url('/mod/workshop/assessment.php',
1063                                array('asid' => $assessment->assessmentid));
1064          $grade = html_writer::link($url, $grade, array('class'=>'grade'));
1065  
1066          if ($shownames) {
1067              $userid = $assessment->userid;
1068              $name   = $this->output->user_picture($userinfo[$userid], array('courseid' => $this->page->course->id, 'size' => 16));
1069              $name  .= html_writer::tag('span', fullname($userinfo[$userid]), array('class' => 'fullname'));
1070              $name   = $separator . html_writer::tag('span', $name, array('class' => 'user'));
1071          } else {
1072              $name   = '';
1073          }
1074  
1075          return $this->output->container($grade . $name, 'assessmentdetails');
1076      }
1077  
1078      /**
1079       * Formats the aggreagated grades
1080       */
1081      protected function helper_grading_report_grade($grade, $over=null) {
1082          $a = new stdclass();
1083          $a->grade = is_null($grade) ? get_string('nullgrade', 'workshop') : $grade;
1084          if (is_null($over)) {
1085              $text = get_string('formataggregatedgrade', 'workshop', $a);
1086          } else {
1087              $a->over = is_null($over) ? get_string('nullgrade', 'workshop') : $over;
1088              $text = get_string('formataggregatedgradeover', 'workshop', $a);
1089          }
1090          return $text;
1091      }
1092  
1093      ////////////////////////////////////////////////////////////////////////////
1094      // Static helpers
1095      ////////////////////////////////////////////////////////////////////////////
1096  
1097      /**
1098       * Helper method dealing with the fact we can not just fetch the output of moodleforms
1099       *
1100       * @param moodleform $mform
1101       * @return string HTML
1102       */
1103      protected static function moodleform(moodleform $mform) {
1104  
1105          ob_start();
1106          $mform->display();
1107          $o = ob_get_contents();
1108          ob_end_clean();
1109  
1110          return $o;
1111      }
1112  
1113      /**
1114       * Helper function returning the n-th item of the array
1115       *
1116       * @param array $a
1117       * @param int   $n from 0 to m, where m is th number of items in the array
1118       * @return mixed the $n-th element of $a
1119       */
1120      protected static function array_nth(array $a, $n) {
1121          $keys = array_keys($a);
1122          if ($n < 0 or $n > count($keys) - 1) {
1123              return null;
1124          }
1125          $key = $keys[$n];
1126          return $a[$key];
1127      }
1128  
1129      /**
1130       * Tries to guess the fullname format set at the site
1131       *
1132       * @return string fl|lf
1133       */
1134      protected static function fullname_format() {
1135          $fake = new stdclass(); // fake user
1136          $fake->lastname = 'LLLL';
1137          $fake->firstname = 'FFFF';
1138          $fullname = get_string('fullnamedisplay', '', $fake);
1139          if (strpos($fullname, 'LLLL') < strpos($fullname, 'FFFF')) {
1140              return 'lf';
1141          } else {
1142              return 'fl';
1143          }
1144      }
1145  }


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