Skip to content

Commit

Permalink
CTP-1685 add unfreeze function to lifecycle block
Browse files Browse the repository at this point in the history
  • Loading branch information
aydevworks committed Nov 19, 2024
1 parent b4a5c5d commit d3ef56c
Show file tree
Hide file tree
Showing 13 changed files with 381 additions and 46 deletions.
5 changes: 5 additions & 0 deletions block_lifecycle.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ public function get_content() {
$html .= $renderer->fetch_clc_content($courseid);
if (manager::is_course_frozen($courseid)) {
$html .= $renderer->fetch_course_read_only_notification();

// Check if user has the capability to unfreeze the course.
if (has_capability("block/lifecycle:unfreezecourse", $context)) {
$html .= $renderer->fetch_unfreeze_button_html($context);
}
}
$html .= $renderer->fetch_course_dates($courseid);
}
Expand Down
24 changes: 24 additions & 0 deletions classes/manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,30 @@ public static function get_weeks_delay_in_seconds() {
return $enddateextend;
}

/**
* Unfreeze course context.
*
* @param int $courseid Course id.
* @return void
* @throws \coding_exception
* @throws \moodle_exception
*/
public static function unfreeze_course(int $courseid): void {
// Check user's permission.
if (!has_capability('block/lifecycle:unfreezecourse', context_course::instance($courseid))) {
throw new \moodle_exception('error:unfreeze_course', 'block_lifecycle');
}
$context = context_course::instance($courseid);
if ($context->is_locked()) {
// Unlock the course context.
$context->set_locked(false);

// Disable auto context freezing for the course.
$preferences = (object) ['togglefreeze' => 1, 'delayfreezedate' => ''];
self::update_auto_freezing_preferences($courseid, $preferences);
}
}

/**
* Get the furthest date among LSA end date and course end date, plus weeks delay.
*
Expand Down
8 changes: 8 additions & 0 deletions db/access.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,12 @@
'manager' => CAP_ALLOW,
],
],
'block/lifecycle:unfreezecourse' => [
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => [
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW,
],
],
];
15 changes: 9 additions & 6 deletions lang/en/block_lifecycle.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,30 @@
* @author Alex Yeung <[email protected]>
*/

$string['pluginname'] = 'Lifecycle';
$string['button:editsettings'] = 'Edit automatic Read-Only settings';
$string['button:toggleautoreadonly'] = 'Disable Automatic Read-Only';
$string['error:dateformat'] = 'Date must be in format YYYY-MM-DD';
$string['error:cannotgetscheduledfreezedate'] = 'Could not get the automatically suggested date.';
$string['error:updatepreferencessuccess'] = 'Auto read only settings updated successfully.';
$string['error:dateformat'] = 'Date must be in format YYYY-MM-DD';
$string['error:unfreeze_course'] = 'You do not have permission to enable editing.';
$string['error:updatepreferencesfailed'] = 'Failed to update read only settings.';
$string['error:updatepreferencessuccess'] = 'Auto read only settings updated successfully.';
$string['generalsettings'] = 'General Settings';
$string['help:togglefreezing'] = 'Disable Automatic Read-Only';
$string['help:togglefreezing_help'] = 'Disable Automatic Read-Only.';
$string['help:delayfreezedate'] = 'override Read-Only date';
$string['help:delayfreezedate_help'] = 'The date for a Read-Only override must be post the automatically suggested date, earlier dates may not be used.';
$string['help:togglefreezing'] = 'Disable Automatic Read-Only';
$string['help:togglefreezing_help'] = 'Disable Automatic Read-Only.';
$string['label:readonlydate'] = 'This course will be made automatically Read Only on: ';
$string['label:readonlydateinput'] = 'Overrides Read-Only date:';
$string['label:unfreezebutton'] = 'Enable editing';
$string['lifecycle:addinstance'] = 'Add lifecycle block';
$string['lifecycle:coursereadonly'] = 'This Course is Read Only';
$string['lifecycle:enddate'] = 'This course\'s end date: {$a}';
$string['lifecycle:myaddinstance'] = 'Add my lifecycle block';
$string['lifecycle:overridecontextfreeze'] = 'Override default course context freezing settings';
$string['lifecycle:startdate'] = 'This course\'s start date: {$a}';
$string['lifecycle:coursereadonly'] = 'This Course is Read Only';
$string['lifecycle:unfreezecourse'] = 'Unfreeze course';
$string['lifecycle:view'] = 'View lifecycle block';
$string['pluginname'] = 'Lifecycle';
$string['privacy:metadata'] = 'The Lifecycle block does not store personal data';
$string['settings:academicyearstartdate'] = 'Academic year start date';
$string['settings:academicyearstartdate:desc'] = 'This field is used to calculate the current academic year period and in MM-DD format';
Expand Down
19 changes: 19 additions & 0 deletions renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

use block_lifecycle\manager;
use core\context\course;

