MDL-49460 tool_lp: Adding user learning plans

Basic CRUD skeleton with external functions.
This commit is contained in:
David Monllao 2015-05-18 10:26:37 +08:00 committed by Frederic Massart
parent d9a39950b2
commit 4db373d5cb
21 changed files with 1653 additions and 27 deletions

View file

@ -0,0 +1,123 @@
// 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/>.
/**
* Delete plans via ajax.
*
* @module tool_lp/plandelete
* @package tool_lp
* @copyright 2015 David Monllao
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(['jquery', 'core/templates', 'core/ajax', 'core/notification', 'core/str'], function($, templates, ajax, notification, str) {
// Private variables and functions.
/** @var {Number} planid The id of the plan */
var planid = 0;
/** @var {Number} userid The id of the user */
var userid = 0;
/**
* Callback to replace the dom element with the rendered template.
*
* @param {string} newhtml The new html to insert.
* @param {string} newjs The new js to run.
*/
var updatePage = function(newhtml, newjs) {
$('[data-region="plans"]').replaceWith(newhtml);
templates.runTemplateJS(newjs);
};
/**
* Callback to render the page template again and update the page.
*
* @param {Object} context The context for the template.
*/
var reloadList = function(context) {
templates.render('tool_lp/plans_page', context)
.done(updatePage)
.fail(notification.exception);
};
/**
* Delete a plan and reload the page.
*/
var doDelete = function() {
// We are chaining ajax requests here.
var requests = ajax.call([{
methodname: 'tool_lp_delete_plan',
args: { id: planid }
}, {
methodname: 'tool_lp_data_for_plans_page',
args: { userid: userid }
}]);
requests[1].done(reloadList).fail(notification.exception);
};
/**
* Handler for "Delete plan" actions.
* @param {Event} e
*/
var confirmDelete = function(e) {
e.preventDefault();
var id = $(this).attr('data-planid');
planid = id;
var requests = ajax.call([{
methodname: 'tool_lp_read_plan',
args: { id: planid }
}]);
requests[0].done(function(plan) {
var strings = str.get_strings([
{ key: 'confirm', component: 'tool_lp' },
{ key: 'deleteplan', component: 'tool_lp', param: plan.name },
{ key: 'delete', component: 'tool_lp' },
{ key: 'cancel', component: 'tool_lp' }
]).done(function (strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Delete plan X?
strings[2], // Delete.
strings[3], // Cancel.
doDelete
);
}).fail(notification.exception);
}).fail(notification.exception);
};
return {
// Public variables and functions.
/**
* Initialise this plugin. Just attaches some event handlers to the delete entries in the menu.
*/
init: function() {
// Init this module.
$('[data-region="plans"]').on(
"click",
'[data-action="deleteplan"]',
confirmDelete
);
userid = $('[data-region="plans"]').attr('data-userid');
}
};
});

View file

