Differences Between: [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403]
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 * Step class. 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 defined('MOODLE_INTERNAL') || die(); 28 29 /** 30 * Step class. 31 * 32 * @copyright 2016 Andrew Nicols <andrew@nicols.co.uk> 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 class step { 36 37 /** 38 * @var int $id The id of the step. 39 */ 40 protected $id; 41 42 /** 43 * @var int $tourid The id of the tour that this step belongs to. 44 */ 45 protected $tourid; 46 47 /** 48 * @var tour $tour The tour class that this step belongs to. 49 */ 50 protected $tour; 51 52 /** 53 * @var string $title The title of the step. 54 */ 55 protected $title; 56 57 /** 58 * @var string $content The content of this step. 59 */ 60 protected $content; 61 62 /** 63 * @var int $targettype The type of target. 64 */ 65 protected $targettype; 66 67 /** 68 * @var string $targetvalue The value for this type of target. 69 */ 70 protected $targetvalue; 71 72 /** 73 * @var int $sortorder The sort order. 74 */ 75 protected $sortorder; 76 77 /** 78 * @var object $config The configuration as an object. 79 */ 80 protected $config; 81 82 /** 83 * @var bool $dirty Whether the step has been changed since it was loaded 84 */ 85 protected $dirty = false; 86 87 /** 88 * Fetch the step instance. 89 * 90 * @param int $id The id of the step to be retrieved. 91 * @return step 92 */ 93 public static function instance($id) { 94 $step = new step(); 95 return $step->fetch($id); 96 } 97 98 /** 99 * Load the step instance. 100 * 101 * @param stdClass $record The step record to be loaded. 102 * @param boolean $clean Clean the values. 103 * @return step 104 */ 105 public static function load_from_record($record, $clean = false) { 106 $step = new self(); 107 return $step->reload_from_record($record, $clean); 108 } 109 110 /** 111 * Fetch the step instance. 112 * 113 * @param int $id The id of the step to be retrieved. 114 * @return step 115 */ 116 protected function fetch($id) { 117 global $DB; 118 119 return $this->reload_from_record( 120 $DB->get_record('tool_usertours_steps', array('id' => $id)) 121 ); 122 } 123 124 /** 125 * Refresh the current step from the datbase. 126 * 127 * @return step 128 */ 129 protected function reload() { 130 return $this->fetch($this->id); 131 } 132 133 /** 134 * Reload the current step from the supplied record. 135 * 136 * @param stdClass $record The step record to be loaded. 137 * @param boolean $clean Clean the values. 138 * @return step 139 */ 140 protected function reload_from_record($record, $clean = false) { 141 $this->id = $record->id; 142 $this->tourid = $record->tourid; 143 if ($clean) { 144 $this->title = clean_param($record->title, PARAM_TEXT); 145 $this->content = clean_text($record->content); 146 } else { 147 $this->title = $record->title; 148 $this->content = $record->content; 149 } 150 $this->targettype = $record->targettype; 151 $this->targetvalue = $record->targetvalue; 152 $this->sortorder = $record->sortorder; 153 $this->config = json_decode($record->configdata); 154 $this->dirty = false; 155 156 return $this; 157 } 158 159 /** 160 * Get the ID of the step. 161 * 162 * @return int 163 */ 164 public function get_id() { 165 return $this->id; 166 } 167 168 /** 169 * Get the Tour ID of the step. 170 * 171 * @return int 172 */ 173 public function get_tourid() { 174 return $this->tourid; 175 } 176 177 /** 178 * Get the Tour instance that this step belongs to. 179 * 180 * @return tour 181 */ 182 public function get_tour() { 183 if ($this->tour === null) { 184 $this->tour = tour::instance($this->tourid); 185 } 186 return $this->tour; 187 } 188 189 /** 190 * Set the id of the tour. 191 * 192 * @param int $value The id of the tour. 193 * @return self 194 */ 195 public function set_tourid($value) { 196 $this->tourid = $value; 197 $this->tour = null; 198 $this->dirty = true; 199 200 return $this; 201 } 202 203 /** 204 * Get the Title of the step. 205 * 206 * @return string 207 */ 208 public function get_title() { 209 return $this->title; 210 } 211 212 /** 213 * Set the title for this step. 214 * 215 * @param string $value The new title to use. 216 * @return $this 217 */ 218 public function set_title($value) { 219 $this->title = clean_text($value); 220 $this->dirty = true; 221 222 return $this; 223 } 224 225 /** 226 * Get the body content of the step. 227 * 228 * @return string 229 */ 230 public function get_content() { 231 return $this->content; 232 } 233 234 /** 235 * Set the content value for this step. 236 * 237 * @param string $value The new content to use. 238 * @return $this 239 */ 240 public function set_content($value) { 241 $this->content = clean_text($value); 242 $this->dirty = true; 243 244 return $this; 245 } 246 247 /** 248 * Get the content value for this step. 249 * 250 * @return string 251 */ 252 public function get_targettype() { 253 return $this->targettype; 254 } 255 256 /** 257 * Set the type of target for this step. 258 * 259 * @param string $value The new target to use. 260 * @return $this 261 */ 262 public function set_targettype($value) { 263 $this->targettype = $value; 264 $this->dirty = true; 265 266 return $this; 267 } 268 269 /** 270 * Get the target value for this step. 271 * 272 * @return string 273 */ 274 public function get_targetvalue() { 275 return $this->targetvalue; 276 } 277 278 /** 279 * Set the target value for this step. 280 * 281 * @param string $value The new target value to use. 282 * @return $this 283 */ 284 public function set_targetvalue($value) { 285 $this->targetvalue = $value; 286 $this->dirty = true; 287 288 return $this; 289 } 290 291 /** 292 * Get the target instance for this step. 293 * 294 * @return target 295 */ 296 public function get_target() { 297 return target::get_target_instance($this); 298 } 299 300 /** 301 * Get the current sortorder for this step. 302 * 303 * @return int 304 */ 305 public function get_sortorder() { 306 return (int) $this->sortorder; 307 } 308 309 /** 310 * Whether this step is the first step in the tour. 311 * 312 * @return boolean 313 */ 314 public function is_first_step() { 315 return ($this->get_sortorder() === 0); 316 } 317 318 /** 319 * Whether this step is the last step in the tour. 320 * 321 * @return boolean 322 */ 323 public function is_last_step() { 324 $stepcount = $this->get_tour()->count_steps(); 325 return ($this->get_sortorder() === $stepcount - 1); 326 } 327 328 /** 329 * Set the sortorder for this step. 330 * 331 * @param int $value The new sortorder to use. 332 * @return $this 333 */ 334 public function set_sortorder($value) { 335 $this->sortorder = $value; 336 $this->dirty = true; 337 338 return $this; 339 } 340 341 /** 342 * Get the link to move this step up in the sortorder. 343 * 344 * @return moodle_url 345 */ 346 public function get_moveup_link() { 347 return helper::get_move_step_link($this->get_id(), helper::MOVE_UP); 348 } 349 350 /** 351 * Get the link to move this step down in the sortorder. 352 * 353 * @return moodle_url 354 */ 355 public function get_movedown_link() { 356 return helper::get_move_step_link($this->get_id(), helper::MOVE_DOWN); 357 } 358 359 /** 360 * Get the value of the specified configuration item. 361 * 362 * If notvalue was found, and no default was specified, the default for the tour will be used. 363 * 364 * @param string $key The configuration key to set. 365 * @param mixed $default The default value to use if a value was not found. 366 * @return mixed 367 */ 368 public function get_config($key = null, $default = null) { 369 if ($this->config === null) { 370 $this->config = (object) array(); 371 } 372 373 if ($key === null) { 374 return $this->config; 375 } 376 377 if ($this->get_targettype() !== null) { 378 $target = $this->get_target(); 379 if ($target->is_setting_forced($key)) { 380 return $target->get_forced_setting_value($key); 381 } 382 } 383 384 if (property_exists($this->config, $key)) { 385 return $this->config->$key; 386 } 387 388 if ($default !== null) { 389 return $default; 390 } 391 392 return $this->get_tour()->get_config($key); 393 } 394 395 /** 396 * Set the configuration item as specified. 397 * 398 * @param string $key The configuration key to set. 399 * @param mixed $value The new value for the configuration item. 400 * @return $this 401 */ 402 public function set_config($key, $value) { 403 if ($this->config === null) { 404 $this->config = (object) array(); 405 } 406 407 if ($value === null) { 408 unset($this->config->$key); 409 } else { 410 $this->config->$key = $value; 411 } 412 $this->dirty = true; 413 414 return $this; 415 } 416 417 /** 418 * Get the edit link for this step. 419 * 420 * @return moodle_url 421 */ 422 public function get_edit_link() { 423 return helper::get_edit_step_link($this->tourid, $this->id); 424 } 425 426 /** 427 * Get the delete link for this step. 428 * 429 * @return moodle_url 430 */ 431 public function get_delete_link() { 432 return helper::get_delete_step_link($this->id); 433 } 434 435 /** 436 * Prepare this step for saving to the database. 437 * 438 * @return object 439 */ 440 public function to_record() { 441 return (object) array( 442 'id' => $this->id, 443 'tourid' => $this->tourid, 444 'title' => $this->title, 445 'content' => $this->content, 446 'targettype' => $this->targettype, 447 'targetvalue' => $this->targetvalue, 448 'sortorder' => $this->sortorder, 449 'configdata' => json_encode($this->config), 450 ); 451 } 452 453 /** 454 * Calculate the next sort-order value. 455 * 456 * @return int 457 */ 458 protected function calculate_sortorder() { 459 $count = $this->get_tour()->count_steps(); 460 $this->sortorder = $count; 461 462 return $this; 463 } 464 465 /** 466 * Save the tour and it's configuration to the database. 467 * 468 * @param boolean $force Whether to force writing to the database. 469 * @return $this 470 */ 471 public function persist($force = false) { 472 global $DB; 473 474 if (!$this->dirty && !$force) { 475 return $this; 476 } 477 478 if ($this->id) { 479 $record = $this->to_record(); 480 $DB->update_record('tool_usertours_steps', $record); 481 } else { 482 $this->calculate_sortorder(); 483 $record = $this->to_record(); 484 unset($record->id); 485 $this->id = $DB->insert_record('tool_usertours_steps', $record); 486 $this->get_tour()->reset_step_sortorder(); 487 } 488 489 $this->reload(); 490 491 // Notify of a change to the step configuration. 492 // This must be done separately to tour change notifications. 493 cache::notify_step_change($this->get_tourid()); 494 495 // Notify the cache that a tour has changed. 496 // Tours are only stored in the cache if there are steps. 497 // If there step count has changed for some reason, this will change the potential cache results. 498 cache::notify_tour_change(); 499 500 return $this; 501 } 502 503 /** 504 * Remove this step. 505 */ 506 public function remove() { 507 global $DB; 508 509 if ($this->id === null) { 510 return; 511 } 512 513 $DB->delete_records('tool_usertours_steps', array('id' => $this->id)); 514 $this->get_tour()->reset_step_sortorder(); 515 516 // Notify of a change to the step configuration. 517 // This must be done separately to tour change notifications. 518 cache::notify_step_change($this->get_id()); 519 520 // Notify the cache that a tour has changed. 521 // Tours are only stored in the cache if there are steps. 522 // If there step count has changed for some reason, this will change the potential cache results. 523 cache::notify_tour_change(); 524 } 525 526 /** 527 * Get the list of possible placement options. 528 * 529 * @return array 530 */ 531 public function get_placement_options() { 532 return configuration::get_placement_options(true); 533 } 534 535 /** 536 * The list of possible configuration keys. 537 * 538 * @return array 539 */ 540 public static function get_config_keys() { 541 return [ 542 'placement', 543 'orphan', 544 'backdrop', 545 'reflex', 546 ]; 547 } 548 549 /** 550 * Add the step configuration to the form. 551 * 552 * @param MoodleQuickForm $mform The form to add configuration to. 553 * @return $this 554 */ 555 public function add_config_to_form(\MoodleQuickForm $mform) { 556 $tour = $this->get_tour(); 557 558 $options = configuration::get_placement_options($tour->get_config('placement')); 559 $mform->addElement('select', 'placement', get_string('placement', 'tool_usertours'), $options); 560 $mform->addHelpButton('placement', 'placement', 'tool_usertours'); 561 562 $this->add_config_field_to_form($mform, 'orphan'); 563 $this->add_config_field_to_form($mform, 'backdrop'); 564 $this->add_config_field_to_form($mform, 'reflex'); 565 566 return $this; 567 } 568 569 /** 570 * Add the specified step field configuration to the form. 571 * 572 * @param MoodleQuickForm $mform The form to add configuration to. 573 * @param string $key The key to add. 574 * @return $this 575 */ 576 public function add_config_field_to_form(\MoodleQuickForm $mform, $key) { 577 $tour = $this->get_tour(); 578 579 $default = (bool) $tour->get_config($key); 580 581 $options = [ 582 true => get_string('yes'), 583 false => get_string('no'), 584 ]; 585 586 if (!isset($options[$default])) { 587 $default = configuration::get_default_value($key); 588 } 589 590 $options = array_reverse($options, true); 591 $options[configuration::TOURDEFAULT] = get_string('defaultvalue', 'tool_usertours', $options[$default]); 592 $options = array_reverse($options, true); 593 594 $mform->addElement('select', $key, get_string($key, 'tool_usertours'), $options); 595 $mform->setDefault($key, configuration::TOURDEFAULT); 596 $mform->addHelpButton($key, $key, 'tool_usertours'); 597 598 return $this; 599 } 600 601 /** 602 * Prepare the configuration data for the moodle form. 603 * 604 * @return object 605 */ 606 public function prepare_data_for_form() { 607 $data = $this->to_record(); 608 foreach (self::get_config_keys() as $key) { 609 $data->$key = $this->get_config($key, configuration::get_step_default_value($key)); 610 } 611 612 if ($this->get_targettype() !== null) { 613 $this->get_target()->prepare_data_for_form($data); 614 } 615 616 return $data; 617 } 618 619 /** 620 * Handle submission of the step editing form. 621 * 622 * @param local\forms\editstep $mform The sumitted form. 623 * @param stdClass $data The submitted data. 624 * @return $this 625 */ 626 public function handle_form_submission(local\forms\editstep &$mform, \stdClass $data) { 627 $this->set_title($data->title); 628 $this->set_content($data->content); 629 $this->set_targettype($data->targettype); 630 631 $this->set_targetvalue($this->get_target()->get_value_from_form($data)); 632 633 foreach (self::get_config_keys() as $key) { 634 if (!$this->get_target()->is_setting_forced($key)) { 635 if (isset($data->$key)) { 636 $value = $data->$key; 637 } else { 638 $value = configuration::TOURDEFAULT; 639 } 640 if ($value === configuration::TOURDEFAULT) { 641 $this->set_config($key, null); 642 } else { 643 $this->set_config($key, $value); 644 } 645 } 646 } 647 648 $this->persist(); 649 650 return $this; 651 } 652 653 /** 654 * Attempt to fetch any matching langstring if the string is in the 655 * format identifier,component. 656 * 657 * @param string $string 658 * @return string 659 */ 660 public static function get_string_from_input($string) { 661 $string = trim($string); 662 663 if (preg_match('|^([a-zA-Z][a-zA-Z0-9\.:/_-]*),([a-zA-Z][a-zA-Z0-9\.:/_-]*)$|', $string, $matches)) { 664 if ($matches[2] === 'moodle') { 665 $matches[2] = 'core'; 666 } 667 668 if (get_string_manager()->string_exists($matches[1], $matches[2])) { 669 $string = get_string($matches[1], $matches[2]); 670 } 671 } 672 673 return $string; 674 } 675 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body