Search moodle.org's
Developer Documentation

See Release Notes

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

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

   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   * Tour helper.
  19   *
  20   * @package    tool_usertours
  21   * @copyright  2016 Andrew Nicols <andrew@nicols.co.uk>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace tool_usertours;
  26  
  27  use tool_usertours\local\clientside_filter\clientside_filter;
  28  
  29  defined('MOODLE_INTERNAL') || die();
  30  
  31  /**
  32   * Tour helper.
  33   *
  34   * @copyright  2016 Andrew Nicols <andrew@nicols.co.uk>
  35   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class helper {
  38  
  39      /**
  40       * @var MOVE_UP
  41       */
  42      const MOVE_UP = -1;
  43  
  44      /**
  45       * @var MOVE_DOWN
  46       */
  47      const MOVE_DOWN = 1;
  48  
  49      /**
  50       * @var boolean Has it been bootstrapped?
  51       */
  52      private static $bootstrapped = false;
  53  
  54      /**
  55       * Get the link to edit the step.
  56       *
  57       * If no stepid is specified, then a link to create a new step is provided. The $targettype must be specified in this case.
  58       *
  59       * @param   int     $tourid     The tour that the step belongs to.
  60       * @param   int     $stepid     The step ID.
  61       * @param   int     $targettype The type of step.
  62       *
  63       * @return moodle_url
  64       */
  65      public static function get_edit_step_link($tourid, $stepid = null, $targettype = null) {
  66          $link = new \moodle_url('/admin/tool/usertours/configure.php');
  67  
  68          if ($stepid) {
  69              $link->param('action', manager::ACTION_EDITSTEP);
  70              $link->param('id', $stepid);
  71          } else {
  72              $link->param('action', manager::ACTION_NEWSTEP);
  73              $link->param('tourid', $tourid);
  74          }
  75  
  76          return $link;
  77      }
  78  
  79      /**
  80       * Get the link to move the tour.
  81       *
  82       * @param   int     $tourid     The tour ID.
  83       * @param   int     $direction  The direction to move in
  84       *
  85       * @return moodle_url
  86       */
  87      public static function get_move_tour_link($tourid, $direction = self::MOVE_DOWN) {
  88          $link = new \moodle_url('/admin/tool/usertours/configure.php');
  89  
  90          $link->param('action', manager::ACTION_MOVETOUR);
  91          $link->param('id', $tourid);
  92          $link->param('direction', $direction);
  93          $link->param('sesskey', sesskey());
  94  
  95          return $link;
  96      }
  97  
  98      /**
  99       * Get the link to move the step.
 100       *
 101       * @param   int     $stepid     The step ID.
 102       * @param   int     $direction  The direction to move in
 103       *
 104       * @return moodle_url
 105       */
 106      public static function get_move_step_link($stepid, $direction = self::MOVE_DOWN) {
 107          $link = new \moodle_url('/admin/tool/usertours/configure.php');
 108  
 109          $link->param('action', manager::ACTION_MOVESTEP);
 110          $link->param('id', $stepid);
 111          $link->param('direction', $direction);
 112          $link->param('sesskey', sesskey());
 113  
 114          return $link;
 115      }
 116  
 117      /**
 118       * Get the link ot create a new step.
 119       *
 120       * @param   int         $tourid     The ID of the tour to attach this step to.
 121       * @param   int         $targettype The type of target.
 122       *
 123       * @return  moodle_url              The required URL.
 124       */
 125      public static function get_new_step_link($tourid, $targettype = null) {
 126          $link = new \moodle_url('/admin/tool/usertours/configure.php');
 127          $link->param('action', manager::ACTION_NEWSTEP);
 128          $link->param('tourid', $tourid);
 129          $link->param('targettype', $targettype);
 130  
 131          return $link;
 132      }
 133  
 134      /**
 135       * Get the link used to view the tour.
 136       *
 137       * @param   int         $tourid     The ID of the tour to display.
 138       * @return  moodle_url              The URL.
 139       */
 140      public static function get_view_tour_link($tourid) {
 141          return new \moodle_url('/admin/tool/usertours/configure.php', [
 142                  'id'        => $tourid,
 143                  'action'    => manager::ACTION_VIEWTOUR,
 144              ]);
 145      }
 146  
 147      /**
 148       * Get the link used to reset the tour state for all users.
 149       *
 150       * @param   int         $tourid     The ID of the tour to display.
 151       * @return  moodle_url              The URL.
 152       */
 153      public static function get_reset_tour_for_all_link($tourid) {
 154          return new \moodle_url('/admin/tool/usertours/configure.php', [
 155                  'id'        => $tourid,
 156                  'action'    => manager::ACTION_RESETFORALL,
 157                  'sesskey'   => sesskey(),
 158              ]);
 159      }
 160  
 161      /**
 162       * Get the link used to edit the tour.
 163       *
 164       * @param   int         $tourid     The ID of the tour to edit.
 165       * @return  moodle_url              The URL.
 166       */
 167      public static function get_edit_tour_link($tourid = null) {
 168          $link = new \moodle_url('/admin/tool/usertours/configure.php');
 169  
 170          if ($tourid) {
 171              $link->param('action', manager::ACTION_EDITTOUR);
 172              $link->param('id', $tourid);
 173          } else {
 174              $link->param('action', manager::ACTION_NEWTOUR);
 175          }
 176  
 177          return $link;
 178      }
 179  
 180      /**
 181       * Get the link used to import the tour.
 182       *
 183       * @return  moodle_url              The URL.
 184       */
 185      public static function get_import_tour_link() {
 186          $link = new \moodle_url('/admin/tool/usertours/configure.php', [
 187                  'action'    => manager::ACTION_IMPORTTOUR,
 188              ]);
 189  
 190          return $link;
 191      }
 192  
 193      /**
 194       * Get the link used to export the tour.
 195       *
 196       * @param   int         $tourid     The ID of the tour to export.
 197       * @return  moodle_url              The URL.
 198       */
 199      public static function get_export_tour_link($tourid) {
 200          $link = new \moodle_url('/admin/tool/usertours/configure.php', [
 201                  'action'    => manager::ACTION_EXPORTTOUR,
 202                  'id'        => $tourid,
 203              ]);
 204  
 205          return $link;
 206      }
 207  
 208      /**
 209       * Get the link used to duplicate the tour.
 210       *
 211       * @param   int         $tourid     The ID of the tour to duplicate.
 212       * @return  moodle_url              The URL.
 213       */
 214      public static function get_duplicate_tour_link($tourid) {
 215          $link = new \moodle_url('/admin/tool/usertours/configure.php', [
 216                  'action'    => manager::ACTION_DUPLICATETOUR,
 217                  'id'        => $tourid,
 218          ]);
 219  
 220          return $link;
 221      }
 222  
 223      /**
 224       * Get the link used to delete the tour.
 225       *
 226       * @param   int         $tourid     The ID of the tour to delete.
 227       * @return  moodle_url              The URL.
 228       */
 229      public static function get_delete_tour_link($tourid) {
 230          return new \moodle_url('/admin/tool/usertours/configure.php', [
 231                  'id'        => $tourid,
 232                  'action'    => manager::ACTION_DELETETOUR,
 233                  'sesskey'   => sesskey(),
 234              ]);
 235      }
 236  
 237      /**
 238       * Get the link for listing tours.
 239       *
 240       * @return  moodle_url              The URL.
 241       */
 242      public static function get_list_tour_link() {
 243          $link = new \moodle_url('/admin/tool/usertours/configure.php');
 244          $link->param('action', manager::ACTION_LISTTOURS);
 245  
 246          return $link;
 247      }
 248  
 249      /**
 250       * Get a filler icon for display in the actions column of a table.
 251       *
 252       * @param   string      $url            The URL for the icon.
 253       * @param   string      $icon           The icon identifier.
 254       * @param   string      $alt            The alt text for the icon.
 255       * @param   string      $iconcomponent  The icon component.
 256       * @param   array       $options        Display options.
 257       * @return  string
 258       */
 259      public static function format_icon_link($url, $icon, $alt, $iconcomponent = 'moodle', $options = array()) {
 260          global $OUTPUT;
 261  
 262          return $OUTPUT->action_icon(
 263                  $url,
 264                  new \pix_icon($icon, $alt, $iconcomponent, [
 265                          'title' => $alt,
 266                      ]),
 267                  null,
 268                  $options
 269                  );
 270  
 271      }
 272  
 273      /**
 274       * Get a filler icon for display in the actions column of a table.
 275       *
 276       * @param   array       $options        Display options.
 277       * @return  string
 278       */
 279      public static function get_filler_icon($options = array()) {
 280          global $OUTPUT;
 281  
 282          return \html_writer::span(
 283              $OUTPUT->pix_icon('t/filler', '', 'tool_usertours', $options),
 284              'action-icon'
 285          );
 286      }
 287  
 288      /**
 289       * Get the link for deleting steps.
 290       *
 291       * @param   int         $stepid     The ID of the step to display.
 292       * @return  moodle_url              The URL.
 293       */
 294      public static function get_delete_step_link($stepid) {
 295          return new \moodle_url('/admin/tool/usertours/configure.php', [
 296                  'action'    => manager::ACTION_DELETESTEP,
 297                  'id'        => $stepid,
 298                  'sesskey'   => sesskey(),
 299              ]);
 300      }
 301  
 302      /**
 303       * Render the inplace editable used to edit the tour name.
 304       *
 305       * @param   tour        $tour       The tour to edit.
 306       * @return  string
 307       */
 308      public static function render_tourname_inplace_editable(tour $tour) {
 309          return new \core\output\inplace_editable(
 310                  'tool_usertours',
 311                  'tourname',
 312                  $tour->get_id(),
 313                  true,
 314                  \html_writer::link(
 315                      $tour->get_view_link(),
 316                      $tour->get_name()
 317                  ),
 318                  $tour->get_name()
 319              );
 320      }
 321  
 322      /**
 323       * Render the inplace editable used to edit the tour description.
 324       *
 325       * @param   tour        $tour       The tour to edit.
 326       * @return  string
 327       */
 328      public static function render_tourdescription_inplace_editable(tour $tour) {
 329          return new \core\output\inplace_editable(
 330                  'tool_usertours',
 331                  'tourdescription',
 332                  $tour->get_id(),
 333                  true,
 334                  $tour->get_description(),
 335                  $tour->get_description()
 336              );
 337      }
 338  
 339      /**
 340       * Render the inplace editable used to edit the tour enable state.
 341       *
 342       * @param   tour        $tour       The tour to edit.
 343       * @return  string
 344       */
 345      public static function render_tourenabled_inplace_editable(tour $tour) {
 346          global $OUTPUT;
 347  
 348          if ($tour->is_enabled()) {
 349              $icon = 't/hide';
 350              $alt = get_string('disable');
 351              $value = 1;
 352          } else {
 353              $icon = 't/show';
 354              $alt = get_string('enable');
 355              $value = 0;
 356          }
 357  
 358          $editable = new \core\output\inplace_editable(
 359                  'tool_usertours',
 360                  'tourenabled',
 361                  $tour->get_id(),
 362                  true,
 363                  $OUTPUT->pix_icon($icon, $alt, 'moodle', [
 364                          'title' => $alt,
 365                      ]),
 366                  $value
 367              );
 368  
 369          $editable->set_type_toggle();
 370          return $editable;
 371      }
 372  
 373      /**
 374       * Render the inplace editable used to edit the step name.
 375       *
 376       * @param   step        $step       The step to edit.
 377       * @return  string
 378       */
 379      public static function render_stepname_inplace_editable(step $step) {
 380          $title = format_text(step::get_string_from_input($step->get_title()), FORMAT_HTML);
 381  
 382          return new \core\output\inplace_editable(
 383                  'tool_usertours',
 384                  'stepname',
 385                  $step->get_id(),
 386                  true,
 387                  \html_writer::link(
 388                      $step->get_edit_link(),
 389                      $title
 390                  ),
 391                  $step->get_title()
 392              );
 393      }
 394  
 395      /**
 396       * Get all of the tours.
 397       *
 398       * @return  stdClass[]
 399       */
 400      public static function get_tours() {
 401          global $DB;
 402  
 403          $tours = $DB->get_records('tool_usertours_tours', array(), 'sortorder ASC');
 404          $return = [];
 405          foreach ($tours as $tour) {
 406              $return[$tour->id] = tour::load_from_record($tour);
 407          }
 408          return $return;
 409      }
 410  
 411      /**
 412       * Get the specified tour.
 413       *
 414       * @param   int         $tourid     The tour that the step belongs to.
 415       * @return  stdClass
 416       */
 417      public static function get_tour($tourid) {
 418          return tour::instance($tourid);
 419      }
 420  
 421      /**
 422       * Fetch the tour with the specified sortorder.
 423       *
 424       * @param   int         $sortorder  The sortorder of the tour.
 425       * @return  tour
 426       */
 427      public static function get_tour_from_sortorder($sortorder) {
 428          global $DB;
 429  
 430          $tour = $DB->get_record('tool_usertours_tours', array('sortorder' => $sortorder));
 431          return tour::load_from_record($tour);
 432      }
 433  
 434      /**
 435       * Return the count of all tours.
 436       *
 437       * @return  int
 438       */
 439      public static function count_tours() {
 440          global $DB;
 441  
 442          return $DB->count_records('tool_usertours_tours');
 443      }
 444  
 445      /**
 446       * Reset the sortorder for all tours.
 447       */
 448      public static function reset_tour_sortorder() {
 449          global $DB;
 450          $tours = $DB->get_records('tool_usertours_tours', null, 'sortorder ASC, pathmatch DESC', 'id, sortorder');
 451  
 452          $index = 0;
 453          foreach ($tours as $tour) {
 454              if ($tour->sortorder != $index) {
 455                  $DB->set_field('tool_usertours_tours', 'sortorder', $index, array('id' => $tour->id));
 456              }
 457              $index++;
 458          }
 459  
 460          // Notify the cache that a tour has changed.
 461          // Tours are only stored in the cache if there are steps.
 462          // If there step count has changed for some reason, this will change the potential cache results.
 463          cache::notify_tour_change();
 464      }
 465  
 466  
 467      /**
 468       * Get all of the steps in the tour.
 469       *
 470       * @param   int         $tourid     The tour that the step belongs to.
 471       * @return  stdClass[]
 472       */
 473      public static function get_steps($tourid) {
 474          $steps = cache::get_stepdata($tourid);
 475  
 476          $return = [];
 477          foreach ($steps as $step) {
 478              $return[$step->id] = step::load_from_record($step);
 479          }
 480          return $return;
 481      }
 482  
 483      /**
 484       * Fetch the specified step.
 485       *
 486       * @param   int         $stepid     The id of the step to fetch.
 487       * @return  step
 488       */
 489      public static function get_step($stepid) {
 490          return step::instance($stepid);
 491      }
 492  
 493      /**
 494       * Fetch the step with the specified sortorder.
 495       *
 496       * @param   int         $tourid     The tour that the step belongs to.
 497       * @param   int         $sortorder  The sortorder of the step.
 498       * @return  step
 499       */
 500      public static function get_step_from_sortorder($tourid, $sortorder) {
 501          global $DB;
 502  
 503          $step = $DB->get_record('tool_usertours_steps', array('tourid' => $tourid, 'sortorder' => $sortorder));
 504          return step::load_from_record($step);
 505      }
 506  
 507      /**
 508       * Handle addition of the tour into the current page.
 509       */
 510      public static function bootstrap() {
 511          global $PAGE;
 512  
 513          if (!isloggedin() || isguestuser()) {
 514              return;
 515          }
 516  
 517          if (in_array($PAGE->pagelayout, ['maintenance', 'print', 'redirect'])) {
 518              // Do not try to show user tours inside iframe, in maintenance mode,
 519              // when printing, or during redirects.
 520              return;
 521          }
 522  
 523          if (self::$bootstrapped) {
 524              return;
 525          }
 526          self::$bootstrapped = true;
 527  
 528          $tours = manager::get_current_tours();
 529  
 530          if ($tours) {
 531              $filters = static::get_all_clientside_filters();
 532  
 533              $tourdetails = array_map(function($tour) use ($filters) {
 534                  return [
 535                          'tourId' => $tour->get_id(),
 536                          'startTour' => $tour->should_show_for_user(),
 537                          'filtervalues' => $tour->get_client_filter_values($filters),
 538                  ];
 539              }, $tours);
 540  
 541              $filternames = [];
 542              foreach ($filters as $filter) {
 543                      $filternames[] = $filter::get_filter_name();
 544              }
 545  
 546              $PAGE->requires->js_call_amd('tool_usertours/usertours', 'init', [
 547                      $tourdetails,
 548                      $filternames,
 549              ]);
 550          }
 551      }
 552  
 553      /**
 554       * Get a list of all possible filters.
 555       *
 556       * @return  array
 557       */
 558      public static function get_all_filters() {
 559          $filters = \core_component::get_component_classes_in_namespace('tool_usertours', 'local\filter');
 560          $filters = array_keys($filters);
 561  
 562          $filters = array_filter($filters, function($filterclass) {
 563              $rc = new \ReflectionClass($filterclass);
 564              return $rc->isInstantiable();
 565          });
 566  
 567          $filters = array_merge($filters, static::get_all_clientside_filters());
 568  
 569          return $filters;
 570      }
 571  
 572      /**
 573       * Get a list of all clientside filters.
 574       *
 575       * @return  array
 576       */
 577      public static function get_all_clientside_filters() {
 578          $filters = \core_component::get_component_classes_in_namespace('tool_usertours', 'local\clientside_filter');
 579          $filters = array_keys($filters);
 580  
 581          $filters = array_filter($filters, function($filterclass) {
 582              $rc = new \ReflectionClass($filterclass);
 583              return $rc->isInstantiable();
 584          });
 585  
 586          return $filters;
 587      }
 588  }