@ -26,6 +26,7 @@ namespace tool_lp;
use stdClass;
use context_system;
use context_course;
use context_user;
use coding_exception;
use required_capability_exception;
@ -817,7 +818,7 @@ class api {
* @param int $limit Max of records to return (pagination)
* @return array of competency_framework
*/
public static function list_templates($filters, $sort, $order, $skip, $limit) {
public static function list_templates($filters = array(), $sort = '', $order = 'ASC', $skip = 0, $limit = 0) {
// First we do a permissions check.
$context = context_system::instance();
$caps = array('tool/lp:templateread', 'tool/lp:templatemanage');
@ -1023,4 +1024,168 @@ class api {
}
return false;
}
/**
* Lists user plans.
*
* @param int userid
* @return \tool_lp\plan[]
*/
public static function list_user_plans($userid) {
global $USER;
$select = 'userid = :userid';
$params = array('userid' => $userid);
$context = context_user::instance($userid);
// We can allow guest user to pass they will not have LP.
if ($USER->id != $userid) {
require_capability('tool/lp:planviewall', $context);
} else {
require_capability('tool/lp:planviewown', $context);
}
// Users that can manage plans can only see active and completed plans.
if (!has_any_capability(array('tool/lp:planmanage', 'tool/lp:planmanageown', 'tool/lp:plancreatedraft'), $context)) {
$select = ' AND status != :statusdraft';
$params['statusdraft'] = plan::STATUS_DRAFT;
}
$plans = new plan();
return $plans->get_records_select($select, $params, 'timemodified DESC');
}
/**
* Creates a learning plan based on the provided data.
*
* @param stdClass $record
* @return \tool_lp\plan
*/
public static function create_plan(stdClass $record) {
global $USER;
$context = context_user::instance($record->userid);
$manageplans = has_capability('tool/lp:planmanage', $context);
$createdraft = has_capability('tool/lp:plancreatedraft', $context);
$manageownplan = has_capability('tool/lp:planmanageown', $context);
// Any of them is enough.
if ($USER->id == $record->userid && !$manageplans && !$createdraft && !$manageownplan) {
// Exception about plancreatedraft as it is the one that is closer to basic users.
throw new required_capability_exception($context, 'tool/lp:plancreatedraft', 'nopermissions', '');
} else if ($USER->id != $record->userid && !$manageplans) {
throw new required_capability_exception($context, 'tool/lp:planmanage', 'nopermissions', '');
}
if (!isset($record->status)) {
// Default to status draft.
$record->status = plan::STATUS_DRAFT;
} else if ($record->status !== plan::STATUS_DRAFT && !$manageplans && !$manageownplan) {
// If the user can only create drafts we don't allow them to set other status.
throw new required_capability_exception($context, 'tool/lp:planmanageown', 'nopermissions', '');
}
$plan = new plan(0, $record);
$id = $plan->create();
return $plan;
}
/**
* Updates a plan.
*
* @param stdClass $record
* @return \tool_lp\plan
*/
public static function update_plan(stdClass $record) {
global $USER;
$context = context_user::instance($record->userid);
$manageplans = has_capability('tool/lp:planmanage', $context);
$createdraft = has_capability('tool/lp:plancreatedraft', $context);
$manageownplan = has_capability('tool/lp:planmanageown', $context);
// Any of them is enough.
if ($USER->id == $record->userid && !$manageplans && !$createdraft && !$manageownplan) {
throw new required_capability_exception($context, 'tool/lp:planmanageown', 'nopermissions', '');
} else if (!$manageplans) {
throw new required_capability_exception($context, 'tool/lp:planmanage', 'nopermissions', '');
}
$current = new plan($record->id);
// We don't allow users without planmanage and without
// planmanageown to edit plans that other users modified.
if (!$manageplans && !$manageownplans && $USER->id != $current->get_usermodified()) {
throw new moodle_exception('erroreditingmodifiedplan', 'tool_lp');
} else if (!$manageplans && $USER->id != $current->userid) {
throw new required_capability_exception($context, 'tool/lp:planmanage', 'nopermissions', '');
}
// If the user can only create drafts we don't allow them to set other status.
if ($record->status !== plan::STATUS_DRAFT && !$manageplans && !$manageownplan) {
required_capability_exception($context, 'tool/lp:planmanageown', 'nopermissions', '');
}
$plan = new plan($record->id, $record);
return $plan->update();
}
/**
* Returns a plan data.
*
* @param int $id
* @return \tool_lp\plan
*/
public static function read_plan($id) {
global $USER;
$plan = new plan($id);
$context = context_user::instance($plan->get_userid());
if ($USER->id == $plan->get_userid()) {
require_capability('tool/lp:planviewown', $context);
} else {
require_capability('tool/lp:planviewall', $context);
}
// We require any of these capabilities to retrieve draft plans.
if ($plan->get_status() === plan::STATUS_DRAFT &&
!has_any_capability(array('tool/lp:planmanageown', 'tool/lp:planmanage', 'tool/lp:plancreatedraft'), $context)) {
// Exception about plancreatedraft as it is the one that is closer to basic users.
throw new required_capability_exception($context, 'tool/lp:plancreatedraft', 'nopermissions', '');
}
return $plan;
}
/**
* Deletes a plan.
*
* @param int $id
* @return bool Success?
*/
public static function delete_plan($id) {
global $USER;
$plan = new plan($id);
$context = context_user::instance($plan->get_userid());
$manageplans = has_capability('tool/lp:planmanage', $context);
$createdraft = has_capability('tool/lp:plancreatedraft', $context);
$manageownplan = has_capability('tool/lp:planmanageown', $context);
if ($USER->id == $plan->get_userid() && $USER->id != $plan->get_usermodified() &&
!$manageplans && !$manageownplan) {
// A normal user can only edit its plan if they created it.
throw new required_capability_exception($context, 'tool/lp:planmanageown', 'nopermissions', '');
} else if ($USER->id != $plan->get_userid() && !$manageplans) {
// Other users needs to have tool/lp:planmanage.
throw new required_capability_exception($context, 'tool/lp:planmanage', 'nopermissions', '');
}
return $plan->delete();
}
}

View file

@ -2111,7 +2111,7 @@ class external extends external_api {
* @param bool $visible Is this template visible.
* @return stdClass Record of new template.
*/
public static function create_template($shortname, $idnumber, $description, $descriptionformat, $visible) {
public static function create_template($shortname, $idnumber, $duedate, $description, $descriptionformat, $visible) {
$params = self::validate_parameters(self::create_template_parameters(),
array(
'shortname' => $shortname,
@ -2953,4 +2953,437 @@ class external extends external_api {
));
}
/**
* A learning plan structure.
*
* @return external_single_structure
*/
protected static function get_plan_external_structure() {
$id = new external_value(
PARAM_INT,
'Database record id'
);
$name = new external_value(
PARAM_TEXT,
'Name for the learning plan'
);
$description = new external_value(
PARAM_RAW,
'Description for the template'
);
$descriptionformat = new external_format_value(
'Description format for the template'
);
$userid = new external_value(
PARAM_INT,
'Learning plan user id'
);
$templateid = new external_value(
PARAM_INT,
'Learning plan templateid'
);
$status = new external_value(
PARAM_INT,
'Learning plan status identifier.'
);
$duedate = new external_value(
PARAM_INT,
'The default due date for instances of this plan.'
);
$timecreated = new external_value(
PARAM_INT,
'Timestamp this record was created'
);
$timemodified = new external_value(
PARAM_INT,
'Timestamp this record was modified'
);
$usermodified = new external_value(
PARAM_INT,
'User who modified this record last'
);
// Extra params.
$statusname = new external_value(
PARAM_TEXT,
'Learning plan status name'
);
$usercanupdate = new external_value(
PARAM_BOOL,
'Whether the current user can update this plan or not'
);
$returns = array(
'id' => $id,
'name' => $name,
'description' => $description,
'descriptionformat' => $descriptionformat,
'userid' => $userid,
'templateid' => $templateid,
'status' => $status,
'duedate' => $duedate,
'timecreated' => $timecreated,
'timemodified' => $timemodified,
'usermodified' => $usermodified,
'statusname' => $statusname,
'usercanupdate' => $usercanupdate
);
return new external_single_structure($returns);
}
/**
* Returns description of create_plan() parameters.
*
* @return external_function_parameters
*/
public static function create_plan_parameters() {
$name = new external_value(
PARAM_TEXT,
'Name for the learning plan template.',
VALUE_REQUIRED
);
$description = new external_value(
PARAM_RAW,
'Optional description for the learning plan description',
VALUE_DEFAULT,
''
);
$descriptionformat = new external_format_value(
'Optional description format for the learning plan description',
VALUE_DEFAULT,
FORMAT_HTML
);
$userid = new external_value(
PARAM_INT,
'The learning plan user id',
VALUE_REQUIRED
);
$templateid = new external_value(
PARAM_INT,
'Optional template id',
VALUE_DEFAULT,
0
);
$status = new external_value(
PARAM_INT,
'Optional template id',
VALUE_DEFAULT,
plan::STATUS_DRAFT
);
$duedate = new external_value(
PARAM_INT,
'The default due date for this plan',
VALUE_DEFAULT,
0
);
$params = array(
'name' => $name,
'description' => $description,
'descriptionformat' => $descriptionformat,
'userid' => $userid,
'templateid' => $templateid,
'status' => $status,
'duedate' => $duedate
);
return new external_function_parameters($params);
}
/**
* Expose to AJAX
* @return boolean
*/
public static function create_plan_is_allowed_from_ajax() {
return true;
}
/**
* Create a new learning plan.
*/
public static function create_plan($name, $description, $descriptionformat, $userid, $templateid, $status, $duedate) {
$params = self::validate_parameters(self::create_plan_parameters(),
array(
'name' => $name,
'description' => $description,
'descriptionformat' => $descriptionformat,
'userid' => $userid,
'templateid' => $templateid,
'status' => $status,
'duedate' => $duedate
));
$params = (object) $params;
$result = api::create_plan($params);
return external_api::clean_returnvalue(self::create_plan_returns(), $result->to_record());
}
/**
* Returns description of create_plan() result value.
*
* @return external_description
*/
public static function create_plan_returns() {
return self::get_plan_external_structure();
}
/**
* Returns description of update_plan() parameters.
*
* @return external_function_parameters
*/
public static function update_plan_parameters() {
$id = new external_value(
PARAM_INT,
'Learning plan id',
VALUE_REQUIRED
);
$name = new external_value(
PARAM_TEXT,
'Name for the learning plan template.',
VALUE_REQUIRED
);
$description = new external_value(
PARAM_RAW,
'Optional description for the learning plan description',
VALUE_DEFAULT,
''
);
$descriptionformat = new external_format_value(
'Optional description format for the learning plan description',
VALUE_DEFAULT,
FORMAT_HTML
);
$userid = new external_value(
PARAM_INT,
'The learning plan user id',
VALUE_REQUIRED
);
$templateid = new external_value(
PARAM_INT,
'Optional template id',
VALUE_DEFAULT,
0
);
$status = new external_value(
PARAM_INT,
'Optional template id',
VALUE_DEFAULT,
plan::STATUS_DRAFT
);
$duedate = new external_value(
PARAM_INT,
'The default due date for this plan',
VALUE_DEFAULT,
0
);
$params = array(
'id' => $id,
'name' => $name,
'description' => $description,
'descriptionformat' => $descriptionformat,
'userid' => $userid,
'templateid' => $templateid,
'status' => $status,
'duedate' => $duedate
);
return new external_function_parameters($params);
}
/**
* Expose to AJAX
* @return boolean
*/
public static function update_plan_is_allowed_from_ajax() {
return true;
}
/**
* Updates a new learning plan.
*/
public static function update_plan($id, $name, $description, $descriptionformat, $userid, $templateid, $status, $duedate) {
$params = self::validate_parameters(self::update_plan_parameters(),
array(
'id' => $id,
'name' => $name,
'description' => $description,
'descriptionformat' => $descriptionformat,
'userid' => $userid,
'templateid' => $templateid,
'status' => $status,
'duedate' => $duedate
));
$params = (object) $params;
$result = api::update_plan($params);
return external_api::clean_returnvalue(self::update_plan_returns(), $result->to_record());
}
/**
* Returns description of update_plan() result value.
*
* @return external_description
*/
public static function update_plan_returns() {
return self::get_plan_external_structure();
}
/**
* Returns description of read_plan() parameters.
*
* @return external_function_parameters
*/
public static function read_plan_parameters() {
$id = new external_value(
PARAM_INT,
'Data base record id for the plan',
VALUE_REQUIRED
);
return new external_function_parameters(array('id' => $id));
}
/**
* Expose to AJAX
* @return boolean
*/
public static function read_plan_is_allowed_from_ajax() {
return true;
}
/**
* Read a plan by id.
*
* @param int $id The id of the plan.
* @return stdClass
*/
public static function read_plan($id) {
$params = self::validate_parameters(self::read_plan_parameters(),
array(
'id' => $id,
));
$result = api::read_plan($params['id']);
return external_api::clean_returnvalue(self::read_plan_returns(), $result->to_record());
}
/**
* Returns description of read_plan() result value.
*
* @return external_description
*/
public static function read_plan_returns() {
return self::get_plan_external_structure();
}
/**
* Returns description of delete_plan() parameters.
*
* @return external_function_parameters
*/
public static function delete_plan_parameters() {
$id = new external_value(
PARAM_INT,
'Data base record id for the learning plan',
VALUE_REQUIRED
);
$params = array(
'id' => $id,
);
return new external_function_parameters($params);
}
/**
* Expose to AJAX
* @return boolean
*/
public static function delete_plan_is_allowed_from_ajax() {
return true;
}
/**
* Delete a plan.
*
* @param int $id The plan id
* @return boolean
*/
public static function delete_plan($id) {
$params = self::validate_parameters(self::delete_plan_parameters(),
array(
'id' => $id,
));
return external_api::clean_returnvalue(self::delete_plan_returns(), api::delete_plan($params['id']));
}
/**
* Returns description of delete_plan() result value.
*
* @return external_description
*/
public static function delete_plan_returns() {
return new external_value(PARAM_BOOL, 'True if the delete was successful');
}
/**
* Returns description of data_for_plans_page() parameters.
*
* @return external_function_parameters
*/
public static function data_for_plans_page_parameters() {
$userid = new external_value(
PARAM_INT,
'The user id',
VALUE_REQUIRED
);
$params = array('userid' => $userid);
return new external_function_parameters($params);
}
/**
* Expose to AJAX
* @return boolean
*/
public static function data_for_plans_page_is_allowed_from_ajax() {
return true;
}
/**
* Loads the data required to render the plans_page template.
*
* @return boolean
*/
public static function data_for_plans_page($userid) {
global $PAGE;
$params = self::validate_parameters(self::data_for_plans_page_parameters(),
array(
'userid' => $userid,
));
$renderable = new \tool_lp\output\plans_page($params['userid']);
$renderer = $PAGE->get_renderer('tool_lp');
return external_api::clean_returnvalue(self::data_for_plans_page_returns(), $renderable->export_for_template($renderer));
}
/**
* Returns description of data_for_plans_page() result value.
*
* @return external_description
*/
public static function data_for_plans_page_returns() {
return new external_single_structure(array (
'userid' => new external_value(PARAM_INT, 'The learning plan user id'),
'plans' => new external_multiple_structure(
self::get_plan_external_structure()
),
'pluginbaseurl' => new external_value(PARAM_LOCALURL, 'Url to the tool_lp plugin folder on this Moodle site'),
'navigation' => new external_multiple_structure(
new external_value(PARAM_RAW, 'HTML for a navigation item that should be on this page')
)
));
}
}

View file

@ -0,0 +1,100 @@
<?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/>.
/**
* This file contains the form add/update a learning plan.
*
* @package tool_lp
* @copyright 2015 David Monllao
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_lp\form;
defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.');
use moodleform;
use tool_lp\api;
require_once($CFG->libdir.'/formslib.php');
/**
* Learning plan form.
*
* @package tool_lp
* @copyright 2015 David Monllao
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan extends moodleform {
/**
* Define the form - called by parent constructor
*/
public function definition() {
$mform = $this->_form;
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
$mform->setDefault('id', 0);
$mform->addElement('hidden', 'userid', $this->_customdata['userid']);
$mform->setType('userid', PARAM_INT);
$mform->addElement('text', 'name', get_string('planname', 'tool_lp'));
$mform->setType('name', PARAM_TEXT);
$mform->addRule('name', null, 'required', null, 'client');
$mform->addElement('editor', 'description', get_string('plandescription', 'tool_lp'), array('rows' => 4));
$mform->setType('description', PARAM_TEXT);
$templates = $this->get_template_options();
if ($templates) {
$mform->addElement('select', 'templateid', get_string('plantemplate', 'tool_lp'), $templates);
$mform->addHelpButton('templateid', 'plantemplate', 'tool_lp');
}
$mform->addElement('date_selector', 'duedate', get_string('duedate', 'tool_lp'));
$mform->addHelpButton('duedate', 'duedate', 'tool_lp');
$this->add_action_buttons(true, get_string('savechanges', 'tool_lp'));
if (!empty($this->_customdata['id'])) {
if (!$this->is_submitted()) {
$plan = api::read_plan($this->_customdata['id']);
$record = $plan->to_record();
$record->description = array('text' => $record->description, 'format' => $record->descriptionformat);
$this->set_data($record);
}
}
}
/**
* Get the template select options from the templates list.
*
* @return array|false
*/
protected function get_template_options() {
if (empty($this->_customdata['templates'])) {
return false;
}
$options = array('' => get_string('choosedots'));
foreach ($this->_customdata['templates'] as $template) {
$options[$template->get_id()] = $template->get_shortname();
}
return $options;
}
}

View file

@ -62,7 +62,7 @@ class manage_templates_page implements renderable, templatable {
$this->templates = api::list_templates(array(), 'sortorder', 'ASC', 0, 0);
$context = context_system::instance();
$this->canmanage = has_capability('tool/lp:learningplanmanage', $context);
$this->canmanage = has_capability('tool/lp:planmanage', $context);
}
/**

View file

@ -0,0 +1,99 @@
<?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/>.
/**
* Class containing data for a user learning plans list page.
*
* @package tool_lp
* @copyright 2015 David Monllao
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_lp\output;
use renderable;
use templatable;
use renderer_base;
use stdClass;
use single_button;
use moodle_url;
use tool_lp\api;
use tool_lp\plan;
use context_user;
/**
* Class containing data for a user learning plans list page.
*
* @copyright 2015 David Monllao
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plans_page implements renderable, templatable {
/** @var array $navigation List of links to display on the page. Each link contains a url and a title. */
var $navigation = array();
var $plans = array();
var $context = null;
var $userid = null;
/**
* Construct this renderable.
*
* @param int $userid
*/
public function __construct($userid) {
$this->userid = $userid;
$this->plans = api::list_user_plans($userid);
$this->context = context_user::instance($userid);
$addplan = new single_button(
new moodle_url('/admin/tool/lp/editplan.php', array('userid' => $userid)),
get_string('addnewplan', 'tool_lp')
);
$this->navigation[] = $addplan;
}
/**
* Export this data so it can be used as the context for a mustache template.
*
* @param renderer_base $output
* @return stdClass
*/
public function export_for_template(renderer_base $output) {
global $USER;
$data = new stdClass();
$data->userid = $this->userid;
$data->pluginbaseurl = (new moodle_url('/admin/tool/lp'))->out(true);
// Attach standard objects as mustache can not parse \tool_lp\plan objects.
if ($this->plans) {
$data->plans = array();
foreach ($this->plans as $plan) {
$data->plans[] = $plan->to_record();
}
}
$data->navigation = array();
foreach ($this->navigation as $button) {
$data->navigation[] = $output->render($button);
}
return $data;
}
}

View file

@ -27,6 +27,7 @@ namespace tool_lp\output;
defined('MOODLE_INTERNAL') || die;
use plugin_renderer_base;
use renderable;
/**
* Renderer class for learning plans
@ -85,4 +86,8 @@ class renderer extends plugin_renderer_base {
return parent::render_from_template('tool_lp/manage_templates_page', $data);
}
public function render_plans_page(renderable $page) {
$data = $page->export_for_template($this);
return parent::render_from_template('tool_lp/plans_page', $data);
}
}

View file

@ -226,7 +226,7 @@ abstract class persistent {
/**
* Load a list of records.
*
* @return array of persistent instances.
* @return \tool_lp\plan[]
*/
public function get_records($filters = array(), $sort = '', $order = 'ASC', $skip = 0, $limit = 0) {
global $DB;
@ -246,6 +246,34 @@ abstract class persistent {
return $instances;
}
/**
* Load a list of records based on a select query.
*
* @param string $select
* @param array $params
* @param string $sort
* @param string $fields
* @param int $limitfrom
* @param int $limitnum
* @return \tool_lp\plan[]
*/
public function get_records_select($select, $params = null, $sort = '', $fields = '*', $limitfrom = 0, $limitnum = 0) {
global $DB;
if (!$records = $DB->get_records_select($this->get_table_name(), $select, $params, $sort, $fields, $limitfrom, $limitnum)) {
return false;
}
// We return class instances.
$instances = array();
foreach ($records as $record) {
array_push($instances, new static(0, $record));
}
return $instances;
}
/**
* Count a list of records.
*

View file

@ -0,0 +1,257 @@
<?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/>.
/**
* Class for plans persistence.
*
* @package tool_lp
* @copyright 2015 David Monllao
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_lp;
use stdClass;
use context_user;
/**
* Class for loading/storing plans from the DB.
*
* @copyright 2015 David Monllao
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plan extends persistent {
const STATUS_DRAFT = 0;
const STATUS_ACTIVE = 1;
const STATUS_COMPLETE = 2;
/** @var string $name Name */
private $name = '';
/** @var string $description Description for this learning plan */
private $description = '';
/** @var int $descriptionformat Format for the description */
private $descriptionformat = FORMAT_MOODLE;
/** @var int $userid */
private $userid = null;
/** @var bool $templateid */
private $templateid = null;
/** @var bool $status The plan status, one of the 3 \tool_lp\plan:STATUS_* constants */
private $status = null;
/** @var bool $duedate */
private $duedate = null;
/**
* Method that provides the table name matching this class.
*
* @return string
*/
public function get_table_name() {
return 'tool_lp_plan';
}
public function get_name() {
return $this->name;
}
public function set_name($value) {
$this->name = $value;
}
public function get_description() {
return $this->description;
}
public function set_description($value) {
$this->description = $value;
}
public function get_descriptionformat() {
return $this->descriptionformat;
}
public function set_descriptionformat($value) {
$this->descriptionformat = $value;
}
public function get_userid() {
return $this->userid;
}
public function set_userid($value) {
$this->userid = $value;
}
public function get_templateid() {
return $this->templateid;
}
public function set_templateid($value) {
$this->templateid = $value;
}
public function get_status() {
if ($this->status === null) {
return null;
}
return (int)$this->status;
}
public function set_status($value) {
$this->status = $value;
}
public function get_duedate() {
return $this->duedate;
}
public function set_duedate($value) {
$this->duedate = $value;
}
// Extra methods.
/**
* Human readable status name.
*
* @return void
*/
public function get_statusname() {
$status = $this->get_status();
switch ($status) {
case self::STATUS_DRAFT:
$strname = 'draft';
break;
case self::STATUS_ACTIVE:
$strname = 'active';
break;
case self::STATUS_COMPLETE:
$strname = 'complete';
break;
default:
throw moodle_exception('errorplanstatus', 'tool_lp', '', $status);
break;
}
return get_string('planstatus' . $strname, 'tool_lp');
}
/**
* Whether the current user can update the learning plan.
*
* @return void
*/
public function get_usercanupdate() {
global $USER;
// Null if the record has not been filled.
if (!$userid = $this->get_userid()) {
return null;
}
$context = context_user::instance($userid);
// Not all users can edit all plans, the template should know about it.
if (has_capability('tool/lp:planmanage', $context) ||
has_capability('tool/lp:planmanageown', $context)) {
return true;
}
// The user that created the template can also edit it if he was the last one that modified it. But
// can't do it if it is already completed.
if ($USER->id == $userid && $this->get_usermodified() == $USER->id && $this->get_status() != plan::STATUS_COMPLETE) {
return true;
}
return false;
}
/**
* Converts the object to a standard PHP object.
*
* If it is used to insert/update into DB the extra fields like statusname will be
* ignored, they are useful though when passing the object to templates.
*
* @return void
*/
public function to_record() {
$record = new stdClass();
$record->id = $this->get_id();
$record->name = $this->get_name();
$record->description = $this->get_description();
$record->descriptionformat = $this->get_descriptionformat();
$record->userid = $this->get_userid();
$record->templateid = $this->get_templateid();
$record->status = $this->get_status();
$record->duedate = $this->get_duedate();
$record->timecreated = $this->get_timecreated();
$record->timemodified = $this->get_timemodified();
$record->usermodified = $this->get_usermodified();
// Extra data.
$record->statusname = $this->get_statusname();
$record->usercanupdate = $this->get_usercanupdate();
return $record;
}
public function from_record($record) {
if (isset($record->id)) {
$this->set_id($record->id);
}
if (isset($record->name)) {
$this->set_name($record->name);
}
if (isset($record->description)) {
$this->set_description($record->description);
}
if (isset($record->descriptionformat)) {
$this->set_descriptionformat($record->descriptionformat);
}
if (isset($record->userid)) {
$this->set_userid($record->userid);
}
if (isset($record->templateid)) {
$this->set_templateid($record->templateid);
}
if (isset($record->status)) {
$this->set_status($record->status);
}
if (isset($record->duedate)) {
$this->set_duedate($record->duedate);
}
if (isset($record->timecreated)) {
$this->set_timecreated($record->timecreated);
}
if (isset($record->timemodified)) {
$this->set_timemodified($record->timemodified);
}
if (isset($record->usermodified)) {
$this->set_usermodified($record->usermodified);
}
}
}

View file

@ -58,21 +58,43 @@ $capabilities = array(
),
'clonepermissionsfrom' => 'moodle/site:config'
),
'tool/lp:learningplanread' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/block:view'
),
'tool/lp:learningplanmanage' => array(
'tool/lp:plancreatedraft' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
),
'clonepermissionsfrom' => 'moodle/site:config'
),
'tool/lp:planmanage' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
),
'clonepermissionsfrom' => 'moodle/site:config'
),
'tool/lp:planmanageown' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_USER,
'archetypes' => array(
),
'clonepermissionsfrom' => 'moodle/site:config'
),
'tool/lp:planviewall' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => array(
),
'clonepermissionsfrom' => 'moodle/site:config'
),
'tool/lp:planviewown' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => array(
'user' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/block:view'
),
'tool/lp:coursecompetencyread' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
@ -90,5 +112,4 @@ $capabilities = array(
),
'clonepermissionsfrom' => 'moodle/site:backup'
)
);

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="admin/tool/lp/db" VERSION="20150312" COMMENT="XMLDB file for Moodle admin/tool/lp"
<XMLDB PATH="admin/tool/lp/db" VERSION="20150515" COMMENT="XMLDB file for Moodle admin/tool/lp"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
>
@ -91,5 +91,27 @@
<KEY NAME="competencyid" TYPE="foreign" FIELDS="competencyid" REFTABLE="tool_lp_competency" REFFIELDS="id" COMMENT="Competency foreign key."/>
</KEYS>
</TABLE>
<TABLE NAME="tool_lp_plan" COMMENT="Learning plans">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="name" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="description" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="descriptionformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="templateid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="status" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="duedate" TYPE="int" LENGTH="10" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="useridstatus" UNIQUE="false" FIELDS="userid, status"/>
<INDEX NAME="templateid" UNIQUE="false" FIELDS="templateid"/>
</INDEXES>
</TABLE>
</TABLES>
</XMLDB>
</XMLDB>

