Search moodle.org's
Developer Documentation


  • Bug fixes for general core bugs in 2.8.x ended 9 November 2015 (12 months).
  • Bug fixes for security issues in 2.8.x ended 9 May 2016 (18 months).
  • minimum PHP 5.4.4 (always use latest PHP 5.4.x or 5.5.x on Windows - http://windows.php.net/download/), PHP 7 is NOT supported
  • Differences Between: [Versions 28 and 32] [Versions 28 and 33] [Versions 28 and 34] [Versions 28 and 35] [Versions 28 and 36] [Versions 28 and 37]

       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 renderers for the course management pages.
      19   *
      20   * @package core_course
      21   * @copyright 2013 Sam Hemelryk
      22   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      23   */
      24  
      25  defined('MOODLE_INTERNAL') || die;
      26  
      27  require_once($CFG->dirroot.'/course/renderer.php');
      28  
      29  /**
      30   * Main renderer for the course management pages.
      31   *
      32   * @package core_course
      33   * @copyright 2013 Sam Hemelryk
      34   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      35   */
      36  class core_course_management_renderer extends plugin_renderer_base {
      37  
      38      /**
      39       * Initialises the JS required to enhance the management interface.
      40       *
      41       * Thunderbirds are go, this function kicks into gear the JS that makes the
      42       * course management pages that much cooler.
      43       */
      44      public function enhance_management_interface() {
      45          $this->page->requires->yui_module('moodle-course-management', 'M.course.management.init');
      46          $this->page->requires->strings_for_js(
      47              array(
      48                  'show',
      49                  'showcategory',
      50                  'hide',
      51                  'expand',
      52                  'expandcategory',
      53                  'collapse',
      54                  'collapsecategory',
      55                  'confirmcoursemove',
      56                  'move',
      57                  'cancel',
      58                  'confirm'
      59              ),
      60              'moodle'
      61          );
      62      }
      63  
      64      /**
      65       * Displays a heading for the management pages.
      66       *
      67       * @param string $heading The heading to display
      68       * @param string|null $viewmode The current view mode if there are options.
      69       * @param int|null $categoryid The currently selected category if there is one.
      70       * @return string
      71       */
      72      public function management_heading($heading, $viewmode = null, $categoryid = null) {
      73          $html = html_writer::start_div('coursecat-management-header clearfix');
      74          if (!empty($heading)) {
      75              $html .= $this->heading($heading);
      76          }
      77          if ($viewmode !== null) {
      78              $html .= html_writer::start_div();
      79              $html .= $this->view_mode_selector(\core_course\management\helper::get_management_viewmodes(), $viewmode);
      80              if ($viewmode === 'courses') {
      81                  $categories = coursecat::make_categories_list(array('moodle/category:manage', 'moodle/course:create'));
      82                  $nothing = false;
      83                  if ($categoryid === null) {
      84                      $nothing = array('' => get_string('selectacategory'));
      85                      $categoryid = '';
      86                  }
      87                  $select = new single_select($this->page->url, 'categoryid', $categories, $categoryid, $nothing);
      88                  $html .= $this->render($select);
      89              }
      90              $html .= html_writer::end_div();
      91          }
      92          $html .= html_writer::end_div();
      93          return $html;
      94      }
      95  
      96      /**
      97       * Prepares the form element for the course category listing bulk actions.
      98       *
      99       * @return string
     100       */
     101      public function management_form_start() {
     102          $form = array('action' => $this->page->url->out(), 'method' => 'POST', 'id' => 'coursecat-management');
     103  
     104          $html = html_writer::start_tag('form', $form);
     105          $html .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
     106          $html .=  html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'action', 'value' => 'bulkaction'));
     107          return $html;
     108      }
     109  
     110      /**
     111       * Closes the course category bulk management form.
     112       *
     113       * @return string
     114       */
     115      public function management_form_end() {
     116          return html_writer::end_tag('form');
     117      }
     118  
     119      /**
     120       * Presents a course category listing.
     121       *
     122       * @param coursecat $category The currently selected category. Also the category to highlight in the listing.
     123       * @return string
     124       */
     125      public function category_listing(coursecat $category = null) {
     126  
     127          if ($category === null) {
     128              $selectedparents = array();
     129              $selectedcategory = null;
     130          } else {
     131              $selectedparents = $category->get_parents();
     132              $selectedparents[] = $category->id;
     133              $selectedcategory = $category->id;
     134          }
     135          $catatlevel = \core_course\management\helper::get_expanded_categories('');
     136          $catatlevel[] = array_shift($selectedparents);
     137          $catatlevel = array_unique($catatlevel);
     138  
     139          $listing = coursecat::get(0)->get_children();
     140  
     141          $attributes = array(
     142              'class' => 'ml',
     143              'role' => 'tree',
     144              'aria-labelledby' => 'category-listing-title'
     145          );
     146  
     147          $html  = html_writer::start_div('category-listing');
     148          $html .= html_writer::tag('h3', get_string('categories'), array('id' => 'category-listing-title'));
     149          $html .= $this->category_listing_actions($category);
     150          $html .= html_writer::start_tag('ul', $attributes);
     151          foreach ($listing as $listitem) {
     152              // Render each category in the listing.
     153              $subcategories = array();
     154              if (in_array($listitem->id, $catatlevel)) {
     155                  $subcategories = $listitem->get_children();
     156              }
     157              $html .= $this->category_listitem(
     158                  $listitem,
     159                  $subcategories,
     160                  $listitem->get_children_count(),
     161                  $selectedcategory,
     162                  $selectedparents
     163              );
     164          }
     165          $html .= html_writer::end_tag('ul');
     166          $html .= $this->category_bulk_actions($category);
     167          $html .= html_writer::end_div();
     168          return $html;
     169      }
     170  
     171      /**
     172       * Renders a category list item.
     173       *
     174       * This function gets called recursively to render sub categories.
     175       *
     176       * @param coursecat $category The category to render as listitem.
     177       * @param coursecat[] $subcategories The subcategories belonging to the category being rented.
     178       * @param int $totalsubcategories The total number of sub categories.
     179       * @param int $selectedcategory The currently selected category
     180       * @param int[] $selectedcategories The path to the selected category and its ID.
     181       * @return string
     182       */
     183      public function category_listitem(coursecat $category, array $subcategories, $totalsubcategories,
     184                                        $selectedcategory = null, $selectedcategories = array()) {
     185  
     186          $isexpandable = ($totalsubcategories > 0);
     187          $isexpanded = (!empty($subcategories));
     188          $activecategory = ($selectedcategory === $category->id);
     189          $attributes = array(
     190              'class' => 'listitem listitem-category',
     191              'data-id' => $category->id,
     192              'data-expandable' => $isexpandable ? '1' : '0',
     193              'data-expanded' => $isexpanded ? '1' : '0',
     194              'data-selected' => $activecategory ? '1' : '0',
     195              'data-visible' => $category->visible ? '1' : '0',
     196              'role' => 'treeitem',
     197              'aria-expanded' => $isexpanded ? 'true' : 'false'
     198          );
     199          $text = $category->get_formatted_name();
     200          if ($category->parent) {
     201              $a = new stdClass;
     202              $a->category = $text;
     203              $a->parentcategory = $category->get_parent_coursecat()->get_formatted_name();
     204              $textlabel = get_string('categorysubcategoryof', 'moodle', $a);
     205          }
     206          $courseicon = $this->output->pix_icon('i/course', get_string('courses'));
     207          $bcatinput = array(
     208              'type' => 'checkbox',
     209              'name' => 'bcat[]',
     210              'value' => $category->id,
     211              'class' => 'bulk-action-checkbox',
     212              'aria-label' => get_string('bulkactionselect', 'moodle', $text),
     213              'data-action' => 'select'
     214          );
     215  
     216          if (!$category->can_resort_subcategories() && !$category->has_manage_capability()) {
     217              // Very very hardcoded here.
     218              $bcatinput['style'] = 'visibility:hidden';
     219          }
     220  
     221          $viewcaturl = new moodle_url('/course/management.php', array('categoryid' => $category->id));
     222          if ($isexpanded) {
     223              $icon = $this->output->pix_icon('t/switch_minus', get_string('collapse'), 'moodle', array('class' => 'tree-icon', 'title' => ''));
     224              $icon = html_writer::link(
     225                  $viewcaturl,
     226                  $icon,
     227                  array(
     228                      'class' => 'float-left',
     229                      'data-action' => 'collapse',
     230                      'title' => get_string('collapsecategory', 'moodle', $text),
     231                      'aria-controls' => 'subcategoryof'.$category->id
     232                  )
     233              );
     234          } else if ($isexpandable) {
     235              $icon = $this->output->pix_icon('t/switch_plus', get_string('expand'), 'moodle', array('class' => 'tree-icon', 'title' => ''));
     236              $icon = html_writer::link(
     237                  $viewcaturl,
     238                  $icon,
     239                  array(
     240                      'class' => 'float-left',
     241                      'data-action' => 'expand',
     242                      'title' => get_string('expandcategory', 'moodle', $text)
     243                  )
     244              );
     245          } else {
     246              $icon = $this->output->pix_icon(
     247                  'i/navigationitem',
     248                  '',
     249                  'moodle',
     250                  array('class' => 'tree-icon', 'title' => get_string('showcategory', 'moodle', $text))
     251              );
     252              $icon = html_writer::span($icon, 'float-left');
     253          }
     254          $actions = \core_course\management\helper::get_category_listitem_actions($category);
     255          $hasactions = !empty($actions) || $category->can_create_course();
     256  
     257          $html = html_writer::start_tag('li', $attributes);
     258          $html .= html_writer::start_div('clearfix');
     259          $html .= html_writer::start_div('float-left ba-checkbox');
     260          $html .= html_writer::empty_tag('input', $bcatinput).'&nbsp;';
     261          $html .= html_writer::end_div();
     262          $html .= $icon;
     263          if ($hasactions) {
     264              $textattributes = array('class' => 'float-left categoryname');
     265          } else {
     266              $textattributes = array('class' => 'float-left categoryname without-actions');
     267          }
     268          if (isset($textlabel)) {
     269              $textattributes['aria-label'] = $textlabel;
     270          }
     271          $html .= html_writer::link($viewcaturl, $text, $textattributes);
     272          $html .= html_writer::start_div('float-right');
     273          if ($category->idnumber) {
     274              $html .= html_writer::tag('span', s($category->idnumber), array('class' => 'dimmed idnumber'));
     275          }
     276          if ($hasactions) {
     277              $html .= $this->category_listitem_actions($category, $actions);
     278          }
     279          $countid = 'course-count-'.$category->id;
     280          $html .= html_writer::span(
     281              html_writer::span($category->get_courses_count()) .
     282              html_writer::span(get_string('courses'), 'accesshide', array('id' => $countid)) .
     283              $courseicon,
     284              'course-count dimmed',
     285              array('aria-labelledby' => $countid)
     286          );
     287          $html .= html_writer::end_div();
     288          $html .= html_writer::end_div();
     289          if ($isexpanded) {
     290              $html .= html_writer::start_tag('ul',
     291                  array('class' => 'ml', 'role' => 'group', 'id' => 'subcategoryof'.$category->id));
     292              $catatlevel = \core_course\management\helper::get_expanded_categories($category->path);
     293              $catatlevel[] = array_shift($selectedcategories);
     294              $catatlevel = array_unique($catatlevel);
     295              foreach ($subcategories as $listitem) {
     296                  $childcategories = (in_array($listitem->id, $catatlevel)) ? $listitem->get_children() : array();
     297                  $html .= $this->category_listitem(
     298                      $listitem,
     299                      $childcategories,
     300                      $listitem->get_children_count(),
     301                      $selectedcategory,
     302                      $selectedcategories
     303                  );
     304              }
     305              $html .= html_writer::end_tag('ul');
     306          }
     307          $html .= html_writer::end_tag('li');
     308          return $html;
     309      }
     310  
     311      /**
     312       * Renderers the actions that are possible for the course category listing.
     313       *
     314       * These are not the actions associated with an individual category listing.
     315       * That happens through category_listitem_actions.
     316       *
     317       * @param coursecat $category
     318       * @return string
     319       */
     320      public function category_listing_actions(coursecat $category = null) {
     321          $actions = array();
     322  
     323          $cancreatecategory = $category && $category->can_create_subcategory();
     324          $cancreatecategory = $cancreatecategory || coursecat::can_create_top_level_category();
     325          if ($category === null) {
     326              $category = coursecat::get(0);
     327          }
     328  
     329          if ($cancreatecategory) {
     330              $url = new moodle_url('/course/editcategory.php', array('parent' => $category->id));
     331              $actions[] = html_writer::link($url, get_string('createnewcategory'));
     332          }
     333          if (coursecat::can_approve_course_requests()) {
     334              $actions[] = html_writer::link(new moodle_url('/course/pending.php'), get_string('coursespending'));
     335          }
     336          if (count($actions) === 0) {
     337              return '';
     338          }
     339          return html_writer::div(join(' | ', $actions), 'listing-actions category-listing-actions');
     340      }
     341  
     342      /**
     343       * Renderers the actions for individual category list items.
     344       *
     345       * @param coursecat $category
     346       * @param array $actions
     347       * @return string
     348       */
     349      public function category_listitem_actions(coursecat $category, array $actions = null) {
     350          if ($actions === null) {
     351              $actions = \core_course\management\helper::get_category_listitem_actions($category);
     352          }
     353          $menu = new action_menu();
     354          $menu->attributes['class'] .= ' category-item-actions item-actions';
     355          $hasitems = false;
     356          foreach ($actions as $key => $action) {
     357              $hasitems = true;
     358              $menu->add(new action_menu_link(
     359                  $action['url'],
     360                  $action['icon'],
     361                  $action['string'],
     362                  in_array($key, array('show', 'hide', 'moveup', 'movedown')),
     363                  array('data-action' => $key, 'class' => 'action-'.$key)
     364              ));
     365          }
     366          if (!$hasitems) {
     367              return '';
     368          }
     369          return $this->render($menu);
     370      }
     371  
     372      /**
     373       * Renders bulk actions for categories.
     374       *
     375       * @param coursecat $category The currently selected category if there is one.
     376       * @return string
     377       */
     378      public function category_bulk_actions(coursecat $category = null) {
     379          // Resort courses.
     380          // Change parent.
     381          if (!coursecat::can_resort_any() && !coursecat::can_change_parent_any()) {
     382              return '';
     383          }
     384          $strgo = new lang_string('go');
     385  
     386          $html  = html_writer::start_div('category-bulk-actions bulk-actions');
     387          $html .= html_writer::div(get_string('categorybulkaction'), 'accesshide', array('tabindex' => '0'));
     388          if (coursecat::can_resort_any()) {
     389              $selectoptions = array(
     390                  'selectedcategories' => get_string('selectedcategories'),
     391                  'allcategories' => get_string('allcategories')
     392              );
     393              $form = html_writer::start_div();
     394              if ($category) {
     395                  $selectoptions = array('thiscategory' => get_string('thiscategory')) + $selectoptions;
     396                  $form .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'currentcategoryid', 'value' => $category->id));
     397              }
     398              $form .= html_writer::div(
     399                  html_writer::select(
     400                      $selectoptions,
     401                      'selectsortby',
     402                      'selectedcategories',
     403                      false,
     404                      array('aria-label' => get_string('selectcategorysort'))
     405                  )
     406              );
     407              $form .= html_writer::div(
     408                  html_writer::select(
     409                      array(
     410                          'name' => get_string('sortbyx', 'moodle', get_string('categoryname')),
     411                          'namedesc' => get_string('sortbyxreverse', 'moodle', get_string('categoryname')),
     412                          'idnumber' => get_string('sortbyx', 'moodle', get_string('idnumbercoursecategory')),
     413                          'idnumberdesc' => get_string('sortbyxreverse' , 'moodle' , get_string('idnumbercoursecategory')),
     414                          'none' => get_string('dontsortcategories')
     415                      ),
     416                      'resortcategoriesby',
     417                      'name',
     418                      false,
     419                      array('aria-label' => get_string('selectcategorysortby'))
     420                  )
     421              );
     422              $form .= html_writer::div(
     423                  html_writer::select(
     424                      array(
     425                          'fullname' => get_string('sortbyx', 'moodle', get_string('fullnamecourse')),
     426                          'fullnamedesc' => get_string('sortbyxreverse', 'moodle', get_string('fullnamecourse')),
     427                          'shortname' => get_string('sortbyx', 'moodle', get_string('shortnamecourse')),
     428                          'shortnamedesc' => get_string('sortbyxreverse', 'moodle', get_string('shortnamecourse')),
     429                          'idnumber' => get_string('sortbyx', 'moodle', get_string('idnumbercourse')),
     430                          'idnumberdesc' => get_string('sortbyxreverse', 'moodle', get_string('idnumbercourse')),
     431                          'timecreated' => get_string('sortbyx', 'moodle', get_string('timecreatedcourse')),
     432                          'timecreateddesc' => get_string('sortbyxreverse', 'moodle', get_string('timecreatedcourse')),
     433                          'none' => get_string('dontsortcourses')
     434                      ),
     435                      'resortcoursesby',
     436                      'fullname',
     437                      false,
     438                      array('aria-label' => get_string('selectcoursesortby'))
     439                  )
     440              );
     441              $form .= html_writer::empty_tag('input', array('type' => 'submit', 'name' => 'bulksort', 'value' => get_string('sort')));
     442              $form .= html_writer::end_div();
     443  
     444              $html .= html_writer::start_div('detail-pair row yui3-g');
     445              $html .= html_writer::div(html_writer::span(get_string('sorting')), 'pair-key span3 yui3-u-1-4');
     446              $html .= html_writer::div($form, 'pair-value span9 yui3-u-3-4');
     447              $html .= html_writer::end_div();
     448          }
     449          if (coursecat::can_change_parent_any()) {
     450              $options = array();
     451              if (has_capability('moodle/category:manage', context_system::instance())) {
     452                  $options[0] = coursecat::get(0)->get_formatted_name();
     453              }
     454              $options += coursecat::make_categories_list('moodle/category:manage');
     455              $select = html_writer::select(
     456                  $options,
     457                  'movecategoriesto',
     458                  '',
     459                  array('' => 'choosedots'),
     460                  array('aria-labelledby' => 'moveselectedcategoriesto')
     461              );
     462              $submit = array('type' => 'submit', 'name' => 'bulkmovecategories', 'value' => get_string('move'));
     463              $html .= $this->detail_pair(
     464                  html_writer::span(get_string('moveselectedcategoriesto'), '', array('id' => 'moveselectedcategoriesto')),
     465                  $select . html_writer::empty_tag('input', $submit)
     466              );
     467          }
     468          $html .= html_writer::end_div();
     469          return $html;
     470      }
     471  
     472      /**
     473       * Renders a course listing.
     474       *
     475       * @param coursecat $category The currently selected category. This is what the listing is focused on.
     476       * @param course_in_list $course The currently selected course.
     477       * @param int $page The page being displayed.
     478       * @param int $perpage The number of courses to display per page.
     479       * @return string
     480       */
     481      public function course_listing(coursecat $category = null, course_in_list $course = null, $page = 0, $perpage = 20) {
     482  
     483          if ($category === null) {
     484              $html = html_writer::start_div('select-a-category');
     485              $html .= html_writer::tag('h3', get_string('courses'),
     486                  array('id' => 'course-listing-title', 'tabindex' => '0'));
     487              $html .= $this->output->notification(get_string('selectacategory'), 'notifymessage');
     488              $html .= html_writer::end_div();
     489              return $html;
     490          }
     491  
     492          $page = max($page, 0);
     493          $perpage = max($perpage, 2);
     494          $totalcourses = $category->coursecount;
     495          $totalpages = ceil($totalcourses / $perpage);
     496          if ($page > $totalpages - 1) {
     497              $page = $totalpages - 1;
     498          }
     499          $options = array(
     500              'offset' => $page * $perpage,
     501              'limit' => $perpage
     502          );
     503          $courseid = isset($course) ? $course->id : null;
     504          $class = '';
     505          if ($page === 0) {
     506              $class .= ' firstpage';
     507          }
     508          if ($page + 1 === (int)$totalpages) {
     509              $class .= ' lastpage';
     510          }
     511  
     512          $html  = html_writer::start_div('course-listing'.$class, array(
     513              'data-category' => $category->id,
     514              'data-page' => $page,
     515              'data-totalpages' => $totalpages,
     516              'data-totalcourses' => $totalcourses,
     517              'data-canmoveoutof' => $category->can_move_courses_out_of() && $category->can_move_courses_into()
     518          ));
     519          $html .= html_writer::tag('h3', $category->get_formatted_name(),
     520              array('id' => 'course-listing-title', 'tabindex' => '0'));
     521          $html .= $this->course_listing_actions($category, $course, $perpage);
     522          $html .= $this->listing_pagination($category, $page, $perpage);
     523          $html .= html_writer::start_tag('ul', array('class' => 'ml', 'role' => 'group'));
     524          foreach ($category->get_courses($options) as $listitem) {
     525              $html .= $this->course_listitem($category, $listitem, $courseid);
     526          }
     527          $html .= html_writer::end_tag('ul');
     528          $html .= $this->listing_pagination($category, $page, $perpage, true);
     529          $html .= $this->course_bulk_actions($category);
     530          $html .= html_writer::end_div();
     531          return $html;
     532      }
     533  
     534      /**
     535       * Renders pagination for a course listing.
     536       *
     537       * @param coursecat $category The category to produce pagination for.
     538       * @param int $page The current page.
     539       * @param int $perpage The number of courses to display per page.
     540       * @param bool $showtotals Set to true to show the total number of courses and what is being displayed.
     541       * @return string
     542       */
     543      protected function listing_pagination(coursecat $category, $page, $perpage, $showtotals = false) {
     544          $html = '';
     545          $totalcourses = $category->get_courses_count();
     546          $totalpages = ceil($totalcourses / $perpage);
     547          if ($showtotals) {
     548              if ($totalpages == 0) {
     549                  $str = get_string('nocoursesyet');
     550              } else if ($totalpages == 1) {
     551                  $str = get_string('showingacourses', 'moodle', $totalcourses);
     552              } else {
     553                  $a = new stdClass;
     554                  $a->start = ($page * $perpage) + 1;
     555                  $a->end = min((($page + 1) * $perpage), $totalcourses);
     556                  $a->total = $totalcourses;
     557                  $str = get_string('showingxofycourses', 'moodle', $a);
     558              }
     559              $html .= html_writer::div($str, 'listing-pagination-totals dimmed');
     560          }
     561  
     562          if ($totalcourses <= $perpage) {
     563              return $html;
     564          }
     565          $aside = 2;
     566          $span = $aside * 2 + 1;
     567          $start = max($page - $aside, 0);
     568          $end = min($page + $aside, $totalpages - 1);
     569          if (($end - $start) < $span) {
     570              if ($start == 0) {
     571                  $end = min($totalpages - 1, $span - 1);
     572              } else if ($end == ($totalpages - 1)) {
     573                  $start = max(0, $end - $span + 1);
     574              }
     575          }
     576          $items = array();
     577          $baseurl = new moodle_url('/course/management.php', array('categoryid' => $category->id));
     578          if ($page > 0) {
     579              $items[] = $this->action_button(new moodle_url($baseurl, array('page' => 0)), get_string('first'));
     580              $items[] = $this->action_button(new moodle_url($baseurl, array('page' => $page - 1)), get_string('prev'));
     581              $items[] = '...';
     582          }
     583          for ($i = $start; $i <= $end; $i++) {
     584              $class = '';
     585              if ($page == $i) {
     586                  $class = 'active-page';
     587              }
     588              $pageurl = new moodle_url($baseurl, array('page' => $i));
     589              $items[] = $this->action_button($pageurl, $i + 1, null, $class, get_string('pagea', 'moodle', $i+1));
     590          }
     591          if ($page < ($totalpages - 1)) {
     592              $items[] = '...';
     593              $items[] = $this->action_button(new moodle_url($baseurl, array('page' => $page + 1)), get_string('next'));
     594              $items[] = $this->action_button(new moodle_url($baseurl, array('page' => $totalpages - 1)), get_string('last'));
     595          }
     596  
     597          $html .= html_writer::div(join('', $items), 'listing-pagination');
     598          return $html;
     599      }
     600  
     601      /**
     602       * Renderers a course list item.
     603       *
     604       * This function will be called for every course being displayed by course_listing.
     605       *
     606       * @param coursecat $category The currently selected category and the category the course belongs to.
     607       * @param course_in_list $course The course to produce HTML for.
     608       * @param int $selectedcourse The id of the currently selected course.
     609       * @return string
     610       */
     611      public function course_listitem(coursecat $category, course_in_list $course, $selectedcourse) {
     612  
     613          $text = $course->get_formatted_name();
     614          $attributes = array(
     615              'class' => 'listitem listitem-course',
     616              'data-id' => $course->id,
     617              'data-selected' => ($selectedcourse == $course->id) ? '1' : '0',
     618              'data-visible' => $course->visible ? '1' : '0'
     619          );
     620  
     621          $bulkcourseinput = array(
     622              'type' => 'checkbox',
     623              'name' => 'bc[]',
     624              'value' => $course->id,
     625              'class' => 'bulk-action-checkbox',
     626              'aria-label' => get_string('bulkactionselect', 'moodle', $text),
     627              'data-action' => 'select'
     628          );
     629          if (!$category->has_manage_capability()) {
     630              // Very very hardcoded here.
     631              $bulkcourseinput['style'] = 'visibility:hidden';
     632          }
     633  
     634          $viewcourseurl = new moodle_url($this->page->url, array('courseid' => $course->id));
     635  
     636          $html  = html_writer::start_tag('li', $attributes);
     637          $html .= html_writer::start_div('clearfix');
     638  
     639          if ($category->can_resort_courses()) {
     640              // In order for dnd to be available the user must be able to resort the category children..
     641              $html .= html_writer::div($this->output->pix_icon('i/move_2d', get_string('dndcourse')), 'float-left drag-handle');
     642          }
     643  
     644          $html .= html_writer::start_div('ba-checkbox float-left');
     645          $html .= html_writer::empty_tag('input', $bulkcourseinput).'&nbsp;';
     646          $html .= html_writer::end_div();
     647          $html .= html_writer::link($viewcourseurl, $text, array('class' => 'float-left coursename'));
     648          $html .= html_writer::start_div('float-right');
     649          if ($course->idnumber) {
     650              $html .= html_writer::tag('span', s($course->idnumber), array('class' => 'dimmed idnumber'));
     651          }
     652          $html .= $this->course_listitem_actions($category, $course);
     653          $html .= html_writer::end_div();
     654          $html .= html_writer::end_div();
     655          $html .= html_writer::end_tag('li');
     656          return $html;
     657      }
     658  
     659      /**
     660       * Renderers actions for the course listing.
     661       *
     662       * Not to be confused with course_listitem_actions which renderers the actions for individual courses.
     663       *
     664       * @param coursecat $category
     665       * @param course_in_list $course The currently selected course.
     666       * @param int $perpage
     667       * @return string
     668       */
     669      public function course_listing_actions(coursecat $category, course_in_list $course = null, $perpage = 20) {
     670          $actions = array();
     671          if ($category->can_create_course()) {
     672              $url = new moodle_url('/course/edit.php', array('category' => $category->id, 'returnto' => 'catmanage'));
     673              $actions[] = html_writer::link($url, get_string('createnewcourse'));
     674          }
     675          if ($category->can_request_course()) {
     676              // Request a new course.
     677              $url = new moodle_url('/course/request.php', array('return' => 'management'));
     678              $actions[] = html_writer::link($url, get_string('requestcourse'));
     679          }
     680          if ($category->can_resort_courses()) {
     681              $params = $this->page->url->params();
     682              $params['action'] = 'resortcourses';
     683              $params['sesskey'] = sesskey();
     684              $baseurl = new moodle_url('/course/management.php', $params);
     685              $fullnameurl = new moodle_url($baseurl, array('resort' => 'fullname'));
     686              $fullnameurldesc = new moodle_url($baseurl, array('resort' => 'fullnamedesc'));
     687              $shortnameurl = new moodle_url($baseurl, array('resort' => 'shortname'));
     688              $shortnameurldesc = new moodle_url($baseurl, array('resort' => 'shortnamedesc'));
     689              $idnumberurl = new moodle_url($baseurl, array('resort' => 'idnumber'));
     690              $idnumberdescurl = new moodle_url($baseurl, array('resort' => 'idnumberdesc'));
     691              $timecreatedurl = new moodle_url($baseurl, array('resort' => 'timecreated'));
     692              $timecreateddescurl = new moodle_url($baseurl, array('resort' => 'timecreateddesc'));
     693              $menu = new action_menu(array(
     694                  new action_menu_link_secondary($fullnameurl,
     695                                                 null,
     696                                                 get_string('sortbyx', 'moodle', get_string('fullnamecourse'))),
     697                  new action_menu_link_secondary($fullnameurldesc,
     698                                                 null,
     699                                                 get_string('sortbyxreverse', 'moodle', get_string('fullnamecourse'))),
     700                  new action_menu_link_secondary($shortnameurl,
     701                                                 null,
     702                                                 get_string('sortbyx', 'moodle', get_string('shortnamecourse'))),
     703                  new action_menu_link_secondary($shortnameurldesc,
     704                                                 null,
     705                                                 get_string('sortbyxreverse', 'moodle', get_string('shortnamecourse'))),
     706                  new action_menu_link_secondary($idnumberurl,
     707                                                 null,
     708                                                 get_string('sortbyx', 'moodle', get_string('idnumbercourse'))),
     709                  new action_menu_link_secondary($idnumberdescurl,
     710                                                 null,
     711                                                 get_string('sortbyxreverse', 'moodle', get_string('idnumbercourse'))),
     712                  new action_menu_link_secondary($timecreatedurl,
     713                                                 null,
     714                                                 get_string('sortbyx', 'moodle', get_string('timecreatedcourse'))),
     715                  new action_menu_link_secondary($timecreateddescurl,
     716                                                 null,
     717                                                 get_string('sortbyxreverse', 'moodle', get_string('timecreatedcourse')))
     718              ));
     719              $menu->set_menu_trigger(get_string('resortcourses'));
     720              $actions[] = $this->render($menu);
     721          }
     722          $strall = get_string('all');
     723          $menu = new action_menu(array(
     724              new action_menu_link_secondary(new moodle_url($this->page->url, array('perpage' => 5)), null, 5),
     725              new action_menu_link_secondary(new moodle_url($this->page->url, array('perpage' => 10)), null, 10),
     726              new action_menu_link_secondary(new moodle_url($this->page->url, array('perpage' => 20)), null, 20),
     727              new action_menu_link_secondary(new moodle_url($this->page->url, array('perpage' => 50)), null, 50),
     728              new action_menu_link_secondary(new moodle_url($this->page->url, array('perpage' => 100)), null, 100),
     729              new action_menu_link_secondary(new moodle_url($this->page->url, array('perpage' => 999)), null, $strall),
     730          ));
     731          if ((int)$perpage === 999) {
     732              $perpage = $strall;
     733          }
     734          $menu->attributes['class'] .= ' courses-per-page';
     735          $menu->set_menu_trigger(get_string('perpagea', 'moodle', $perpage));
     736          $actions[] = $this->render($menu);
     737          return html_writer::div(join(' | ', $actions), 'listing-actions course-listing-actions');
     738      }
     739  
     740      /**
     741       * Renderers actions for individual course actions.
     742       *
     743       * @param coursecat $category The currently selected category.
     744       * @param course_in_list $course The course to renderer actions for.
     745       * @return string
     746       */
     747      public function course_listitem_actions(coursecat $category, course_in_list $course) {
     748          $actions = \core_course\management\helper::get_course_listitem_actions($category, $course);
     749          if (empty($actions)) {
     750              return '';
     751          }
     752          $actionshtml = array();
     753          foreach ($actions as $action) {
     754              $action['attributes']['role'] = 'button';
     755              $actionshtml[] = $this->output->action_icon($action['url'], $action['icon'], null, $action['attributes']);
     756          }
     757          return html_writer::span(join('', $actionshtml), 'course-item-actions item-actions');
     758      }
     759  
     760      /**
     761       * Renderers bulk actions that can be performed on courses.
     762       *
     763       * @param coursecat $category The currently selected category and the category in which courses that
     764       *      are selectable belong.
     765       * @return string
     766       */
     767      public function course_bulk_actions(coursecat $category) {
     768          $html  = html_writer::start_div('course-bulk-actions bulk-actions');
     769          if ($category->can_move_courses_out_of()) {
     770              $html .= html_writer::div(get_string('coursebulkaction'), 'accesshide', array('tabindex' => '0'));
     771              $options = coursecat::make_categories_list('moodle/category:manage');
     772              $select = html_writer::select(
     773                  $options,
     774                  'movecoursesto',
     775                  '',
     776                  array('' => 'choosedots'),
     777                  array('aria-labelledby' => 'moveselectedcoursesto')
     778              );
     779              $submit = array('type' => 'submit', 'name' => 'bulkmovecourses', 'value' => get_string('move'));
     780              $html .= $this->detail_pair(
     781                  html_writer::span(get_string('moveselectedcoursesto'), '', array('id' => 'moveselectedcoursesto')),
     782                  $select . html_writer::empty_tag('input', $submit)
     783              );
     784          }
     785          $html .= html_writer::end_div();
     786          return $html;
     787      }
     788  
     789      /**
     790       * Renderers bulk actions that can be performed on courses in search returns
     791       *
     792       * @return string
     793       */
     794      public function course_search_bulk_actions() {
     795          $html  = html_writer::start_div('course-bulk-actions bulk-actions');
     796          $html .= html_writer::div(get_string('coursebulkaction'), 'accesshide', array('tabindex' => '0'));
     797          $options = coursecat::make_categories_list('moodle/category:manage');
     798          $select = html_writer::select(
     799              $options,
     800              'movecoursesto',
     801              '',
     802              array('' => 'choosedots'),
     803              array('aria-labelledby' => 'moveselectedcoursesto')
     804          );
     805          $submit = array('type' => 'submit', 'name' => 'bulkmovecourses', 'value' => get_string('move'));
     806          $html .= $this->detail_pair(
     807              html_writer::span(get_string('moveselectedcoursesto'), '', array('id' => 'moveselectedcoursesto')),
     808              $select . html_writer::empty_tag('input', $submit)
     809          );
     810          $html .= html_writer::end_div();
     811          return $html;
     812      }
     813  
     814      /**
     815       * Renderers detailed course information.
     816       *
     817       * @param course_in_list $course The course to display details for.
     818       * @return string
     819       */
     820      public function course_detail(course_in_list $course) {
     821          $details = \core_course\management\helper::get_course_detail_array($course);
     822          $fullname = $details['fullname']['value'];
     823  
     824          $html  = html_writer::start_div('course-detail');
     825          $html .= html_writer::tag('h3', $fullname, array('id' => 'course-detail-title', 'tabindex' => '0'));
     826          $html .= $this->course_detail_actions($course);
     827          foreach ($details as $class => $data) {
     828              $html .= $this->detail_pair($data['key'], $data['value'], $class);
     829          }
     830          $html .= html_writer::end_div();
     831          return $html;
     832      }
     833  
     834      /**
     835       * Renderers a key value pair of information for display.
     836       *
     837       * @param string $key
     838       * @param string $value
     839       * @param string $class
     840       * @return string
     841       */
     842      protected function detail_pair($key, $value, $class ='') {
     843          $html = html_writer::start_div('detail-pair row yui3-g '.preg_replace('#[^a-zA-Z0-9_\-]#', '-', $class));
     844          $html .= html_writer::div(html_writer::span($key), 'pair-key span3 yui3-u-1-4');
     845          $html .= html_writer::div(html_writer::span($value), 'pair-value span9 yui3-u-3-4');
     846          $html .= html_writer::end_div();
     847          return $html;
     848      }
     849  
     850      /**
     851       * A collection of actions for a course.
     852       *
     853       * @param course_in_list $course The course to display actions for.
     854       * @return string
     855       */
     856      public function course_detail_actions(course_in_list $course) {
     857          $actions = \core_course\management\helper::get_course_detail_actions($course);
     858          if (empty($actions)) {
     859              return '';
     860          }
     861          $options = array();
     862          foreach ($actions as $action) {
     863              $options[] = $this->action_link($action['url'], $action['string']);
     864          }
     865          return html_writer::div(join(' | ', $options), 'listing-actions course-detail-listing-actions');
     866      }
     867  
     868      /**
     869       * Creates an action button (styled link)
     870       *
     871       * @param moodle_url $url The URL to go to when clicked.
     872       * @param string $text The text for the button.
     873       * @param string $id An id to give the button.
     874       * @param string $class A class to give the button.
     875       * @param array $attributes Any additional attributes
     876       * @return string
     877       */
     878      protected function action_button(moodle_url $url, $text, $id = null, $class = null, $title = null, array $attributes = array()) {
     879          if (isset($attributes['class'])) {
     880              $attributes['class'] .= ' yui3-button';
     881          } else {
     882              $attributes['class'] = 'yui3-button';
     883          }
     884          if (!is_null($id)) {
     885              $attributes['id'] = $id;
     886          }
     887          if (!is_null($class)) {
     888              $attributes['class'] .= ' '.$class;
     889          }
     890          if (is_null($title)) {
     891              $title = $text;
     892          }
     893          $attributes['title'] = $title;
     894          if (!isset($attributes['role'])) {
     895              $attributes['role'] = 'button';
     896          }
     897          return html_writer::link($url, $text, $attributes);
     898      }
     899  
     900      /**
     901       * Opens a grid.
     902       *
     903       * Call {@link core_course_management_renderer::grid_column_start()} to create columns.
     904       *
     905       * @param string $id An id to give this grid.
     906       * @param string $class A class to give this grid.
     907       * @return string
     908       */
     909      public function grid_start($id = null, $class = null) {
     910          $gridclass = 'grid-row-r row-fluid';
     911          if (is_null($class)) {
     912              $class = $gridclass;
     913          } else {
     914              $class .= ' ' . $gridclass;
     915          }
     916          $attributes = array();
     917          if (!is_null($id)) {
     918              $attributes['id'] = $id;
     919          }
     920          return html_writer::start_div($class, $attributes);
     921      }
     922  
     923      /**
     924       * Closes the grid.
     925       *
     926       * @return string
     927       */
     928      public function grid_end() {
     929          return html_writer::end_div();
     930      }
     931  
     932      /**
     933       * Opens a grid column
     934       *
     935       * @param int $size The number of segments this column should span.
     936       * @param string $id An id to give the column.
     937       * @param string $class A class to give the column.
     938       * @return string
     939       */
     940      public function grid_column_start($size, $id = null, $class = null) {
     941  
     942          // Calculate Bootstrap grid sizing.
     943          $bootstrapclass = 'span'.$size;
     944  
     945          // Calculate YUI grid sizing.
     946          if ($size === 12) {
     947              $maxsize = 1;
     948              $size = 1;
     949          } else {
     950              $maxsize = 12;
     951              $divisors = array(8, 6, 5, 4, 3, 2);
     952              foreach ($divisors as $divisor) {
     953                  if (($maxsize % $divisor === 0) && ($size % $divisor === 0)) {
     954                      $maxsize = $maxsize / $divisor;
     955                      $size = $size / $divisor;
     956                      break;
     957                  }
     958              }
     959          }
     960          if ($maxsize > 1) {
     961              $yuigridclass =  "grid-col-{$size}-{$maxsize} grid-col";
     962          } else {
     963              $yuigridclass =  "grid-col-1 grid-col";
     964          }
     965  
     966          if (is_null($class)) {
     967              $class = $yuigridclass . ' ' . $bootstrapclass;
     968          } else {
     969              $class .= ' ' . $yuigridclass . ' ' . $bootstrapclass;
     970          }
     971          $attributes = array();
     972          if (!is_null($id)) {
     973              $attributes['id'] = $id;
     974          }
     975          return html_writer::start_div($class, $attributes);
     976      }
     977  
     978      /**
     979       * Closes a grid column.
     980       *
     981       * @return string
     982       */
     983      public function grid_column_end() {
     984          return html_writer::end_div();
     985      }
     986  
     987      /**
     988       * Renders an action_icon.
     989       *
     990       * This function uses the {@link core_renderer::action_link()} method for the
     991       * most part. What it does different is prepare the icon as HTML and use it
     992       * as the link text.
     993       *
     994       * @param string|moodle_url $url A string URL or moodel_url
     995       * @param pix_icon $pixicon
     996       * @param component_action $action
     997       * @param array $attributes associative array of html link attributes + disabled
     998       * @param bool $linktext show title next to image in link
     999       * @return string HTML fragment
    1000       */
    1001      public function action_icon($url, pix_icon $pixicon, component_action $action = null,
    1002                                  array $attributes = null, $linktext = false) {
    1003          if (!($url instanceof moodle_url)) {
    1004              $url = new moodle_url($url);
    1005          }
    1006          $attributes = (array)$attributes;
    1007  
    1008          if (empty($attributes['class'])) {
    1009              // Let devs override the class via $attributes.
    1010              $attributes['class'] = 'action-icon';
    1011          }
    1012  
    1013          $icon = $this->render($pixicon);
    1014  
    1015          if ($linktext) {
    1016              $text = $pixicon->attributes['alt'];
    1017          } else {
    1018              $text = '';
    1019          }
    1020  
    1021          return $this->action_link($url, $icon.$text, $action, $attributes);
    1022      }
    1023  
    1024      /**
    1025       * Displays a view mode selector.
    1026       *
    1027       * @param array $modes An array of view modes.
    1028       * @param string $currentmode The current view mode.
    1029       * @param moodle_url $url The URL to use when changing actions. Defaults to the page URL.
    1030       * @param string $param The param name.
    1031       * @return string
    1032       */
    1033      public function view_mode_selector(array $modes, $currentmode, moodle_url $url = null, $param = 'view') {
    1034          if ($url === null) {
    1035              $url = $this->page->url;
    1036          }
    1037  
    1038          $menu = new action_menu;
    1039          $menu->attributes['class'] .= ' view-mode-selector vms';
    1040  
    1041          $selected = null;
    1042          foreach ($modes as $mode => $modestr) {
    1043              $attributes = array(
    1044                  'class' => 'vms-mode',
    1045                  'data-mode' => $mode
    1046              );
    1047              if ($currentmode === $mode) {
    1048                  $attributes['class'] .= ' currentmode';
    1049                  $selected = $modestr;
    1050              }
    1051              if ($selected === null) {
    1052                  $selected = $modestr;
    1053              }
    1054              $modeurl = new moodle_url($url, array($param => $mode));
    1055              if ($mode === 'default') {
    1056                  $modeurl->remove_params($param);
    1057              }
    1058              $menu->add(new action_menu_link_secondary($modeurl, null, $modestr, $attributes));
    1059          }
    1060  
    1061          $menu->set_menu_trigger($selected);
    1062  
    1063          $html = html_writer::start_div('view-mode-selector vms');
    1064          $html .= get_string('viewing').' '.$this->render($menu);
    1065          $html .= html_writer::end_div();
    1066  
    1067          return $html;
    1068      }
    1069  
    1070      /**
    1071       * Displays a search result listing.
    1072       *
    1073       * @param array $courses The courses to display.
    1074       * @param int $totalcourses The total number of courses to display.
    1075       * @param course_in_list $course The currently selected course if there is one.
    1076       * @param int $page The current page, starting at 0.
    1077       * @param int $perpage The number of courses to display per page.
    1078       * @param string $search The string we are searching for.
    1079       * @return string
    1080       */
    1081      public function search_listing(array $courses, $totalcourses, course_in_list $course = null, $page = 0, $perpage = 20,
    1082          $search = '') {
    1083          $page = max($page, 0);
    1084          $perpage = max($perpage, 2);
    1085          $totalpages = ceil($totalcourses / $perpage);
    1086          if ($page > $totalpages - 1) {
    1087              $page = $totalpages - 1;
    1088          }
    1089          $courseid = isset($course) ? $course->id : null;
    1090          $first = true;
    1091          $last = false;
    1092          $i = $page * $perpage;
    1093  
    1094          $html  = html_writer::start_div('course-listing', array(
    1095              'data-category' => 'search',
    1096              'data-page' => $page,
    1097              'data-totalpages' => $totalpages,
    1098              'data-totalcourses' => $totalcourses
    1099          ));
    1100          $html .= html_writer::tag('h3', get_string('courses'));
    1101          $html .= $this->search_pagination($totalcourses, $page, $perpage);
    1102          $html .= html_writer::start_tag('ul', array('class' => 'ml'));
    1103          foreach ($courses as $listitem) {
    1104              $i++;
    1105              if ($i == $totalcourses) {
    1106                  $last = true;
    1107              }
    1108              $html .= $this->search_listitem($listitem, $courseid, $first, $last);
    1109              $first = false;
    1110          }
    1111          $html .= html_writer::end_tag('ul');
    1112          $html .= $this->search_pagination($totalcourses, $page, $perpage, true, $search);
    1113          $html .= $this->course_search_bulk_actions();
    1114          $html .= html_writer::end_div();
    1115          return $html;
    1116      }
    1117  
    1118      /**
    1119       * Displays pagination for search results.
    1120       *
    1121       * @param int $totalcourses The total number of courses to be displayed.
    1122       * @param int $page The current page.
    1123       * @param int $perpage The number of courses being displayed.
    1124       * @param bool $showtotals Whether or not to print total information.
    1125       * @param string $search The string we are searching for.
    1126       * @return string
    1127       */
    1128      protected function search_pagination($totalcourses, $page, $perpage, $showtotals = false, $search = '') {
    1129          $html = '';
    1130          $totalpages = ceil($totalcourses / $perpage);
    1131          if ($showtotals) {
    1132              if ($totalpages == 0) {
    1133                  $str = get_string('nocoursesfound', 'moodle', s($search));
    1134              } else if ($totalpages == 1) {
    1135                  $str = get_string('showingacourses', 'moodle', $totalcourses);
    1136              } else {
    1137                  $a = new stdClass;
    1138                  $a->start = ($page * $perpage) + 1;
    1139                  $a->end = min((($page + 1) * $perpage), $totalcourses);
    1140                  $a->total = $totalcourses;
    1141                  $str = get_string('showingxofycourses', 'moodle', $a);
    1142              }
    1143              $html .= html_writer::div($str, 'listing-pagination-totals dimmed');
    1144          }
    1145  
    1146          if ($totalcourses < $perpage) {
    1147              return $html;
    1148          }
    1149          $aside = 2;
    1150          $span = $aside * 2 + 1;
    1151          $start = max($page - $aside, 0);
    1152          $end = min($page + $aside, $totalpages - 1);
    1153          if (($end - $start) < $span) {
    1154              if ($start == 0) {
    1155                  $end = min($totalpages - 1, $span - 1);
    1156              } else if ($end == ($totalpages - 1)) {
    1157                  $start = max(0, $end - $span + 1);
    1158              }
    1159          }
    1160          $items = array();
    1161          $baseurl = $this->page->url;
    1162          if ($page > 0) {
    1163              $items[] = $this->action_button(new moodle_url($baseurl, array('page' => 0)), get_string('first'));
    1164              $items[] = $this->action_button(new moodle_url($baseurl, array('page' => $page - 1)), get_string('prev'));
    1165              $items[] = '...';
    1166          }
    1167          for ($i = $start; $i <= $end; $i++) {
    1168              $class = '';
    1169              if ($page == $i) {
    1170                  $class = 'active-page';
    1171              }
    1172              $items[] = $this->action_button(new moodle_url($baseurl, array('page' => $i)), $i + 1, null, $class);
    1173          }
    1174          if ($page < ($totalpages - 1)) {
    1175              $items[] = '...';
    1176              $items[] = $this->action_button(new moodle_url($baseurl, array('page' => $page + 1)), get_string('next'));
    1177              $items[] = $this->action_button(new moodle_url($baseurl, array('page' => $totalpages - 1)), get_string('last'));
    1178          }
    1179  
    1180          $html .= html_writer::div(join('', $items), 'listing-pagination');
    1181          return $html;
    1182      }
    1183  
    1184      /**
    1185       * Renderers a search result course list item.
    1186       *
    1187       * This function will be called for every course being displayed by course_listing.
    1188       *
    1189       * @param course_in_list $course The course to produce HTML for.
    1190       * @param int $selectedcourse The id of the currently selected course.
    1191       * @return string
    1192       */
    1193      public function search_listitem(course_in_list $course, $selectedcourse) {
    1194  
    1195          $text = $course->get_formatted_name();
    1196          $attributes = array(
    1197              'class' => 'listitem listitem-course',
    1198              'data-id' => $course->id,
    1199              'data-selected' => ($selectedcourse == $course->id) ? '1' : '0',
    1200              'data-visible' => $course->visible ? '1' : '0'
    1201          );
    1202          $bulkcourseinput = '';
    1203          if (coursecat::get($course->category)->can_move_courses_out_of()) {
    1204              $bulkcourseinput = array(
    1205                  'type' => 'checkbox',
    1206                  'name' => 'bc[]',
    1207                  'value' => $course->id,
    1208                  'class' => 'bulk-action-checkbox',
    1209                  'aria-label' => get_string('bulkactionselect', 'moodle', $text),
    1210                  'data-action' => 'select'
    1211              );
    1212          }
    1213          $viewcourseurl = new moodle_url($this->page->url, array('courseid' => $course->id));
    1214          $categoryname = coursecat::get($course->category)->get_formatted_name();
    1215  
    1216          $html  = html_writer::start_tag('li', $attributes);
    1217          $html .= html_writer::start_div('clearfix');
    1218          $html .= html_writer::start_div('float-left');
    1219          if ($bulkcourseinput) {
    1220              $html .= html_writer::empty_tag('input', $bulkcourseinput).'&nbsp;';
    1221          }
    1222          $html .= html_writer::end_div();
    1223          $html .= html_writer::link($viewcourseurl, $text, array('class' => 'float-left coursename'));
    1224          $html .= html_writer::tag('span', $categoryname, array('class' => 'float-left categoryname'));
    1225          $html .= html_writer::start_div('float-right');
    1226          $html .= $this->search_listitem_actions($course);
    1227          $html .= html_writer::tag('span', s($course->idnumber), array('class' => 'dimmed idnumber'));
    1228          $html .= html_writer::end_div();
    1229          $html .= html_writer::end_div();
    1230          $html .= html_writer::end_tag('li');
    1231          return $html;
    1232      }
    1233  
    1234      /**
    1235       * Renderers actions for individual course actions.
    1236       *
    1237       * @param course_in_list $course The course to renderer actions for.
    1238       * @return string
    1239       */
    1240      public function search_listitem_actions(course_in_list $course) {
    1241          $baseurl = new moodle_url(
    1242              '/course/managementsearch.php',
    1243              array('courseid' => $course->id, 'categoryid' => $course->category, 'sesskey' => sesskey())
    1244          );
    1245          $actions = array();
    1246          // Edit.
    1247          if ($course->can_access()) {
    1248              if ($course->can_edit()) {
    1249                  $actions[] = $this->output->action_icon(
    1250                      new moodle_url('/course/edit.php', array('id' => $course->id)),
    1251                      new pix_icon('t/edit', get_string('edit')),
    1252                      null,
    1253                      array('class' => 'action-edit')
    1254                  );
    1255              }
    1256              // Delete.
    1257              if ($course->can_delete()) {
    1258                  $actions[] = $this->output->action_icon(
    1259                      new moodle_url('/course/delete.php', array('id' => $course->id)),
    1260                      new pix_icon('t/delete', get_string('delete')),
    1261                      null,
    1262                      array('class' => 'action-delete')
    1263                  );
    1264              }
    1265              // Show/Hide.
    1266              if ($course->can_change_visibility()) {
    1267                      $actions[] = $this->output->action_icon(
    1268                          new moodle_url($baseurl, array('action' => 'hidecourse')),
    1269                          new pix_icon('t/hide', get_string('hide')),
    1270                          null,
    1271                          array('data-action' => 'hide', 'class' => 'action-hide')
    1272                      );
    1273                      $actions[] = $this->output->action_icon(
    1274                          new moodle_url($baseurl, array('action' => 'showcourse')),
    1275                          new pix_icon('t/show', get_string('show')),
    1276                          null,
    1277                          array('data-action' => 'show', 'class' => 'action-show')
    1278                      );
    1279              }
    1280          }
    1281          if (empty($actions)) {
    1282              return '';
    1283          }
    1284          return html_writer::span(join('', $actions), 'course-item-actions item-actions');
    1285      }
    1286  
    1287      /**
    1288       * Renders html to display a course search form
    1289       *
    1290       * @param string $value default value to populate the search field
    1291       * @param string $format display format - 'plain' (default), 'short' or 'navbar'
    1292       * @return string
    1293       */
    1294      public function course_search_form($value = '', $format = 'plain') {
    1295          static $count = 0;
    1296          $formid = 'coursesearch';
    1297          if ((++$count) > 1) {
    1298              $formid .= $count;
    1299          }
    1300  
    1301          switch ($format) {
    1302              case 'navbar' :
    1303                  $formid = 'coursesearchnavbar';
    1304                  $inputid = 'navsearchbox';
    1305                  $inputsize = 20;
    1306                  break;
    1307              case 'short' :
    1308                  $inputid = 'shortsearchbox';
    1309                  $inputsize = 12;
    1310                  break;
    1311              default :
    1312                  $inputid = 'coursesearchbox';
    1313                  $inputsize = 30;
    1314          }
    1315  
    1316          $strsearchcourses = get_string("searchcourses");
    1317          $searchurl = new moodle_url('/course/management.php');
    1318  
    1319          $output = html_writer::start_tag('form', array('id' => $formid, 'action' => $searchurl, 'method' => 'get'));
    1320          $output .= html_writer::start_tag('fieldset', array('class' => 'coursesearchbox invisiblefieldset'));
    1321          $output .= html_writer::tag('label', $strsearchcourses.': ', array('for' => $inputid));
    1322          $output .= html_writer::empty_tag('input', array('type' => 'text', 'id' => $inputid,
    1323              'size' => $inputsize, 'name' => 'search', 'value' => s($value)));
    1324          $output .= html_writer::empty_tag('input', array('type' => 'submit',
    1325              'value' => get_string('go')));
    1326          $output .= html_writer::end_tag('fieldset');
    1327          $output .= html_writer::end_tag('form');
    1328  
    1329          return $output;
    1330      }
    1331  
    1332      /**
    1333       * Creates access hidden skip to links for the displayed sections.
    1334       *
    1335       * @param bool $displaycategorylisting
    1336       * @param bool $displaycourselisting
    1337       * @param bool $displaycoursedetail
    1338       * @return string
    1339       */
    1340      public function accessible_skipto_links($displaycategorylisting, $displaycourselisting, $displaycoursedetail) {
    1341          $html = html_writer::start_div('skiplinks accesshide');
    1342          $url = new moodle_url($this->page->url);
    1343          if ($displaycategorylisting) {
    1344              $url->set_anchor('category-listing');
    1345              $html .= html_writer::link($url, get_string('skiptocategorylisting'), array('class' => 'skip'));
    1346          }
    1347          if ($displaycourselisting) {
    1348              $url->set_anchor('course-listing');
    1349              $html .= html_writer::link($url, get_string('skiptocourselisting'), array('class' => 'skip'));
    1350          }
    1351          if ($displaycoursedetail) {
    1352              $url->set_anchor('course-detail');
    1353              $html .= html_writer::link($url, get_string('skiptocoursedetails'), array('class' => 'skip'));
    1354          }
    1355          $html .= html_writer::end_div();
    1356          return $html;
    1357      }
    1358  
    1359  }
    

    Search This Site: