Merge branch 'MDL-72783-master-test' of https://github.com/rezaies/moodle

This commit is contained in:
Andrew Nicols 2022-02-03 15:30:59 +08:00
commit 5b730e1149
29 changed files with 399 additions and 99 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1435,10 +1435,14 @@ const Tour = class {
let drawertop = 0;
if (targetNode.parents('[data-usertour="scroller"]').length) {
drawertop = targetNode.parents('[data-usertour="scroller"]').scrollTop();
background.css({
position: 'fixed'
});
const scrollerElement = targetNode.parents('[data-usertour="scroller"]');
const navigationBuffer = scrollerElement.offset().top;
if (scrollerElement.scrollTop() >= navigationBuffer) {
drawertop = scrollerElement.scrollTop() - navigationBuffer;
background.css({
position: 'fixed'
});
}
}
background.css({

View File

@ -84,13 +84,22 @@ EOF;
// Attempt to determine whether this is the front page.
// This is a special case because the frontpage uses a shortened page path making it difficult to detect exactly.
$isfrontpage = $targetmatch->compare(new \moodle_url('/'), URL_MATCH_BASE);
$isdashboard = $targetmatch->compare(new \moodle_url('/my/'), URL_MATCH_BASE);
$target = $targetmatch->out_as_local_url();
return array_filter($tours, function($tour) use ($isfrontpage, $target) {
if ($isfrontpage && $tour->pathmatch === 'FRONTPAGE') {
return array_filter($tours, function($tour) use ($isfrontpage, $isdashboard, $target) {
if (($isfrontpage || $isdashboard) && $tour->pathmatch === 'FRONTPAGE') {
return true;
}
$pattern = preg_quote($tour->pathmatch, '@');
$pattern = str_replace('%', '.*', $pattern);
if (strpos($pattern, '%') !== false) {
// The URL match format is something like: /my/%.
// We need to find all the URLs which match the first part of the pattern.
$pattern = str_replace('%', '.*', $pattern);
} else {
// The URL match format is something like: /my/courses.php.
// We need to find all the URLs which match with whole pattern.
$pattern .= '$';
}
return !!preg_match("@{$pattern}@", $target);
});
}

View File

@ -24,6 +24,7 @@
namespace tool_usertours;
use core\output\inplace_editable;
use tool_usertours\local\clientside_filter\clientside_filter;
defined('MOODLE_INTERNAL') || die();
@ -51,6 +52,11 @@ class helper {
*/
private static $bootstrapped = false;
/**
* @var string Regex to check any matching lang string.
*/
protected const LANG_STRING_REGEX = '|^([a-zA-Z][a-zA-Z0-9\.:/_-]*),([a-zA-Z][a-zA-Z0-9\.:/_-]*)$|';
/**
* Get the link to edit the step.
*
@ -302,18 +308,19 @@ class helper {
/**
* Render the inplace editable used to edit the tour name.
*
* @param tour $tour The tour to edit.
* @return string
* @param tour $tour The tour to edit.
* @return inplace_editable
*/
public static function render_tourname_inplace_editable(tour $tour) {
return new \core\output\inplace_editable(
public static function render_tourname_inplace_editable(tour $tour): inplace_editable {
$name = format_text(static::get_string_from_input($tour->get_name()), FORMAT_HTML);
return new inplace_editable(
'tool_usertours',
'tourname',
$tour->get_id(),
true,
\html_writer::link(
$tour->get_view_link(),
$tour->get_name()
$name
),
$tour->get_name()
);
@ -322,16 +329,17 @@ class helper {
/**
* Render the inplace editable used to edit the tour description.
*
* @param tour $tour The tour to edit.
* @return string
* @param tour $tour The tour to edit.
* @return inplace_editable
*/
public static function render_tourdescription_inplace_editable(tour $tour) {
return new \core\output\inplace_editable(
public static function render_tourdescription_inplace_editable(tour $tour): inplace_editable {
$description = format_text(static::get_string_from_input($tour->get_description()), FORMAT_HTML);
return new inplace_editable(
'tool_usertours',
'tourdescription',
$tour->get_id(),
true,
$tour->get_description(),
$description,
$tour->get_description()
);
}
@ -339,10 +347,10 @@ class helper {
/**
* Render the inplace editable used to edit the tour enable state.
*
* @param tour $tour The tour to edit.
* @return string
* @param tour $tour The tour to edit.
* @return inplace_editable
*/
public static function render_tourenabled_inplace_editable(tour $tour) {
public static function render_tourenabled_inplace_editable(tour $tour): inplace_editable {
global $OUTPUT;
if ($tour->is_enabled()) {
@ -355,7 +363,7 @@ class helper {
$value = 0;
}
$editable = new \core\output\inplace_editable(
$editable = new inplace_editable(
'tool_usertours',
'tourenabled',
$tour->get_id(),
@ -373,13 +381,13 @@ class helper {
/**
* Render the inplace editable used to edit the step name.
*
* @param step $step The step to edit.
* @return string
* @param step $step The step to edit.
* @return inplace_editable
*/
public static function render_stepname_inplace_editable(step $step) {
$title = format_text(step::get_string_from_input($step->get_title()), FORMAT_HTML);
public static function render_stepname_inplace_editable(step $step): inplace_editable {
$title = format_text(static::get_string_from_input($step->get_title()), FORMAT_HTML);
return new \core\output\inplace_editable(
return new inplace_editable(
'tool_usertours',
'stepname',
$step->get_id(),
@ -585,4 +593,37 @@ class helper {
return $filters;
}
/**
* Attempt to fetch any matching langstring if the content is in the
* format identifier,component.
*
* @param string $content Step's content or Tour's name or Tour's description
* @return string Processed content, any langstring will be converted to translated text
*/
public static function get_string_from_input(string $content): string {
$content = trim($content);
if (preg_match(static::LANG_STRING_REGEX, $content, $matches)) {
if ($matches[2] === 'moodle') {
$matches[2] = 'core';
}
if (get_string_manager()->string_exists($matches[1], $matches[2])) {
$content = get_string($matches[1], $matches[2]);
}
}
return $content;
}
/**
* Check if the given string contains any matching langstring.
*
* @param string $string
* @return bool
*/
public static function is_language_string_from_input(string $string): bool {
return preg_match(static::LANG_STRING_REGEX, $string) == true;
}
}

View File

@ -25,6 +25,7 @@
namespace tool_usertours\local\forms;
use stdClass;
use tool_usertours\helper;
use tool_usertours\step;
defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.');
@ -188,7 +189,7 @@ class editstep extends \moodleform {
public function set_data($data): void {
$data = (object) $data;
if (!isset($data->contenttype)) {
if (!empty($data->content['text']) && step::is_language_string_from_input($data->content['text'])) {
if (!empty($data->content['text']) && helper::is_language_string_from_input($data->content['text'])) {
$data->contenttype = static::CONTENTTYPE_LANGSTRING;
$data->contentlangstring = $data->content['text'];

View File

@ -67,10 +67,12 @@ class edittour extends \moodleform {
$mform->addElement('text', 'name', get_string('name', 'tool_usertours'));
$mform->addRule('name', get_string('required'), 'required', null, 'client');
$mform->setType('name', PARAM_TEXT);
$mform->addHelpButton('name', 'name', 'tool_usertours');
// Admin-only descriptions.
$mform->addElement('textarea', 'description', get_string('description', 'tool_usertours'));
$mform->setType('description', PARAM_RAW);
$mform->addHelpButton('description', 'description', 'tool_usertours');
// Application.
$mform->addElement('text', 'pathmatch', get_string('pathmatch', 'tool_usertours'));

View File

@ -101,7 +101,10 @@ class step_list extends \flexible_table {
$content = file_rewrite_pluginfile_urls($content, 'pluginfile.php', $systemcontext->id,
'tool_usertours', 'stepcontent', $step->get_id());
return format_text(step::get_string_from_input($content), $step->get_contentformat());
$content = helper::get_string_from_input($content);
$content = step::get_step_image_from_input($content);
return format_text($content, $step->get_contentformat());
}
/**

View File

@ -353,7 +353,7 @@ class manager {
global $PAGE;
if ($id) {
$tour = tour::instance($id);
$PAGE->navbar->add($tour->get_name(), $tour->get_edit_link());
$PAGE->navbar->add(helper::get_string_from_input($tour->get_name()), $tour->get_edit_link());
} else {
$tour = new tour();
@ -393,7 +393,8 @@ class manager {
notification::add(get_string('modifyshippedtourwarning', 'tool_usertours'), notification::WARNING);
}
$this->header($tour->get_name());
$tourname = !empty($tour->get_name()) ? helper::get_string_from_input($tour->get_name()) : '';
$this->header($tourname);
$data = $tour->prepare_data_for_form();
// Prepare filter values for the form.
@ -475,12 +476,13 @@ class manager {
protected function view_tour($tourid) {
global $PAGE;
$tour = helper::get_tour($tourid);
$tourname = helper::get_string_from_input($tour->get_name());
$PAGE->navbar->add($tour->get_name(), $tour->get_view_link());
$PAGE->navbar->add($tourname, $tour->get_view_link());
$this->header($tour->get_name());
$this->header($tourname);
echo \html_writer::span(get_string('viewtour_info', 'tool_usertours', [
'tourname' => $tour->get_name(),
'tourname' => $tourname,
'path' => $tour->get_pathmatch(),
]));
echo \html_writer::div(get_string('viewtour_edit', 'tool_usertours', [
@ -728,9 +730,9 @@ class manager {
notification::add(get_string('modifyshippedtourwarning', 'tool_usertours'), notification::WARNING);
}
$PAGE->navbar->add($tour->get_name(), $tour->get_view_link());
$PAGE->navbar->add(helper::get_string_from_input($tour->get_name()), $tour->get_view_link());
if (isset($id)) {
$PAGE->navbar->add($step->get_title(), $step->get_edit_link());
$PAGE->navbar->add(helper::get_string_from_input($step->get_title()), $step->get_edit_link());
} else {
$PAGE->navbar->add(get_string('newstep', 'tool_usertours'), $step->get_edit_link());
}
@ -746,7 +748,7 @@ class manager {
if (empty($id)) {
$this->header(get_string('newstep', 'tool_usertours'));
} else {
$this->header(get_string('editstep', 'tool_usertours', $step->get_title()));
$this->header(get_string('editstep', 'tool_usertours', helper::get_string_from_input($step->get_title())));
}
$form->set_data($step->prepare_data_for_form());
@ -862,6 +864,10 @@ class manager {
// the format filename => version. The version value needs to
// be increased if the tour has been updated.
$shippedtours = [
'40_tour_navigation_dashboard.json' => 1,
'40_tour_navigation_mycourse.json' => 1,
'40_tour_navigation_course_teacher.json' => 1,
'40_tour_navigation_course_student.json' => 1,
];
// These are tours that we used to ship but don't ship any longer.

View File

@ -28,6 +28,7 @@ defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . "/filelib.php");
use tool_usertours\helper;
use tool_usertours\step as stepsource;
/**
@ -67,16 +68,19 @@ class step implements \renderable {
$content = file_rewrite_pluginfile_urls($content, 'pluginfile.php', $systemcontext->id,
'tool_usertours', 'stepcontent', $step->get_id());
$content = helper::get_string_from_input($content);
$content = $step::get_step_image_from_input($content);
$result = (object) [
'stepid' => $step->get_id(),
'title' => external_format_text(
stepsource::get_string_from_input($step->get_title()),
helper::get_string_from_input($step->get_title()),
FORMAT_HTML,
$PAGE->context->id,
'tool_usertours'
)[0],
'content' => external_format_text(
stepsource::get_string_from_input($content),
$content,
$step->get_contentformat(),
$PAGE->context->id,
'tool_usertours'

View File

@ -92,11 +92,6 @@ class step {
*/
protected $dirty = false;
/**
* @var string Regex to check any matching lang string.
*/
protected const LANG_STRING_REGEX = '|^([a-zA-Z][a-zA-Z0-9\.:/_-]*),([a-zA-Z][a-zA-Z0-9\.:/_-]*)$|';
/**
* @var bool $isimporting Whether the step is being imported or not.
*/
@ -801,13 +796,16 @@ class step {
* Attempt to fetch any matching langstring if the string is in the
* format identifier,component.
*
* @deprecated since Moodle 4.0 MDL-72783. Please use helper::get_string_from_input() instead.
* @param string $string
* @return string
*/
public static function get_string_from_input($string) {
debugging('Use of ' . __FUNCTION__ .
'() have been deprecated, please update your code to use helper::get_string_from_input()', DEBUG_DEVELOPER);
$string = trim($string);
if (preg_match(static::LANG_STRING_REGEX, $string, $matches)) {
if (preg_match('|^([a-zA-Z][a-zA-Z0-9\.:/_-]*),([a-zA-Z][a-zA-Z0-9\.:/_-]*)$|', $string, $matches)) {
if ($matches[2] === 'moodle') {
$matches[2] = 'core';
}
@ -821,12 +819,27 @@ class step {
}
/**
* Check if the given string contains any matching langstring.
* Attempt to replace PIXICON placeholder with the correct images for tour step content.
*
* @param string $string Tour step content
* @return bool
* @param string $content Tour content
* @return string Processed tour content
*/
public static function is_language_string_from_input(string $string): bool {
return preg_match(static::LANG_STRING_REGEX, $string) == true;
public static function get_step_image_from_input(string $content): string {
global $OUTPUT;
if (preg_match('/(?<=@@PIXICON::).*?(?=@@)/', $content, $matches)) {
$bits = explode('::', $matches[0]);
$identifier = $bits[0];
$component = $bits[1];
if ($component == 'moodle') {
$component = 'core';
}
$image = \html_writer::img($OUTPUT->image_url($identifier, $component)->out(false),
'', ['class' => 'img-fluid']);
$contenttoreplace = '@@PIXICON::' . $matches[0] . '@@';
$content = str_replace($contenttoreplace, $image, $content);
}
return $content;
}
}

View File

@ -114,11 +114,12 @@ function xmldb_tool_usertours_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2021101300, 'tool', 'usertours');
}
if ($oldversion < 2021101301) {
if ($oldversion < 2021101302) {
// Update shipped tours.
// Normally, we just bump the version numbers because we need to call update_shipped_tours only once.
manager::update_shipped_tours();
upgrade_plugin_savepoint(true, 2021101301, 'tool', 'usertours');
upgrade_plugin_savepoint(true, 2021101302, 'tool', 'usertours');
}
return true;

View File

@ -31,6 +31,9 @@ $string['block_named'] = 'Block named \'{$a}\'';
$string['cachedef_stepdata'] = 'List of user tour steps';
$string['cachedef_tourdata'] = 'List of enabled user tours information which is fetched on every page';
$string['description'] = 'Description';
$string['description_help'] = 'The description of a tour may be added as plain text, enclosed in multilang tags (for use with the multi-language content filter) if required.
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['confirmstepremovalquestion'] = 'Are you sure that you wish to remove this step?';
@ -93,6 +96,9 @@ $string['movestepup'] = 'Move step up';
$string['movetourdown'] = 'Move tour down';
$string['movetourup'] = 'Move tour up';
$string['name'] = 'Name';
$string['name_help'] = 'The name of a tour may be added as plain text, enclosed in multilang tags (for use with the multi-language content filter) if required.
Alternatively, a language string ID may be entered in the format identifier,component (with no brackets or space after the comma).';
$string['newstep'] = 'Create step';
$string['newstep'] = 'New step';
$string['newtour'] = 'Create a new tour';
@ -260,6 +266,28 @@ $string['tour_activityinfo_course_student_content'] = 'Activity dates and/or wha
$string['tour_activityinfo_course_teacher_title'] = 'New: Activity information';
$string['tour_activityinfo_course_teacher_content'] = 'New course settings \'Show completion conditions\' and \'Show activity dates\' enable you to choose whether activity completion conditions (if set) and/or dates are displayed for students on the course page.';
// 4.0 New navigation tour.
$string['tour_navigation_course_announcements_teacher_content'] = '@@PIXICON::tour/tour_course_admin_3::tool_usertours@@<br>Post important news here.';
$string['tour_navigation_course_announcements_teacher_title'] = 'Something to tell everyone?';
$string['tour_navigation_course_edit_teacher_content'] = '@@PIXICON::tour/tour_course_admin_1::tool_usertours@@<br>Add new content or edit existing content.';
$string['tour_navigation_course_edit_teacher_title'] = 'Activate edit mode';
$string['tour_navigation_course_index_student_content'] = '@@PIXICON::tour/tour_course_student::tool_usertours@@<br>Browse through activities and track your progress.';
$string['tour_navigation_course_index_student_title'] = 'Find your way around';
$string['tour_navigation_course_index_teacher_content'] = '@@PIXICON::tour/tour_course_admin_2::tool_usertours@@<br>Drag and drop activities to re-order course content.';
$string['tour_navigation_course_index_teacher_title'] = 'Course index';
$string['tour_navigation_course_student_tour_des'] = 'Where to browse through activities in a course';
$string['tour_navigation_course_student_tour_name'] = 'Course index';
$string['tour_navigation_course_teacher_tour_des'] = 'Edit mode, drag and drop of activities and posting announcements in a course';
$string['tour_navigation_course_teacher_tour_name'] = 'Course editing';
$string['tour_navigation_dashboard_content'] = '@@PIXICON::tour/tour_dashboard::tool_usertours@@<br>This side panel can contain more features.';
$string['tour_navigation_dashboard_title'] = 'Expand to explore!';
$string['tour_navigation_dashboard_tour_des'] = 'Where blocks can be found on the Dashboard';
$string['tour_navigation_dashboard_tour_name'] = 'Block drawer';
$string['tour_navigation_mycourses_content'] = '@@PIXICON::tour/tour_mycourses::tool_usertours@@<br>Add, copy, delete and hide courses from this menu.';
$string['tour_navigation_mycourses_title'] = 'Courses and categories';
$string['tour_navigation_mycourses_tour_des'] = 'Course management options on the My courses page';
$string['tour_navigation_mycourses_tour_name'] = 'Course management';
$string['tour_final_step_title'] = 'End of tour';
$string['tour_final_step_content'] = 'This is the end of your user tour. It won\'t show again unless you reset it using the link in the footer.';

View File

@ -24,15 +24,16 @@
defined('MOODLE_INTERNAL') || die();
use core\output\inplace_editable;
use tool_usertours\helper;
/**
* Manage inplace editable saves.
*
* @param string $itemtype The type of item.
* @param int $itemid The ID of the item.
* @param mixed $newvalue The new value
* @return string
* @param string $itemtype The type of item.
* @param int $itemid The ID of the item.
* @param mixed $newvalue The new value
* @return inplace_editable
*/
function tool_usertours_inplace_editable($itemtype, $itemid, $newvalue) {
$context = \context_system::instance();

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -11,6 +11,11 @@ Feature: Apply content type to a tour
| Description | My first tour |
| Apply to URL match | /my/% |
| Tour is enabled | 1 |
And I add a new user tour with:
| Name | tour_activityinfo_activity_student_title,tool_usertours |
| Description | tour_activityinfo_activity_student_content,tool_usertours |
| Apply to URL match | /my/% |
| Tour is enabled | 0 |
@javascript
Scenario: User can choose the the content type of the tour step
@ -42,6 +47,7 @@ Feature: Apply content type to a tour
And I should see "New: Activity information"
And I should see "New course settings 'Show completion conditions' and 'Show activity dates' enable you to choose whether activity completion conditions (if set) and/or dates are displayed for students on the course page."
And I click on "Edit" "link" in the "New: Activity information" "table_row"
And I should see "Editing \"New: Activity information\""
And the field "Title" matches value "tour_activityinfo_course_teacher_title,tool_usertours"
And the field "Moodle language identifier" matches value "tour_activityinfo_course_teacher_content,tool_usertours"
@ -57,6 +63,20 @@ Feature: Apply content type to a tour
And I should see "New: Activity information"
And I should see "Test content"
And I click on "Edit" "link" in the "New: Activity information" "table_row"
And I should see "Editing \"New: Activity information\""
And I should not see "Moodle language identifier"
And the field "Title" matches value "tour_activityinfo_course_teacher_title,tool_usertours"
And the field "id_content" matches value "<b>Test content</b>"
@javascript
Scenario: Tour name and description can be translatable
Given I open the User tour settings page
And I should see "New: Activity information"
And I should see "Activity dates plus what to do to complete the activity are shown on the activity page."
When I click on "View" "link" in the "New: Activity information" "table_row"
Then I should see "New: Activity information"
And I should see "This is the 'New: Activity information' tour. It applies to the path '/my/%'."
And I click on "edit the tour defaults" "link"
And I should see "New: Activity information"
And the field "Name" matches value "tour_activityinfo_activity_student_title,tool_usertours"
And the field "Description" matches value "tour_activityinfo_activity_student_content,tool_usertours"

View File

@ -164,7 +164,7 @@ class cache_testcase extends advanced_testcase {
'Matches expected glob' => [
$tourconfigs,
'/my/index.php',
['my_glob_1', 'my_glob_2'],
['my_glob_1', 'my_glob_2', 'frontpage_match'],
],
'Matches expected glob and exact' => [
$tourconfigs,

View File

@ -0,0 +1,84 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Tests for helper.
*
* @package tool_usertours
* @copyright 2022 Huong Nguyen <huongnv13@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_usertours;
use advanced_testcase;
defined('MOODLE_INTERNAL') || die();
/**
* Tests for helper.
*
* @package tool_usertours
* @copyright 2022 Huong Nguyen <huongnv13@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class helper_test extends advanced_testcase {
/**
* Data Provider for get_string_from_input.
*
* @return array
*/
public function get_string_from_input_provider(): array {
return [
'Text' => [
'example',
'example',
],
'Text which looks like a langstring' => [
'example,fakecomponent',
'example,fakecomponent',
],
'Text which is a langstring' => [
'administration,core',
'Administration',
],
'Text which is a langstring but uses "moodle" instead of "core"' => [
'administration,moodle',
'Administration',
],
'Text which is a langstring, but with extra whitespace' => [
' administration,moodle ',
'Administration',
],
'Looks like a langstring, but has incorrect space around comma' => [
'administration , moodle',
'administration , moodle',
],
];
}
/**
* Ensure that the get_string_from_input function returns langstring strings correctly.
*
* @dataProvider get_string_from_input_provider
* @param string $string The string to test
* @param string $expected The expected result
*/
public function test_get_string_from_input($string, $expected) {
$this->assertEquals($expected, helper::get_string_from_input($string));
}
}

View File

@ -825,47 +825,24 @@ class step_testcase extends advanced_testcase {
}
/**
* Data Provider for get_string_from_input.
*
* @return array
* Ensure that the get_step_image_from_input function replace PIXICON placeholder with the correct images correctly.
*/
public function get_string_from_input_provider() {
return [
'Text' => [
'example',
'example',
],
'Text which looks like a langstring' => [
'example,fakecomponent',
'example,fakecomponent',
],
'Text which is a langstring' => [
'administration,core',
'Administration',
],
'Text which is a langstring but uses "moodle" instead of "core"' => [
'administration,moodle',
'Administration',
],
'Text which is a langstring, but with extra whitespace' => [
' administration,moodle ',
'Administration',
],
'Looks like a langstring, but has incorrect space around comma' => [
'administration , moodle',
'administration , moodle',
],
];
}
public function test_get_step_image_from_input() {
$stepcontent = '@@PIXICON::tour/tour_mycourses::tool_usertours@@<br>Test';
$stepcontent = \tool_usertours\step::get_step_image_from_input($stepcontent);
/**
* Ensure that the get_string_from_input function returns langstring strings correctly.
*
* @dataProvider get_string_from_input_provider
* @param string $string The string to test
* @param string $expected The expected result
*/
public function test_get_string_from_input($string, $expected) {
$this->assertEquals($expected, \tool_usertours\step::get_string_from_input($string));
// If the format is correct, PIXICON placeholder will be replaced with the img tag.
$this->assertStringStartsWith('<img', $stepcontent);
$this->assertStringEndsWith('Test', $stepcontent);
$this->assertStringNotContainsString('PIXICON', $stepcontent);
$stepcontent = '@@PIXICON::tour/tour_mycourses<br>Test';
$stepcontent = \tool_usertours\step::get_step_image_from_input($stepcontent);
// If the format is not correct, PIXICON placeholder will not be replaced with the img tag.
$this->assertStringStartsNotWith('<img', $stepcontent);
$this->assertStringStartsWith('@@PIXICON', $stepcontent);
$this->assertStringEndsWith('Test', $stepcontent);
$this->assertStringContainsString('PIXICON', $stepcontent);
}
}

View File

@ -0,0 +1,22 @@
{
"name": "tour_navigation_course_student_tour_name,tool_usertours",
"description": "tour_navigation_course_student_tour_des,tool_usertours",
"pathmatch": "\/course\/view.php%",
"enabled": "1",
"sortorder": "3",
"endtourlabel": "",
"configdata": "{\"placement\":\"right\",\"orphan\":\"0\",\"backdrop\":\"1\",\"reflex\":\"0\",\"filtervalues\":{\"accessdate\":{\"filter_accessdate\":\"tool_usertours_accountcreation\",\"filter_accessdate_range\":0,\"filter_accessdate_enabled\":\"0\"},\"category\":[],\"course\":[],\"courseformat\":[],\"role\":[\"student\"],\"theme\":[\"boost\"],\"cssselector\":[]},\"majorupdatetime\":1641972472,\"shipped_tour\":true,\"shipped_filename\":\"40_tour_navigation_course_student.json\",\"shipped_version\":1}",
"displaystepnumbers": true,
"version": "2021101301",
"steps": [
{
"title": "tour_navigation_course_index_student_title,tool_usertours",
"content": "tour_navigation_course_index_student_content,tool_usertours",
"contentformat": "1",
"targettype": "0",
"targetvalue": "#theme_boost-drawers-courseindex .drawercontent",
"sortorder": "0",
"configdata": "{}"
}
]
}

View File

@ -0,0 +1,40 @@
{
"name": "tour_navigation_course_teacher_tour_name,tool_usertours",
"description": "tour_navigation_course_teacher_tour_des,tool_usertours",
"pathmatch": "\/course\/view.php%",
"enabled": "1",
"sortorder": "2",
"endtourlabel": "",
"configdata": "{\"placement\":\"bottom\",\"orphan\":\"0\",\"backdrop\":\"1\",\"reflex\":\"0\",\"filtervalues\":{\"accessdate\":{\"filter_accessdate\":\"tool_usertours_accountcreation\",\"filter_accessdate_range\":0,\"filter_accessdate_enabled\":\"0\"},\"category\":[],\"course\":[],\"courseformat\":[],\"role\":[\"-1\",\"coursecreator\",\"manager\",\"teacher\",\"editingteacher\"],\"theme\":[\"boost\"],\"cssselector\":[]},\"majorupdatetime\":1641972470,\"shipped_tour\":true,\"shipped_filename\":\"40_tour_navigation_course_teacher.json\",\"shipped_version\":1}",
"displaystepnumbers": true,
"version": "2021101301",
"steps": [
{
"title": "tour_navigation_course_edit_teacher_title,tool_usertours",
"content": "tour_navigation_course_edit_teacher_content,tool_usertours",
"contentformat": "1",
"targettype": "0",
"targetvalue": "form.editmode-switch-form",
"sortorder": "0",
"configdata": "{}"
},
{
"title": "tour_navigation_course_index_teacher_title,tool_usertours",
"content": "tour_navigation_course_index_teacher_content,tool_usertours",
"contentformat": "1",
"targettype": "0",
"targetvalue": "#theme_boost-drawers-courseindex .drawercontent",
"sortorder": "1",
"configdata": "{\"placement\":\"right\"}"
},
{
"title": "tour_navigation_course_announcements_teacher_title,tool_usertours",
"content": "tour_navigation_course_announcements_teacher_content,tool_usertours",
"contentformat": "1",
"targettype": "0",
"targetvalue": ".course-content .course-content-item-content .activity-item[data-activityname=\"Announcements\"]",
"sortorder": "2",
"configdata": "{\"placement\":\"left\"}"
}
]
}

View File

@ -0,0 +1,22 @@
{
"name": "tour_navigation_dashboard_tour_name,tool_usertours",
"description": "tour_navigation_dashboard_tour_des,tool_usertours",
"pathmatch": "FRONTPAGE",
"enabled": "1",
"sortorder": "0",
"endtourlabel": "",
"configdata": "{\"placement\":\"left\",\"orphan\":\"0\",\"backdrop\":\"1\",\"reflex\":\"0\",\"filtervalues\":{\"accessdate\":{\"filter_accessdate\":\"tool_usertours_accountcreation\",\"filter_accessdate_range\":0,\"filter_accessdate_enabled\":\"0\"},\"category\":[],\"course\":[],\"courseformat\":[],\"role\":[],\"theme\":[\"boost\"],\"cssselector\":[]},\"majorupdatetime\":1641972465,\"shipped_tour\":true,\"shipped_filename\":\"40_tour_navigation_dashboard.json\",\"shipped_version\":1}",
"displaystepnumbers": true,
"version": "2021101301",
"steps": [
{
"title": "tour_navigation_dashboard_title,tool_usertours",
"content": "tour_navigation_dashboard_content,tool_usertours",
"contentformat": "1",
"targettype": "0",
"targetvalue": ".drawer-toggles .drawer-toggler.drawer-right-toggle",
"sortorder": "0",
"configdata": "{\"placement\":\"left\"}"
}
]
}

View File

@ -0,0 +1,22 @@
{
"name": "tour_navigation_mycourses_tour_name,tool_usertours",
"description": "tour_navigation_mycourses_tour_des,tool_usertours",
"pathmatch": "\/my\/courses.php",
"enabled": "1",
"sortorder": "1",
"endtourlabel": "I understand",
"configdata": "{\"placement\":\"bottom\",\"orphan\":\"0\",\"backdrop\":\"1\",\"reflex\":\"0\",\"filtervalues\":{\"accessdate\":{\"filter_accessdate\":\"tool_usertours_accountcreation\",\"filter_accessdate_range\":0,\"filter_accessdate_enabled\":\"0\"},\"category\":[],\"course\":[],\"courseformat\":[],\"role\":[],\"theme\":[\"boost\"],\"cssselector\":[]},\"majorupdatetime\":1641972468,\"shipped_tour\":true,\"shipped_filename\":\"40_tour_navigation_mycourse.json\",\"shipped_version\":1}",
"displaystepnumbers": true,
"version": "2021101301",
"steps": [
{
"title": "tour_navigation_mycourses_title,tool_usertours",
"content": "tour_navigation_mycourses_content,tool_usertours",
"contentformat": "1",
"targettype": "0",
"targetvalue": ".header-actions-container .btn-group",
"sortorder": "0",
"configdata": "{}"
}
]
}

View File

@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2021101301; // The current module version (Date: YYYYMMDDXX).
$plugin->version = 2021101302; // The current module version (Date: YYYYMMDDXX).
$plugin->requires = 2021052500; // Requires this Moodle version.
$plugin->component = 'tool_usertours'; // Full name of the plugin (used for diagnostics).