View file

@ -308,6 +308,53 @@ $functions = array(
'type' => 'write',
'capabilities'=> 'tool/lp:templatemanage',
),
'tool_lp_create_plan' => array(
'classname' => 'tool_lp\external',
'methodname' => 'create_plan',
'classpath' => '',
'description' => 'Creates a learning plan.',
'type' => 'write',
'capabilities'=> 'tool/lp:planmanage',
),
'tool_lp_update_plan' => array(
'classname' => 'tool_lp\external',
'methodname' => 'update_plan',
'classpath' => '',
'description' => 'Updates a learning plan.',
'type' => 'write',
'capabilities'=> 'tool/lp:planmanage',
),
'tool_lp_read_plan' => array(
'classname' => 'tool_lp\external',
'methodname' => 'read_plan',
'classpath' => '',
'description' => 'Load a learning plan.',
'type' => 'read',
'capabilities'=> 'tool/lp:planviewown',
),
'tool_lp_read_plan' => array(
'classname' => 'tool_lp\external',
'methodname' => 'read_plan',
'classpath' => '',
'description' => 'Load a learning plan.',
'type' => 'read',
'capabilities'=> 'tool/lp:planviewown',
),
'tool_lp_delete_plan' => array(
'classname' => 'tool_lp\external',
'methodname' => 'delete_plan',
'classpath' => '',
'description' => 'Delete a learning plan.',
'type' => 'write',
'capabilities'=> 'tool/lp:planmanage',
),
'tool_lp_data_for_plans_page' => array(
'classname' => 'tool_lp\external',
'methodname' => 'data_for_plans_page',
'classpath' => '',
'description' => 'Load the data for the plans page template',
'type' => 'read',
'capabilities'=> 'tool/lp:planviewown',
)
);

