Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support viewing marks, colours, links and comments in the app #113

Merged
merged 5 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/moodle-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ jobs:
env:
DB: ${{ matrix.database }}
MOODLE_BRANCH: ${{ matrix.moodle-branch }}
MUSTACHE_IGNORE_NAMES: 'mobile_view_checklist.mustache'

- name: PHP Lint
if: ${{ always() }}
Expand Down
90 changes: 90 additions & 0 deletions classes/external/update_item_state.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?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/>.

namespace mod_checklist\external;

defined('MOODLE_INTERNAL') || die;

global $CFG;
require_once("$CFG->libdir/externallib.php");

use core_external\external_api;
use core_external\external_value;
use core_external\external_function_parameters;
use core_external\external_single_structure;

/**
* External function to update the state of an item in a checklist
*
* @copyright 2023 Davo Smith
* @package mod_checklist
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class update_item_state extends external_api {

/**
* Describes the parameters for update_item_state.
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters(
[
'cmid' => new \external_value(PARAM_INT),
'itemid' => new \external_value(PARAM_INT),
'state' => new \external_value(PARAM_BOOL),
]
);
}

/**
* Updates item state.
*
* @param int $cmid Checklist course module ID.
* @param int $itemid Item ID.
* @param bool $state State to set.
* @return stdClass
*/
public static function execute(int $cmid, int $itemid, bool $state): \stdClass {
global $DB, $PAGE, $USER;
$cm = get_coursemodule_from_id('checklist', $cmid, 0, false, MUST_EXIST);
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
$checklist = $DB->get_record('checklist', array('id' => $cm->instance), '*', MUST_EXIST);
require_login($course, true, $cm);
require_capability('mod/checklist:updateown', $PAGE->context);

$chk = new \checklist_class($cm->id, $USER->id, $checklist, $cm, $course);
$chk->ajaxupdatechecks([$itemid => $state]);

return (object)[
'status' => true,
'warnings' => [],
];
}

/**
* Describes the update_item_state return value.
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([
'status' => new external_value(PARAM_BOOL),
'warnings' => new \external_warnings(),
]);
}

}
63 changes: 63 additions & 0 deletions classes/output/mobile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?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/>.

namespace mod_checklist\output;

/**
* Functions to support mobile app
*
* @package mod_checklist
* @copyright 2023 Davo Smith
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mobile {

/**
* Returns the checklist template and JS for the mobile app.
*
* @param array $args Arguments from tool_mobile_get_content WS
* @return array HTML, javascript and otherdata
*/
public static function mobile_course_view($args) {
global $OUTPUT, $CFG, $USER;
require_once($CFG->dirroot.'/mod/checklist/locallib.php');

$args = (object)$args;
$cm = get_coursemodule_from_id('checklist', $args->cmid);

require_login($args->courseid, false, $cm, true, true);
$context = \context_module::instance($cm->id);
if (!has_capability('mod/checklist:preview', $context)) {
require_capability('mod/checklist:updateown', $context);
}

$checklist = new \checklist_class($cm->id, $USER->id, null, $cm);
$data = $checklist->get_items_for_template();

return [
'templates' => [
[
'id' => 'main',
'html' => $OUTPUT->render_from_template('mod_checklist/mobile_view_checklist', $data),
],
],
'javascript' => file_get_contents($CFG->dirroot.'/mod/checklist/mobileapp/mobile.js'),
'otherdata' => [],
'files' => [],
];
}

}
53 changes: 53 additions & 0 deletions db/mobile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?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/>.

