From 3f9035b989283063306271daf504a22709a92af0 Mon Sep 17 00:00:00 2001 From: Huong Nguyen Date: Wed, 21 Apr 2021 14:32:40 +0700 Subject: [PATCH] MDL-71252 completion: Avoid showing the 'Mark as done' button The following activites will be applied: - Label - File (Force download/Open/In pop-up) - URL (Open/In pop-up) --- .../classes/activity_custom_completion.php | 11 +++ completion/classes/cm_completion_details.php | 38 +++++++-- completion/tests/behat/behat_completion.php | 26 ++++++ .../classes/output/activity_information.php | 1 + course/templates/activity_info.mustache | 5 +- .../behat/assign_activity_completion.feature | 63 ++++++++++++++ .../classes/completion/custom_completion.php | 73 +++++++++++++++++ .../behat/label_activity_completion.feature | 45 ++++++++++ .../behat/page_activity_completion.feature | 20 +++++ .../classes/completion/custom_completion.php | 82 +++++++++++++++++++ mod/resource/lib.php | 7 +- .../resource_activity_completion.feature | 60 ++++++++++++++ .../classes/completion/custom_completion.php | 82 +++++++++++++++++++ mod/url/lib.php | 2 + .../behat/url_activity_completion.feature | 34 ++++++++ 15 files changed, 539 insertions(+), 10 deletions(-) create mode 100644 mod/assign/tests/behat/assign_activity_completion.feature create mode 100644 mod/label/classes/completion/custom_completion.php create mode 100644 mod/label/tests/behat/label_activity_completion.feature create mode 100644 mod/resource/classes/completion/custom_completion.php create mode 100644 mod/resource/tests/behat/resource_activity_completion.feature create mode 100644 mod/url/classes/completion/custom_completion.php diff --git a/completion/classes/activity_custom_completion.php b/completion/classes/activity_custom_completion.php index 2ac83dd11ad..f401ceb15d5 100644 --- a/completion/classes/activity_custom_completion.php +++ b/completion/classes/activity_custom_completion.php @@ -138,6 +138,17 @@ abstract class activity_custom_completion { return $descriptions[$rule]; } + /** + * Show the manual completion or not regardless of the course's showcompletionconditions setting. + * Returns false by default for plugins that don't need to override the course's showcompletionconditions setting. + * Activity plugins that need to always show manual completion need to override this function. + * + * @return bool + */ + public function manual_completion_always_shown(): bool { + return false; + } + /** * Fetches the module's custom completion class implementation if it's available. * diff --git a/completion/classes/cm_completion_details.php b/completion/classes/cm_completion_details.php index 3354eb8ec69..11b9fb3888c 100644 --- a/completion/classes/cm_completion_details.php +++ b/completion/classes/cm_completion_details.php @@ -49,6 +49,9 @@ class cm_completion_details { /** @var bool Whether to return automatic completion details. */ protected $returndetails = true; + /** @var activity_custom_completion Activity custom completion object. */ + protected $cmcompletion = null; + /** * Constructor. * @@ -62,6 +65,10 @@ class cm_completion_details { $this->cminfo = $cminfo; $this->userid = $userid; $this->returndetails = $returndetails; + $cmcompletionclass = activity_custom_completion::get_cm_completion_class($this->cminfo->modname); + if ($cmcompletionclass) { + $this->cmcompletion = new $cmcompletionclass($this->cminfo, $this->userid); + } } /** @@ -116,16 +123,12 @@ class cm_completion_details { ]; } - // Check if this activity has custom_completion class implemented. - $cmcompletionclass = activity_custom_completion::get_cm_completion_class($this->cminfo->modname); - if ($cmcompletionclass) { + if ($this->cmcompletion) { if (isset($completiondata->customcompletion)) { - /** @var activity_custom_completion $cmcompletion */ - $cmcompletion = new $cmcompletionclass($this->cminfo, $this->userid); foreach ($completiondata->customcompletion as $rule => $status) { $details[$rule] = (object)[ 'status' => !$hasoverride ? $status : $completiondata->completionstate, - 'description' => $cmcompletion->get_custom_rule_description($rule), + 'description' => $this->cmcompletion->get_custom_rule_description($rule), ]; } } @@ -193,6 +196,29 @@ class cm_completion_details { return $this->completioninfo->is_tracked_user($this->userid); } + /** + * Determine whether to show the manual completion or not. + * + * @return bool + */ + public function show_manual_completion(): bool { + global $PAGE; + + if ($PAGE->context->contextlevel == CONTEXT_MODULE) { + // Manual completion should always be shown on the activity page. + return true; + } else { + $course = $this->cminfo->get_course(); + if ($course->showcompletionconditions == COMPLETION_SHOW_CONDITIONS) { + return true; + } else if ($this->cmcompletion) { + return $this->cmcompletion->manual_completion_always_shown(); + } + } + + return false; + } + /** * Generates an instance of this class. * diff --git a/completion/tests/behat/behat_completion.php b/completion/tests/behat/behat_completion.php index 7ebe22a9a37..4d78021b8d8 100644 --- a/completion/tests/behat/behat_completion.php +++ b/completion/tests/behat/behat_completion.php @@ -295,6 +295,32 @@ class behat_completion extends behat_base { $this->execute("behat_general::the_element_should_be_disabled", $params); } + /** + * Check that the manual completion button for the activity does not exist. + * + * @Given /^the manual completion button for "(?P(?:[^"]|\\")*)" should not exist/ + * @param string $activityname The activity name. + */ + public function the_manual_completion_button_for_activity_should_not_exist(string $activityname): void { + $selector = "div[data-activityname='$activityname'] button"; + + $params = [$selector, "css_element"]; + $this->execute('behat_general::should_not_exist', $params); + } + + /** + * Check that the manual completion button for the activity exists. + * + * @Given /^the manual completion button for "(?P(?:[^"]|\\")*)" should exist/ + * @param string $activityname The activity name. + */ + public function the_manual_completion_button_for_activity_should_exist(string $activityname): void { + $selector = "div[data-activityname='$activityname'] button"; + + $params = [$selector, "css_element"]; + $this->execute('behat_general::should_exist', $params); + } + /** * Check that the activity has the given automatic completion condition. * diff --git a/course/classes/output/activity_information.php b/course/classes/output/activity_information.php index 03e9d423c6e..deaa39c2a2d 100644 --- a/course/classes/output/activity_information.php +++ b/course/classes/output/activity_information.php @@ -98,6 +98,7 @@ class activity_information implements renderable, templatable { $data->hascompletion = $this->cmcompletion->has_completion(); $data->isautomatic = $this->cmcompletion->is_automatic(); + $data->showmanualcompletion = $this->cmcompletion->show_manual_completion(); // Get the name of the user overriding the completion condition, if available. $data->overrideby = null; diff --git a/course/templates/activity_info.mustache b/course/templates/activity_info.mustache index ac7ef27065f..f415d2a4cf6 100644 --- a/course/templates/activity_info.mustache +++ b/course/templates/activity_info.mustache @@ -30,6 +30,7 @@ "hasdates": true, "isautomatic": true, "istrackeduser": true, + "showmanualcompletion": true, "activitydates": [ { "label": "Opens:", @@ -67,7 +68,9 @@ {{/isautomatic}} {{^isautomatic}} - {{> core_course/completion_manual }} + {{#showmanualcompletion}} + {{> core_course/completion_manual }} + {{/showmanualcompletion}} {{/isautomatic}} {{/uservisible}} diff --git a/mod/assign/tests/behat/assign_activity_completion.feature b/mod/assign/tests/behat/assign_activity_completion.feature new file mode 100644 index 00000000000..acaf766774a --- /dev/null +++ b/mod/assign/tests/behat/assign_activity_completion.feature @@ -0,0 +1,63 @@ +@mod @mod_assign @core_completion +Feature: View activity completion information in the Assign resource + In order to have visibility of assign completion requirements + As a student + I need to be able to view my assign completion progress + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | student1 | Vinnie | Student1 | student1@example.com | + | teacher1 | Darrell | Teacher1 | teacher1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | teacher1 | C1 | editingteacher | + And I log in as "teacher1" + + @javascript + Scenario: The manual completion button will be shown on the course page if the Show completion conditions is set to Yes + Given I am on "Course 1" course homepage with editing mode on + And I navigate to "Edit settings" in current page administration + And I expand all fieldsets + And I set the following fields to these values: + | Enable completion tracking | Yes | + | Show completion conditions | Yes | + And I press "Save and display" + And I add a "Assignment" to section "1" and I fill the form with: + | Assignment name | History of ants | + | Completion tracking | Students can manually mark the activity as completed | + # Teacher view. + And the manual completion button for "History of ants" should exist + And the manual completion button for "History of ants" should be disabled + And I log out + # Student view. + When I log in as "student1" + And I am on "Course 1" course homepage + Then the manual completion button for "History of ants" should exist + And the manual completion button of "History of ants" is displayed as "Mark as done" + And I toggle the manual completion state of "History of ants" + And the manual completion button of "History of ants" is displayed as "Done" + + @javascript + Scenario: The manual completion button will not be shown on the course page if the Show completion conditions is set to No + Given I am on "Course 1" course homepage with editing mode on + And I navigate to "Edit settings" in current page administration + And I expand all fieldsets + And I set the following fields to these values: + | Enable completion tracking | Yes | + | Show completion conditions | No | + And I press "Save and display" + And I add a "Assignment" to section "1" and I fill the form with: + | Assignment name | History of ants | + | Completion tracking | Students can manually mark the activity as completed | + # Teacher view. + And the manual completion button for "History of ants" should not exist + And I log out + # Student view. + When I log in as "student1" + And I am on "Course 1" course homepage + Then the manual completion button for "History of ants" should not exist diff --git a/mod/label/classes/completion/custom_completion.php b/mod/label/classes/completion/custom_completion.php new file mode 100644 index 00000000000..b6c7546b06d --- /dev/null +++ b/mod/label/classes/completion/custom_completion.php @@ -0,0 +1,73 @@ +. + +declare(strict_types=1); + +namespace mod_label\completion; + +use core_completion\activity_custom_completion; + +/** + * Activity custom completion subclass for the label. + * + * Class for defining mod_label's custom completion rules and fetching the completion statuses + * of the custom completion rules for a given label instance and a user. + * + * @package mod_label + * @copyright 2021 Huong Nguyen + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class custom_completion extends activity_custom_completion { + + /** + * Fetches the completion state for a given completion rule. + * + * @param string $rule The completion rule. + * @return int The completion state. + */ + public function get_state(string $rule): int { + return COMPLETION_UNKNOWN; + } + + /** + * Fetch the list of custom completion rules that this module defines. + * + * @return array + */ + public static function get_defined_custom_rules(): array { + // This activity/resource do not have any custom rules. + return []; + } + + /** + * Returns an associative array of the descriptions of custom completion rules. + * + * @return array + */ + public function get_custom_rule_descriptions(): array { + // This activity/resource do not have any custom rule descriptions. + return []; + } + + /** + * Show the manual completion or not regardless of the course's showcompletionconditions setting. + * + * @return bool + */ + public function manual_completion_always_shown(): bool { + return true; + } +} diff --git a/mod/label/tests/behat/label_activity_completion.feature b/mod/label/tests/behat/label_activity_completion.feature new file mode 100644 index 00000000000..c501bc86a31 --- /dev/null +++ b/mod/label/tests/behat/label_activity_completion.feature @@ -0,0 +1,45 @@ +@mod @mod_label @core_completion +Feature: View activity completion information for the label + In order to have visibility of Label completion requirements + As a student + I need to be able to view my Label completion progress + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | student1 | Vinnie | Student1 | student1@example.com | + | teacher1 | Darrell | Teacher1 | teacher1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | teacher1 | C1 | editingteacher | + And I log in as "teacher1" + And I am on "Course 1" course homepage + And I navigate to "Edit settings" in current page administration + And I expand all fieldsets + And I set the following fields to these values: + | Enable completion tracking | Yes | + | Show completion conditions | No | + And I press "Save and display" + + @javascript + Scenario: The manual completion button will be shown on the course page if the Show completion conditions is set to No + Given I am on "Course 1" course homepage with editing mode on + When I add a "label" to section "1" and I fill the form with: + | Label text | Swanky label | + | Availability | Show on course page | + | Completion tracking | Students can manually mark the activity as completed | + # Teacher view. + And the manual completion button for "Swanky label" should exist + And the manual completion button for "Swanky label" should be disabled + And I log out + # Student view. + When I log in as "student1" + And I am on "Course 1" course homepage + Then the manual completion button for "Swanky label" should exist + And the manual completion button of "Swanky label" is displayed as "Mark as done" + And I toggle the manual completion state of "Swanky label" + And the manual completion button of "Swanky label" is displayed as "Done" diff --git a/mod/page/tests/behat/page_activity_completion.feature b/mod/page/tests/behat/page_activity_completion.feature index 7fbc179d647..14e207148f0 100644 --- a/mod/page/tests/behat/page_activity_completion.feature +++ b/mod/page/tests/behat/page_activity_completion.feature @@ -60,3 +60,23 @@ Feature: View activity completion information in the Page resource Then the manual completion button of "Music history" is displayed as "Mark as done" And I toggle the manual completion state of "Music history" And the manual completion button of "Music history" is displayed as "Done" + + Scenario: The manual completion button will not be shown on the course page if the Show completion conditions is set to No + Given I am on "Course 1" course homepage with editing mode on + And I navigate to "Edit settings" in current page administration + And I expand all fieldsets + And I set the following fields to these values: + | Enable completion tracking | Yes | + | Show completion conditions | No | + And I press "Save and display" + And I add a "Page" to section "1" and I fill the form with: + | Name | Music history | + | Page content | A lesson learned in life | + | Completion tracking | Students can manually mark the activity as completed | + # Teacher view. + And the manual completion button for "Music history" should not exist + And I log out + # Student view. + When I log in as "student1" + And I am on "Course 1" course homepage + Then the manual completion button for "Music history" should not exist diff --git a/mod/resource/classes/completion/custom_completion.php b/mod/resource/classes/completion/custom_completion.php new file mode 100644 index 00000000000..504d13ef99c --- /dev/null +++ b/mod/resource/classes/completion/custom_completion.php @@ -0,0 +1,82 @@ +. + +declare(strict_types=1); + +namespace mod_resource\completion; + +use core_completion\activity_custom_completion; + +/** + * Activity custom completion subclass for the resource. + * + * Class for defining mod_resource's custom completion rules and fetching the completion statuses + * of the custom completion rules for a given resource instance and a user. + * + * @package mod_resource + * @copyright 2021 Huong Nguyen + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class custom_completion extends activity_custom_completion { + + /** + * Fetches the completion state for a given completion rule. + * + * @param string $rule The completion rule. + * @return int The completion state. + */ + public function get_state(string $rule): int { + return COMPLETION_UNKNOWN; + } + + /** + * Fetch the list of custom completion rules that this module defines. + * + * @return array + */ + public static function get_defined_custom_rules(): array { + // This activity/resource do not have any custom rules. + return []; + } + + /** + * Returns an associative array of the descriptions of custom completion rules. + * + * @return array + */ + public function get_custom_rule_descriptions(): array { + // This activity/resource do not have any custom rule descriptions. + return []; + } + + /** + * Show the manual completion or not regardless of the course's showcompletionconditions setting. + * + * @return bool + */ + public function manual_completion_always_shown(): bool { + $display = $this->cm->customdata['display'] ?? null; + + $displaytypes = [ + RESOURCELIB_DISPLAY_NEW, + RESOURCELIB_DISPLAY_OPEN, + RESOURCELIB_DISPLAY_DOWNLOAD, + RESOURCELIB_DISPLAY_POPUP + ]; + + return in_array($display, $displaytypes); + } +} diff --git a/mod/resource/lib.php b/mod/resource/lib.php index ac53899a58c..f7d387911b0 100644 --- a/mod/resource/lib.php +++ b/mod/resource/lib.php @@ -252,10 +252,11 @@ function resource_get_coursemodule_info($coursemodule) { if (($filedetails = resource_get_file_details($resource, $coursemodule)) && empty($filedetails['isref'])) { $displayoptions = @unserialize($resource->displayoptions); $displayoptions['filedetails'] = $filedetails; - $info->customdata = serialize($displayoptions); + $info->customdata['displayoptions'] = serialize($displayoptions); } else { - $info->customdata = $resource->displayoptions; + $info->customdata['displayoptions'] = $resource->displayoptions; } + $info->customdata['display'] = $display; return $info; } @@ -270,7 +271,7 @@ function resource_cm_info_view(cm_info $cm) { global $CFG; require_once($CFG->dirroot . '/mod/resource/locallib.php'); - $resource = (object)array('displayoptions' => $cm->customdata); + $resource = (object) ['displayoptions' => $cm->customdata['displayoptions']]; $details = resource_get_optional_details($resource, $cm); if ($details) { $cm->set_after_link(' ' . html_writer::tag('span', $details, diff --git a/mod/resource/tests/behat/resource_activity_completion.feature b/mod/resource/tests/behat/resource_activity_completion.feature new file mode 100644 index 00000000000..1bf7fa870bc --- /dev/null +++ b/mod/resource/tests/behat/resource_activity_completion.feature @@ -0,0 +1,60 @@ +@mod @mod_resource @core_completion @_file_upload +Feature: View activity completion information for the resource + In order to have visibility of Resource completion requirements + As a student + I need to be able to view my Resource completion progress + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | student1 | Vinnie | Student1 | student1@example.com | + | teacher1 | Darrell | Teacher1 | teacher1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | teacher1 | C1 | editingteacher | + And the following config values are set as admin: + | displayoptions | 0,1,2,3,4,5,6 | resource | + And I log in as "teacher1" + And I am on "Course 1" course homepage + And I navigate to "Edit settings" in current page administration + And I expand all fieldsets + And I set the following fields to these values: + | Enable completion tracking | Yes | + | Show completion conditions | No | + And I press "Save and display" + + @javascript + Scenario Outline: The manual completion button will be shown on the course page for Open, In pop-up, New window and Force download display mode if the Show completion conditions is set to No + Given I am on "Course 1" course homepage with editing mode on + And I add a "File" to section "1" + And I set the following fields to these values: + | Name | Myfile | + | id_display | | + | Show size | 0 | + | Show type | 0 | + | Show upload/modified date | 0 | + | Completion tracking | Students can manually mark the activity as completed | + And I upload "mod/resource/tests/fixtures/samplefile.txt" file to "Select files" filemanager + And I press "Save and return to course" + # Teacher view. + And the manual completion button for "Myfile" should exist + And the manual completion button for "Myfile" should be disabled + And I log out + # Student view. + When I log in as "student1" + And I am on "Course 1" course homepage + Then the manual completion button for "Myfile" should exist + And the manual completion button of "Myfile" is displayed as "Mark as done" + And I toggle the manual completion state of "Myfile" + And the manual completion button of "Myfile" is displayed as "Done" + + Examples: + | display | + | Open | + | In pop-up | + | Force download | + | New window | diff --git a/mod/url/classes/completion/custom_completion.php b/mod/url/classes/completion/custom_completion.php new file mode 100644 index 00000000000..84c02278df5 --- /dev/null +++ b/mod/url/classes/completion/custom_completion.php @@ -0,0 +1,82 @@ +. + +declare(strict_types=1); + +namespace mod_url\completion; + +use core_completion\activity_custom_completion; + +/** + * Activity custom completion subclass for the url resource. + * + * Class for defining mod_url's custom completion rules and fetching the completion statuses + * of the custom completion rules for a given url instance and a user. + * + * @package mod_url + * @copyright 2021 Huong Nguyen + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class custom_completion extends activity_custom_completion { + + /** + * Fetches the completion state for a given completion rule. + * + * @param string $rule The completion rule. + * @return int The completion state. + */ + public function get_state(string $rule): int { + return COMPLETION_UNKNOWN; + } + + /** + * Fetch the list of custom completion rules that this module defines. + * + * @return array + */ + public static function get_defined_custom_rules(): array { + // This activity/resource do not have any custom rules. + return []; + } + + /** + * Returns an associative array of the descriptions of custom completion rules. + * + * @return array + */ + public function get_custom_rule_descriptions(): array { + // This activity/resource do not have any custom rule descriptions. + return []; + } + + /** + * Show the manual completion or not regardless of the course's showcompletionconditions setting. + * + * @return bool + */ + public function manual_completion_always_shown(): bool { + $display = $this->cm->customdata['display'] ?? null; + + $displaytypes = [ + RESOURCELIB_DISPLAY_NEW, + RESOURCELIB_DISPLAY_OPEN, + RESOURCELIB_DISPLAY_POPUP + ]; + + return in_array($display, $displaytypes); + } + +} diff --git a/mod/url/lib.php b/mod/url/lib.php index b8050297f9b..2ef5f3385dc 100644 --- a/mod/url/lib.php +++ b/mod/url/lib.php @@ -243,6 +243,8 @@ function url_get_coursemodule_info($coursemodule) { $info->content = format_module_intro('url', $url, $coursemodule->id, false); } + $info->customdata['display'] = $display; + return $info; } diff --git a/mod/url/tests/behat/url_activity_completion.feature b/mod/url/tests/behat/url_activity_completion.feature index 79a33ae64fc..c6f9ea2ab84 100644 --- a/mod/url/tests/behat/url_activity_completion.feature +++ b/mod/url/tests/behat/url_activity_completion.feature @@ -16,6 +16,8 @@ Feature: View activity completion information in the URL resource | user | course | role | | student1 | C1 | student | | teacher1 | C1 | editingteacher | + And the following config values are set as admin: + | displayoptions | 0,1,2,3,4,5,6 | url | And I log in as "teacher1" And I am on "Course 1" course homepage And I navigate to "Edit settings" in current page administration @@ -116,3 +118,35 @@ Feature: View activity completion information in the URL resource Then the manual completion button of "Music history" is displayed as "Mark as done" And I toggle the manual completion state of "Music history" And the manual completion button of "Music history" is displayed as "Done" + + @javascript + Scenario Outline: The manual completion button will be shown on the course page for Open, In pop-up and New window display mode if the Show completion conditions is set to No + Given I am on "Course 1" course homepage with editing mode on + And I navigate to "Edit settings" in current page administration + And I expand all fieldsets + And I set the following fields to these values: + | Enable completion tracking | Yes | + | Show completion conditions | No | + And I press "Save and display" + And I add a "URL" to section "1" and I fill the form with: + | Name | Music history | + | External URL | https://moodle.org/ | + | id_display | | + | Completion tracking | Students can manually mark the activity as completed | + # Teacher view. + And the manual completion button for "Music history" should exist + And the manual completion button for "Music history" should be disabled + And I log out + # Student view. + When I log in as "student1" + And I am on "Course 1" course homepage + Then the manual completion button for "Music history" should exist + And the manual completion button of "Music history" is displayed as "Mark as done" + And I toggle the manual completion state of "Music history" + And the manual completion button of "Music history" is displayed as "Done" + + Examples: + | display | + | Open | + | In pop-up | + | New window |