100
admin/tool/lp/editplan.php Normal file
View file

@ -0,0 +1,100 @@
<?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/>.
/**
* Page to edit a plan.
*
* @package tool_lp
* @copyright 2015 David Monllao
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
$userid = optional_param('userid', false, PARAM_INT);
$id = optional_param('id', false, PARAM_INT);
// Set up the page.
if (empty($id)) {
$pagetitle = get_string('addnewplan', 'tool_lp');
} else {
$pagetitle = get_string('editplan', 'tool_lp');
}
// Default to the current user.
if (!$userid) {
$userid = $USER->id;
}
$context = context_user::instance($userid);
$params = array('userid' => $userid);
if ($id) {
$params['id'] = $id;
}
$url = new moodle_url("/admin/tool/lp/editplan.php", $params);
$PAGE->set_context($context);
$PAGE->set_url($url);
$PAGE->set_title($pagetitle);
$PAGE->set_pagelayout('admin');
$PAGE->set_heading($pagetitle);
$output = $PAGE->get_renderer('tool_lp');
$manageplans = has_capability('tool/lp:planmanage', $context);
$owncapabilities = array('tool/lp:plancreatedraft', 'tool/lp:planmanageown');
if ($USER->id === $userid && !has_any_capability($owncapabilities, $context) && !$manageplans) {
throw new required_capability_exception($context, 'tool/lp:planmanageown', 'nopermissions', '');
} else if (!$manageplans) {
throw new required_capability_exception($context, 'tool/lp:planmanage', 'nopermissions', '');
}
// Passing the templates list to the form.
$templates = array();
if ($manageplans) {
$templates = \tool_lp\api::list_templates();
}
$customdata = array('id' => $id, 'userid' => $userid, 'templates' => $templates);
$form = new \tool_lp\form\plan(null, $customdata);
if ($form->is_cancelled()) {
redirect(new moodle_url('/admin/tool/lp/plans.php?userid=' . $userid));
}
echo $output->header();
echo $output->heading($pagetitle);
$data = $form->get_data();
if ($data) {
$data->descriptionformat = $data->description['format'];
$data->description = $data->description['text'];
if (empty($data->id)) {
require_sesskey();
\tool_lp\api::create_plan($data);
echo $output->notification(get_string('plancreated', 'tool_lp'), 'notifysuccess');
echo $output->continue_button('/admin/tool/lp/plans.php?userid=' . $userid);
} else {
require_sesskey();
\tool_lp\api::update_plan($data);
echo $output->notification(get_string('planupdated', 'tool_lp'), 'notifysuccess');
echo $output->continue_button('/admin/tool/lp/plans.php?userid=' . $userid);
}
} else {
$form->display();
}
echo $output->footer();

View file

@ -23,8 +23,12 @@
*/
$string['pluginname'] = 'Learning Plans';
$string['lp:learningplanmanage'] = 'Manage learning plans';
$string['lp:learningplanread'] = 'View learning plans';
$string['lp:plancreatedraft'] = 'Create draft learning plans';
$string['lp:planmanage'] = 'Manage learning plans';
$string['lp:planmanage'] = 'Manage learning plans';
$string['lp:planmanageown'] = 'Manage own learning plans';
$string['lp:planviewall'] = 'View all learning plans';
$string['lp:planviewown'] = 'View own learning plans';
$string['lp:competencymanage'] = 'Manage competency frameworks';
$string['lp:competencyread'] = 'View competency frameworks';
$string['lp:coursecompetencymanage'] = 'Manage course competencies';
@ -33,19 +37,25 @@ $string['competencies'] = 'Competencies';
$string['competenciesforframework'] = 'Competencies for {$a}';
$string['competencyframeworks'] = 'Competency Frameworks';
$string['addnewcompetencyframework'] = 'Add new competency framework';
$string['addnewplan'] = 'Add new learning plan';
$string['addnewtemplate'] = 'Add new learning plan template';
$string['addnewcompetency'] = 'Add new competency';
$string['addnewplan'] = 'Add new learning plan';
$string['addcompetency'] = 'Add competency';
$string['editcompetencyframework'] = 'Edit competency framework';
$string['erroreditingmodifiedplan'] = 'You can not edit a learning plan modified by another user if you don\'t have tool/lp:planmanage or tool/lp:planmanageown capabilities.';
$string['errorplanstatus'] = 'Learning plans {$a} status unknown';
$string['listcompetencyframeworkscaption'] = 'List of competency frameworks';
$string['listtemplatescaption'] = 'List of learning plan templates';
$string['listplanscaption'] = 'List of learning plans';
$string['competencyframeworkname'] = 'Name';
$string['actions'] = 'Actions';
$string['status'] = 'Status';
$string['notemplates'] = 'No learning plan templates have been created yet.';
$string['nocompetencyframeworks'] = 'No competency frameworks have been created yet.';
$string['nocompetencies'] = 'No competencies have been created in this framework.';
$string['nocompetenciesincourse'] = 'No competencies have been linked to this course.';
$string['nouserplans'] = 'No learning plans have been created yet.';
$string['shortname'] = 'Name';
$string['savechanges'] = 'Save changes';
$string['description'] = 'Description';
@ -58,6 +68,9 @@ $string['competencyframeworkcreated'] = 'Competency framework created.';
$string['competencyframeworkupdated'] = 'Competency framework updated.';
$string['editcompetencyframework'] = 'Edit competency framework';
$string['editthiscompetencyframework'] = 'Edit';
$string['editplan'] = 'Edit learning plan';
$string['editthisplan'] = 'Edit this learning plan';
$string['deletethisplan'] = 'Delete this learning plan';
$string['deletethiscompetencyframework'] = 'Delete';
$string['deletethistemplate'] = 'Delete';
$string['hiddenhint'] = '(hidden)';
@ -66,6 +79,13 @@ $string['movetonewparent'] = 'Relocate';
$string['moveframeworkafter'] = 'Move competency framework after {$a}';
$string['selectedcompetency'] = 'Selected competency';
$string['nocompetencyselected'] = 'No competency selected';
$string['plancreated'] = 'Learning plan created';
$string['planupdated'] = 'Learning plan updated';
$string['planname'] = 'Name';
$string['plandescription'] = 'Description';
$string['planstatusdraft'] = 'Draft';
$string['planstatusactive'] = 'Active';
$string['planstatuscomplete'] = 'Complete';
$string['search'] = 'Search...';
$string['competencycreated'] = 'Competency created';
$string['competencyupdated'] = 'Competency updated';
@ -73,8 +93,9 @@ $string['hidden'] = 'Hidden';
$string['editcompetency'] = 'Edit competency';
$string['confirm'] = 'Confirm';
$string['delete'] = 'Delete';
$string['deletecompetency'] = 'Delete competency? {$a}';
$string['deletecompetencyframework'] = 'Delete competency framework? {$a}';
$string['deletecompetency'] = 'Delete competency {$a}?';
$string['deletecompetencyframework'] = 'Delete competency framework {$a}?';
$string['deleteplan'] = 'Delete plan {$a}?';
$string['cancel'] = 'Cancel';
$string['move'] = 'Move';
$string['movecompetency'] = 'Move competency: {$a}';
@ -90,7 +111,8 @@ $string['coursesusingthiscompetency'] = 'Courses using this competency';
$string['learningplans'] = 'Learning plans';
$string['movecoursecompetency'] = 'Move course competency';
$string['movecoursecompetencyafter'] = 'Move course competency after {$a}';
$string['plantemplate'] = 'Select template';
$string['plantemplate_help'] = 'A learning plan created from a template will contain a list of competencies that match the template. Updates to the template will be reflected in any plan created from that template.';
$string['templates'] = 'Learning plan templates';
$string['templatename'] = 'Name';
$string['editthistemplate'] = 'Edit';