/**
* Support for mobile app
*
* @package mod_checklist
* @copyright 2023 Davo Smith
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

defined('MOODLE_INTERNAL') || die();
global $CFG;

$addons = [
'mod_checklist' => [
'handlers' => [
'checklist' => [
'displaydata' => [
'title' => 'pluginname',
'icon' => $CFG->wwwroot.'/mod/checklist/pix/monologo.svg',
'class' => '',
],
'delegate' => 'CoreCourseModuleDelegate',
'method' => 'mobile_course_view',
'offlinefunctions' => [],
'styles' => [
'url' => $CFG->wwwroot.'/mod/checklist/styles_app.css',
'version' => '0.1',
],
],
],
'lang' => [
['pluginname', 'checklist'],
['percentcomplete', 'checklist'],
['percentcompleteall', 'checklist'],
['linktourl', 'checklist'],
],
]
];
16 changes: 12 additions & 4 deletions db/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,22 @@

defined('MOODLE_INTERNAL') || die();

$functions = array(
'mod_checklist_update_student_comment' => array(
$functions = [
'mod_checklist_update_student_comment' => [
'classname' => 'mod_checklist\external\update_student_comment',
'methodname' => 'execute',
'classpath' => '',
'description' => 'Update a student comment',
'ajax' => true,
'type' => 'write',
'capabilities' => 'mod/checklist:view, mod/checklist:updateown',
),
);
],
'mod_checklist_update_item_state' => [
'classname' => \mod_checklist\external\update_item_state::class,
'methodname' => 'execute',
'ajax' => true,
'type' => 'write',
'capabilities' => 'mod/checklist:updateown',
'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE],
],
];
130 changes: 130 additions & 0 deletions locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,136 @@ protected function get_items() {
}
}

/**
* Get the items to output in a template.
* @return object
*/
public function get_items_for_template() {
global $DB;

$checklist = clone($this->checklist);
$checklist->name = format_string($checklist->name);
[$checklist->intro, $checklist->introformat] = \core_external\util::format_text($checklist->intro,
$checklist->introformat,
$this->context,
'mod_checklist',
'intro');

// Configure the status of the checklist output.
$status = new output_status();
$status->set_viewother(false);
$status->set_userreport(false);
$status->set_teachercomments($checklist->teachercomments);
$status->set_studentcomments($checklist->studentcomments);
$status->set_canupdateown($this->canupdateown());
$status->set_canaddown($this->canaddown());
$status->set_courseid($this->course->id);

$progressinfo = $this->get_progress();
$progress = 0.0;
$progressall = 0.0;
$showrequired = false;
if ($progressinfo) {
if ($progressinfo->totalitems !== $progressinfo->requireditems) {
$showrequired = true;
if ($progressinfo->requireditems) {
$progress = 100.0 * $progressinfo->requiredcompleteitems / $progressinfo->requireditems;
}
}
if ($progressinfo->totalitems) {
$progressall = 100.0 * $progressinfo->allcompleteitems / $progressinfo->totalitems;
}
}
$isoverrideauto = ($this->checklist->autoupdate != CHECKLIST_AUTOUPDATE_YES);

// TODO Allow adding/editing items, adding/editing comments.

$data = (object)[
'intro' => $checklist->intro,
'cmid' => $this->cm->id,
'courseid' => $checklist->course,
'items' => [],
'showteachermark' => in_array($this->checklist->teacheredit,
[CHECKLIST_MARKING_TEACHER, CHECKLIST_MARKING_BOTH]),
'showcheckbox' => in_array($this->checklist->teacheredit,
[CHECKLIST_MARKING_STUDENT, CHECKLIST_MARKING_BOTH]),
'progress' => $progress,
'progressall' => $progressall,
'showrequired' => $showrequired,
];

// Load comments.
if ($status->is_teachercomments()) {
$comments = checklist_comment::fetch_by_userid_itemids($this->userid, array_keys($this->items));
checklist_comment::add_commentby_names($comments);
checklist_item::add_comments($this->items, $comments);
}
if ($status->is_studentcomments()) {
$studentcomments = checklist_comment_student::get_student_comments_indexed($this->userid, array_keys($this->items));
checklist_comment_student::add_student_names($studentcomments);
checklist_item::add_student_comments($this->items, $studentcomments);
}

foreach ($this->items as $item) {
if ($item->hidden) {
continue;
}
$disabled = false;
if (!$isoverrideauto && $item->is_auto_item()) {
$disabled = true;
}

$itemfortemplate = (object)[
'itemid' => $item->id,
'text' => $item->displaytext,
'indent' => $item->indent,
'colour' => $item->colour,
'duetime' => $item->duetime ? $item->duetime : false,
'showitemmark' => $data->showteachermark && !$item->is_heading(),
'showitemcheckbox' => $data->showcheckbox && !$item->is_heading(),
'isoverdue' => $item->duetime && $item->duetime <= time(),
'isheading' => $item->is_heading(),
'isoptional' => $item->is_optional(),
'checkedstudent' => $item->is_checked_student(),
'teachermarktext' => $item->get_teachermark_text(),
'teachermarkimage' => $item->get_teachermark_image_url()->out(),
'url' => $item->get_link_url(),
'disabled' => $disabled,
];

if ($status->is_teachercomments()) {
$comment = $item->get_comment();
if ($comment) {
$itemfortemplate->comment = (object)[
'commentby' => $comment->commentby,
'text' => s($comment->text),
];
if ($comment->commentby) {
$itemfortemplate->comment->commentbyurl = $comment->get_commentby_url();
$itemfortemplate->comment->commentbyname = $comment->get_commentby_name();
}
}
}

if ($status->is_studentcomments()) {
// Right now you can only see your own list in the app, not other people's lists.
$studentcomment = $item->get_student_comment();
if ($this->userid && $studentcomment) {
$currentuser = $DB->get_record('user', ['id' => $this->userid], '*', MUST_EXIST);
$itemfortemplate->studentcomment = (object)[
'text' => s($studentcomment->get('text')),
'studentid' => $this->userid,
'studenturl' => new moodle_url('/user/view.php', ['id' => $this->userid, 'course' => $this->course->id]),
'studentname' => fullname($currentuser),
];
}
}

$data->items[] = $itemfortemplate;
}
return $data;
}

/**
* Loop through all activities / resources in course and check they
* are in the current checklist (in the right order)
Expand Down
Loading