MDL-80871 tool_usertours: Allow tours to ignore completion

The use-case here is for tours which must be shown on every page load.

The tour still needs to be ended for the current page, but should be
shown again on the next time the page is loaded.
This commit is contained in:
Andrew Nicols 2024-02-09 11:47:42 +08:00
parent 4d992e8cae
commit 43e2e62be4
No known key found for this signature in database
GPG Key ID: 6D1E3157C8CFBF14
8 changed files with 116 additions and 7 deletions

View File

@ -189,6 +189,7 @@ class tour extends external_api {
self::validate_context($context);
$tour = tourinstance::instance($params['tourid']);
$tour->mark_user_completed();
\tool_usertours\event\tour_ended::create([

View File

@ -21,9 +21,9 @@ use core\output\inplace_editable;
/**
* Tour helper.
*
* @package tool_usertours
* @copyright 2016 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @package tool_usertours
*/
class helper {
/**

View File

@ -29,6 +29,7 @@ defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.');
require_once($CFG->libdir . '/formslib.php');
use tool_usertours\helper;
use tool_usertours\tour;
/**
* Form for editing tours.
@ -88,6 +89,17 @@ class edittour extends \moodleform {
$mform->addElement('checkbox', 'displaystepnumbers', get_string('displaystepnumbers', 'tool_usertours'));
$mform->addHelpButton('displaystepnumbers', 'displaystepnumbers', 'tool_usertours');
$mform->addElement(
'select',
'showtourwhen',
get_string('showtourwhen', 'tool_usertours'),
[
tour::SHOW_TOUR_UNTIL_COMPLETE => get_string('showtouruntilcomplete', 'tool_usertours'),
tour::SHOW_TOUR_ON_EACH_PAGE_VISIT => get_string('showtoureachtime', 'tool_usertours'),
]
);
$mform->setDefault('showtourwhen', tour::SHOW_TOUR_UNTIL_COMPLETE);
// Configuration.
$this->tour->add_config_to_form($mform);

View File

@ -363,6 +363,7 @@ class manager {
$tour->set_enabled(!empty($data->enabled));
$tour->set_endtourlabel($data->endtourlabel);
$tour->set_display_step_numbers(!empty($data->displaystepnumbers));
$tour->set_showtourwhen($data->showtourwhen);
foreach (configuration::get_defaultable_keys() as $key) {
$tour->set_config($key, $data->$key);

View File

@ -52,6 +52,12 @@ class tour {
*/
const TOUR_REQUESTED_BY_USER = 'tool_usertours_tour_reset_time_';
/** @var int Whether to show the tour only until it has been marked complete */
const SHOW_TOUR_UNTIL_COMPLETE = 1;
/** @var int Whether to show the tour every time a page matches */
const SHOW_TOUR_ON_EACH_PAGE_VISIT = 2;
/**
* @var $id The tour ID.
*/
@ -641,6 +647,11 @@ class tour {
return false;
}
if ($this->get_showtourwhen() === self::SHOW_TOUR_ON_EACH_PAGE_VISIT) {
// The tour should be shown on every page visit.
return true;
}
if ($tourcompletiondate = get_user_preferences(self::TOUR_LAST_COMPLETED_BY_USER . $this->get_id(), null)) {
if ($tourresetdate = get_user_preferences(self::TOUR_REQUESTED_BY_USER . $this->get_id(), null)) {
if ($tourresetdate >= $tourcompletiondate) {
@ -763,6 +774,7 @@ class tour {
*/
public function prepare_data_for_form() {
$data = $this->to_record();
$data->showtourwhen = $this->get_showtourwhen();
foreach (configuration::get_defaultable_keys() as $key) {
$data->$key = $this->get_config($key, configuration::get_default_value($key));
}
@ -860,4 +872,29 @@ class tour {
public function get_display_step_numbers(): bool {
return $this->displaystepnumbers;
}
/**
* Set the value for the when to show the tour.
*
* @see self::SHOW_TOUR_UNTIL_COMPLETE
* @see self::SHOW_TOUR_ON_EACH_PAGE_VISIT
*
* @param int $value
* @return self
*/
public function set_showtourwhen(int $value): tour {
return $this->set_config('showtourwhen', $value);
}
/**
* When to show the tour.
*
* @see self::SHOW_TOUR_UNTIL_COMPLETE
* @see self::SHOW_TOUR_ON_EACH_PAGE_VISIT
*
* @return int
*/
public function get_showtourwhen(): int {
return $this->get_config('showtourwhen', self::SHOW_TOUR_UNTIL_COMPLETE);
}
}

View File

@ -36,6 +36,9 @@ $string['description_help'] = 'The description of a tour may be added as plain t
Alternatively, a language string ID may be entered in the format identifier,component (with no brackets or space after the comma).';
$string['displaystepnumbers'] = 'Display step numbers';
$string['displaystepnumbers_help'] = 'Whether to display a step number count e.g. 1/4, 2/4 etc. to indicate the length of the user tour.';
$string['showtourwhen'] = 'Show tour';
$string['showtoureachtime'] = 'each time a filter matches it';
$string['showtouruntilcomplete'] = 'until it has been closed';
$string['confirmstepremovalquestion'] = 'Are you sure that you wish to remove this step?';
$string['confirmstepremovaltitle'] = 'Confirm step removal';
$string['confirmtourremovalquestion'] = 'Are you sure that you wish to remove this tour?';

View File

@ -0,0 +1,29 @@
@tool @tool_usertours
Feature: Prevent yours from being marked as complete
In order to impart key information
As an administrator
I can prevent a user tour from being marked as complete
Background:
Given I log in as "admin"
And I add a new user tour with:
| Name | First tour |
| Description | My first tour |
| Apply to URL match | FRONTPAGE |
| Tour is enabled | 1 |
| Show with backdrop | 1 |
# 2 = tour::SHOW_TOUR_ON_EACH_PAGE_VISIT
| Show tour | 2 |
And I add steps to the "First tour" tour:
| targettype | Title | id_content | Content type |
| Display in middle of page | Welcome | Welcome tour. | Manual |
@javascript
Scenario: Ending the tour should not mark it as complete
# Changing the window viewport to mobile so we will have the footer section.
Given I am on site homepage
And I should see "Welcome"
And I press "Got it"
And I should not see "Welcome"
When I am on site homepage
Then I should see "Welcome"

View File

@ -98,6 +98,10 @@ class tour_test extends \advanced_testcase {
'config',
['key', 'value'],
],
'showtourwhen' => [
'showtourwhen',
[0],
],
];
}
@ -598,30 +602,44 @@ class tour_test extends \advanced_testcase {
null,
null,
null,
[],
true,
],
'Completed by user before majorupdatetime' => [
$time - DAYSECS,
null,
$time,
[],
true,
],
'Completed by user since majorupdatetime' => [
$time,
null,
$time - DAYSECS,
[],
false,
],
'Requested by user before current completion' => [
$time,
$time - DAYSECS,
null,
$time - MINSECS,
[],
false,
],
'Requested by user since completion' => [
$time - DAYSECS,
$time,
'null',
[],
true,
],
'Tour will show on each load' => [
$time,
$time - DAYSECS,
null,
[
'showtourwhen' => tour::SHOW_TOUR_ON_EACH_PAGE_VISIT,
],
true,
],
];
@ -634,9 +652,16 @@ class tour_test extends \advanced_testcase {
* @param mixed $completiondate The user's completion date for this tour
* @param mixed $requesteddate The user's last requested date for this tour
* @param mixed $updateddate The date this tour was last updated
* @param mixed $config The tour config to apply
* @param string $expectation The expected tour key
*/
public function test_should_show_for_user($completiondate, $requesteddate, $updateddate, $expectation): void {
public function test_should_show_for_user(
$completiondate,
$requesteddate,
$updateddate,
$config,
$expectation,
): void {
// Uses user preferences so we must be in a user context.
$this->resetAfterTest();
$this->setAdminUser();
@ -644,7 +669,6 @@ class tour_test extends \advanced_testcase {
$tour = $this->getMockBuilder(tour::class)
->onlyMethods([
'get_id',
'get_config',
'is_enabled',
])
->getMock();
@ -652,6 +676,10 @@ class tour_test extends \advanced_testcase {
$tour->method('is_enabled')
->willReturn(true);
foreach ($config as $key => $value) {
$tour->set_config($key, $value);
}
$id = rand(1, 100);
$tour->method('get_id')
->willReturn($id);
@ -665,9 +693,7 @@ class tour_test extends \advanced_testcase {
}
if ($updateddate !== null) {
$tour->expects($this->once())
->method('get_config')
->willReturn($updateddate);
$tour->set_config('majorupdatetime', $updateddate);
}
$this->assertEquals($expectation, $tour->should_show_for_user());