View file

@ -45,3 +45,31 @@ function tool_lp_extend_navigation_course($navigation, $course, $coursecontext)
$navigation->add_node($settingsnode);
}
}
/**
* Add nodes to myprofile page.
*
* @param \core_user\output\myprofile\tree $tree Tree object
* @param stdClass $user user object
* @param bool $iscurrentuser
* @param stdClass $course Course object
*
* @return bool
*/
function tool_lp_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) {
global $USER;
$context = context_user::instance($USER->id);
if (!$iscurrentuser && !has_capability('tool/lp:planviewall', $context)) {
return false;
}
if (!has_capability('tool/lp:planviewown', $context)) {
return false;
}
$url = new moodle_url('/admin/tool/lp/plans.php');
$node = new core_user\output\myprofile\node('miscellaneous', 'learningplans',
get_string('learningplans', 'tool_lp'), null, $url);
$tree->add_node($node);
}

69
admin/tool/lp/plans.php Normal file
View file

@ -0,0 +1,69 @@
<?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/>.
/**
* This page lets users see their learning plans.
*
* @package tool_lp
* @copyright 2015 David Monllao
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../../config.php');
$userid = optional_param('userid', false, PARAM_INT);
require_login(null, false);
if (isguestuser()) {
throw new require_login_exception();
}
$iscurrentuser = $userid == $USER->id;
if ($userid === false) {
$userid = $USER->id;
}
$context = context_user::instance($userid);
// Check that the user is a valid user.
$user = core_user::get_user($userid);
if (!$user || !core_user::is_real_user($userid)) {
throw new moodle_exception('invaliduser', 'error');
}
if (!has_capability('tool/lp:planviewall', $context)) {
if ($iscurrentuser) {
require_capability('tool/lp:planviewown', $context);
}
throw new required_capability_exception($context, 'tool/lp:planviewall', 'nopermissions', '');
}
$url = new moodle_url('/admin/tool/lp/plans.php', array('userid' => $userid));
$title = get_string('learningplans', 'tool_lp');
$PAGE->set_context($context);
$PAGE->set_pagelayout('admin');
$PAGE->set_url($url);
$PAGE->set_title($title);
$PAGE->set_heading($title);
$output = $PAGE->get_renderer('tool_lp');
echo $output->header();
echo $output->heading($title);
$page = new \tool_lp\output\plans_page($userid);
echo $output->render($page);
echo $output->footer();

View file

@ -38,7 +38,7 @@ $temp = new admin_externalpage(
'toollplearningplans',
get_string('learningplans', 'tool_lp'),
new moodle_url('/admin/tool/lp/learningplans.php'),
'tool/lp:learningplanmanage'
'tool/lp:planmanage'
);
$ADMIN->add('root', $temp, 'toollpcompetencies');

View file

@ -1,19 +1,23 @@
.path-admin-tool-learningplan [data-region="managecompetencies"] ul li,
.path-admin-tool-learningplan [data-region="plans"] ul li,
.path-admin-tool-learningplan [data-region="competencymovetree"] ul li,
.path-admin-tool-learningplan [data-region="competencylinktree"] ul li {
list-style-type: none;
}
.path-admin-tool-learningplan [data-region="managecompetencies"] ul li img {
.path-admin-tool-learningplan [data-region="managecompetencies"] ul li img,
.path-admin-tool-learningplan [data-region="plans"] ul li img {
margin-left: -20px;
margin-right: 4px;
}
.dir-rtl.path-admin-tool-learningplan [data-region="plans"] ul li img,
.dir-rtl.path-admin-tool-learningplan [data-region="managecompetencies"] ul li img {
margin-right: -20px;
margin-left: 4px;
}
.path-admin-tool-learningplan [data-region="managecompetencies"] ul[data-enhance="tree"],
.path-admin-tool-learningplan [data-region="plans"] ul[data-enhance="tree"],
.path-admin-tool-learningplan [data-region="competencylinktree"] ul[data-enhance="linktree"],
.path-admin-tool-learningplan [data-region="competencymovetree"] ul[data-enhance="movetree"] {
border: 1px solid #ccc;
@ -26,12 +30,14 @@
margin-right: 10px;
}
.path-admin-tool-learningplan [data-region="managecompetencies"] ul,
.path-admin-tool-learningplan [data-region="plans"] ul,
.path-admin-tool-learningplan [data-region="competencylinktree"] ul,
.path-admin-tool-learningplan [data-region="competencymovetree"] ul {
cursor: pointer;
}
.path-admin-tool-learningplan [data-region="competencylinktree"] ul [aria-selected="true"],
.path-admin-tool-learningplan [data-region="competencymovetree"] ul [aria-selected="true"],
.path-admin-tool-learningplan [data-region="plans"] ul [aria-selected="true"],
.path-admin-tool-learningplan [data-region="managecompetencies"] ul [aria-selected="true"] {
background-color: #dfdfdf;
}

View file

@ -23,7 +23,7 @@
* drag-samenode
* competencyframeworkactions
Data attibutes required for JS:
Data attributes required for JS:
* data-region = managecompetencies
* data-frameworkid = id
* data-action = deletecompetencyframework

View file

@ -0,0 +1,101 @@
{{!
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/>.
}}
{{!
User learning plans page.
Classes required for JS:
* planactions
Data attributes required for JS:
* data-region = plans
* data-planid = plans.id
* data-userid = userid
* data-action = deleteplan
Context variables required for this template:
* userid - The plan user id
* pluginbaseurl - tool_lp base url
* plans - The list of learning plans
* navigation - array of strings containing buttons for navigation
}}
<div data-region="plans" data-userid="{{userid}}">
<table class="generaltable fullwidth">
<caption>{{#str}}listplanscaption, tool_lp{{/str}}</caption>
<thead>
<tr>
<th scope="col">{{#str}}planname, tool_lp{{/str}}</th>
<th scope="col">{{#str}}status, tool_lp{{/str}}</th>
<th scope="col">{{#str}}actions, tool_lp{{/str}}</th>
</tr>
</thead>
<tbody>
{{#plans}}
<tr>
<td>
<span><a href="{{pluginbaseurl}}/plan.php?id={{id}}">{{name}}</a></span>
</td>
<td>{{statusname}}</td>
<td>
{{#usercanupdate}}
<div style="display: inline-block;">
<ul class="planactions hide">
<li>
<a href="{{pluginbaseurl}}/editplan.php?id={{id}}">
{{#pix}}t/edit{{/pix}}{{#str}}editthisplan, tool_lp{{/str}}
</a>
</li>
<li>
<a data-action="deleteplan" data-planid="{{id}}" href="#">
{{#pix}}t/delete{{/pix}}{{#str}}deletethisplan, tool_lp{{/str}}
</a>
</li>
</ul>
{{/usercanupdate}}
</div>
</td>
</tr>
{{/plans}}
</tbody>
</table>
{{^plans}}
<p class="alert-info">
{{#str}}nouserplans, tool_lp{{/str}}
</p>
{{/plans}}
<div class="btn-group pull-right">
{{#navigation}}
{{{.}}}
{{/navigation}}
</div>
{{#js}}
// Initialise the JS.
require(['tool_lp/plandelete',
'core/menu'],
function(deleteMod, menu) {
deleteMod.init();
menu.menu('{{#str}}edit{{/str}}', '.planactions');
});
{{/js}}
</div>

View file

@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2015021623; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2015021633; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2014110400; // Requires this Moodle version.
$plugin->component = 'tool_lp'; // Full name of the plugin (used for diagnostics).