/**
* Class block_lifecycle_renderer
Expand Down Expand Up @@ -151,4 +152,22 @@ public function fetch_course_read_only_notification(): string {

return $content;
}

/**
* Return the html for the unfreeze button.
*
* @param context_course $context
* @return string
* @throws coding_exception|moodle_exception
*/
public function fetch_unfreeze_button_html(context_course $context): string {
$url = new moodle_url('/blocks/lifecycle/unfreeze.php', ['id' => $context->instanceid]);
return $this->output->render_from_template(
'block_lifecycle/unfreeze_button',
[
'url' => $url->out(false),
'coursename' => $context->get_context_name(),
]
);
}
}
47 changes: 47 additions & 0 deletions templates/unfreeze_button.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{{!
This file is part the Local Analytics plugin for Moodle
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/>.
}}
{{!
@template block_lifecycle/unfreeze_button
Template for displaying the unfreeze button to unfreeze a frozen course.
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* url - string The URL to the unfreeze page.
* coursefullname - string The full name of the course.
Example context (json):
{
"url": "http://test.m44.local/blocks/lifecycle/unfreeze.php?id=5",
"coursename": "Test Course 1"
}
}}
<button type="button"
class="btn btn-primary w-100"
data-confirmation="modal"
data-confirmation-title-str='["label:unfreezebutton", "block_lifecycle"]'
data-confirmation-content-str='["confirmcontextunlock", "admin", {"contextname": "{{coursename}}"}]'
data-confirmation-yes-button-str='["confirm"]'
data-confirmation-destination="{{url}}"
>
Enable editing
<span class="sr-only"> for course {{coursename}}</span>
</button>
91 changes: 91 additions & 0 deletions tests/behat/behat_lifecycle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?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/>.

use Behat\Gherkin\Node\TableNode;
require_once(__DIR__ . '/../../../../lib/behat/behat_base.php');

/**
* Defines the behat steps for the block_lifecycle plugin.
*
* @package block_lifecycle
* @copyright 2024 onwards University College London {@link https://www.ucl.ac.uk/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Alex Yeung <[email protected]>
*/
class behat_lifecycle extends behat_base {
/**
* Create custom field.
*
* @param TableNode $table
* @throws \dml_exception
*
* @Given /^the following custom field exists for lifecycle block:$/
*/
public function the_following_custom_field_exists_for_lifecycle_block(TableNode $table): void {
global $DB;

$data = $table->getRowsHash();

// Create a new custom field category if it doesn't exist.
$category = $DB->get_record(
'customfield_category',
['name' => $data['category'],
'component' => 'core_course',
'area' => 'course']);

if (!$category) {
$category = (object)[
'name' => $data['category'],
'component' => 'core_course',
'area' => 'course',
'sortorder' => 1,
'timecreated' => time(),
'timemodified' => time(),
];
$category->id = $DB->insert_record(
'customfield_category',
$category
);
}

// Check if the field already exists.
$fieldexists = $DB->record_exists('customfield_field', ['shortname' => $data['shortname'], 'categoryid' => $category->id]);

// Create the custom field if not exists.
if (!$fieldexists) {
$field = (object)[
'shortname' => $data['shortname'],
'name' => $data['name'],
'type' => $data['type'],
'categoryid' => $category->id,
'sortorder' => 0,
'configdata' => json_encode([
"required" => 0,
"uniquevalues" => 0,
"maxlength" => 4,
"defaultvalue" => "",
"ispassword" => 0,
"displaysize" => 4,
"locked" => 1,
"visibility" => 0,
]),
'timecreated' => time(),
'timemodified' => time(),
];
$DB->insert_record('customfield_field', $field);
}
}
}
34 changes: 34 additions & 0 deletions tests/behat/unfreeze_course.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@block @block_lifecycle

Feature: Unfreeze a frozen course
As a teacher with the appropriate permission
I can click on the "Enable editing" button in the lifecycle block to unfreeze a frozen course

Background:
Given the following "users" exist:
| username | firstname | lastname | idnumber | email |
| teacher1 | Teacher1 | Test | tea1 | teacher1@example.com |
And the following custom field exists for lifecycle block:
| category | CLC |
| shortname | course_year |
| name | Course Year |
| type | text |
And the following "courses" exist:
| fullname | shortname | format | customfield_course_year | startdate | enddate |
| Course 1 | C1 | topics | ##now##%Y## | ## 2 days ago ## | ## yesterday ## |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| lifecycle | Course | C1 | course-view-* | side-pre |
And the "C1" "Course" is context frozen

@javascript
Scenario: Unfreeze a frozen course
Given I am on the "C1" course page logged in as teacher1
And edit mode should not be available on the current page
And I should see "Enable editing" in the "Lifecycle" "block"
And I click on "Enable editing" "text"
And I press "Confirm"
Then edit mode should be available on the current page
2 changes: 1 addition & 1 deletion tests/freezecontext_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Alex Yeung <[email protected]>
*/
class freezecontext_test extends \advanced_testcase {
final class freezecontext_test extends \advanced_testcase {
protected function setUp(): void {
parent::setUp();
$this->resetAfterTest();
Expand Down
Loading

0 comments on commit d3ef56c

Please sign in to comment.