+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+define(['core/dragdrop-reorder',
+ 'core/str',
+ 'core/notification',
+ 'jquery',
+ 'core/ajax'],
+ function(dragdrop, str, notification, $, ajax) {
+ // Private variables and functions.
+
+ /**
+ * Handle a drop on a node.
+ *
+ * @param {DOMNode} drag
+ * @param {DOMNode} drop
+ */
+ var handleDrop = function(drag, drop) {
+ var from = $(drag).data('templateid');
+ var to = $(drop).data('templateid');
+
+ var requests = ajax.call([{
+ methodname: 'tool_lp_reorder_template',
+ args: { from: from, to: to }
+ }]);
+ requests[0].fail(notification.exception);
+
+ };
+
+ return {
+ // Public variables and functions.
+ /**
+ * Initialise this plugin. It loads some strings, then adds the drag/drop functions.
+ */
+ init: function() {
+ // Init this module.
+ str.get_string('movetemplate', 'tool_lp').done(
+ function(movestring) {
+ dragdrop.dragdrop('movetemplate',
+ movestring,
+ { identifier: 'movetemplate', component: 'tool_lp'},
+ { identifier: 'movetemplateafter', component: 'tool_lp'},
+ 'drag-samenode',
+ 'drag-parentnode',
+ 'drag-handlecontainer',
+ handleDrop);
+ }
+ ).fail(notification.exception);
+ }
+
+ };
+});
diff --git a/admin/tool/lp/classes/api.php b/admin/tool/lp/classes/api.php
new file mode 100644
index 00000000000..c6372002b00
--- /dev/null
+++ b/admin/tool/lp/classes/api.php
@@ -0,0 +1,1026 @@
+.
+
+/**
+ * Class for loading/storing competency frameworks from the DB.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_lp;
+
+use stdClass;
+use context_system;
+use context_course;
+use coding_exception;
+use required_capability_exception;
+
+/**
+ * Class for doing things with competency frameworks.
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class api {
+
+ /**
+ * Create a competency from a record containing all the data for the class.
+ *
+ * Requires tool/lp:competencymanage capability at the system context.
+ *
+ * @param stdClass $record Record containing all the data for an instance of the class.
+ * @return competency
+ */
+ public static function create_competency(stdClass $record) {
+ // First we do a permissions check.
+ require_capability('tool/lp:competencymanage', context_system::instance());
+
+ // OK - all set.
+ $competency = new competency(0, $record);
+ $id = $competency->create();
+ return $competency;
+ }
+
+ /**
+ * Delete a competency by id.
+ *
+ * Requires tool/lp:competencymanage capability at the system context.
+ *
+ * @param int $id The record to delete. This will delete alot of related data - you better be sure.
+ * @return boolean
+ */
+ public static function delete_competency($id) {
+ // First we do a permissions check.
+ require_capability('tool/lp:competencymanage', context_system::instance());
+
+ // OK - all set.
+ $competency = new competency();
+ $competency->set_id($id);
+ return $competency->delete();
+ }
+
+ /**
+ * Reorder this competency.
+ *
+ * Requires tool/lp:competencymanage capability at the system context.
+ *
+ * @param int $id The id of the competency to move.
+ * @return boolean
+ */
+ public static function move_down_competency($id) {
+ // First we do a permissions check.
+ require_capability('tool/lp:competencymanage', context_system::instance());
+
+ // Check the current one too.
+ $current = new competency($id);
+
+ $max = self::count_competencies(array('parentid' => $current->get_parentid(),
+ 'competencyframeworkid' => $current->get_competencyframeworkid()));
+ if ($max > 0) {
+ $max--;
+ }
+
+ $sortorder = $current->get_sortorder();
+ if ($sortorder >= $max) {
+ return false;
+ }
+ $sortorder = $sortorder + 1;
+ $current->set_sortorder($sortorder);
+
+ $filters = array('parentid' => $current->get_parentid(),
+ 'competencyframeworkid' => $current->get_competencyframeworkid(),
+ 'sortorder' => $sortorder);
+ $children = self::list_competencies($filters, 'id');
+ foreach ($children as $needtoswap) {
+ $needtoswap->set_sortorder($sortorder - 1);
+ $needtoswap->update();
+ }
+
+ // OK - all set.
+ return $current->update();
+ }
+
+ /**
+ * Reorder this competency.
+ *
+ * Requires tool/lp:competencymanage capability at the system context.
+ *
+ * @param int $id The id of the competency to move.
+ * @return boolean
+ */
+ public static function move_up_competency($id) {
+ // First we do a permissions check.
+ require_capability('tool/lp:competencymanage', context_system::instance());
+
+ // Check the current one too.
+ $current = new competency($id);
+
+ $sortorder = $current->get_sortorder();
+ if ($sortorder == 0) {
+ return false;
+ }
+
+ $sortorder = $sortorder - 1;
+ $current->set_sortorder($sortorder);
+
+ $filters = array('parentid' => $current->get_parentid(),
+ 'competencyframeworkid' => $current->get_competencyframeworkid(),
+ 'sortorder' => $sortorder);
+ $children = self::list_competencies($filters, 'id');
+ foreach ($children as $needtoswap) {
+ $needtoswap->set_sortorder($sortorder + 1);
+ $needtoswap->update();
+ }
+
+ // OK - all set.
+ return $current->update();
+ }
+
+ /**
+ * Move this competency so it sits in a new parent.
+ *
+ * Requires tool/lp:competencymanage capability at the system context.
+ *
+ * @param int $id The id of the competency to move.
+ * @param int $newparentid The new parent id for the competency.
+ * @return boolean
+ */
+ public static function set_parent_competency($id, $newparentid) {
+ // First we do a permissions check.
+ require_capability('tool/lp:competencymanage', context_system::instance());
+
+ // This will throw an exception if the parent does not exist.
+
+ // Check the current one too.
+ $current = new competency($id);
+ $parentframeworkid = $current->get_competencyframeworkid();
+ $parentpath = '/0/';
+ if ($newparentid) {
+ $parent = new competency($newparentid);
+ $parentframeworkid = $parent->get_competencyframeworkid();
+ $parentpath = $parent->get_path();
+ }
+
+ if ($parentframeworkid != $current->get_competencyframeworkid()) {
+ // Only allow moving within the same framework.
+ throw new coding_exception('Moving competencies is only supported within the same framework.');
+ }
+
+ // If we are moving a node to a child of itself, promote all the child nodes by one level.
+
+ $newparents = explode('/', $parentpath);
+ if (in_array($current->get_id(), $newparents)) {
+ $filters = array('parentid' => $current->get_id(), 'competencyframeworkid' => $current->get_competencyframeworkid());
+ $children = self::list_competencies($filters, 'id');
+
+ foreach ($children as $child) {
+ $child->set_parentid($current->get_parentid());
+ $child->update();
+ }
+ }
+
+ $current->set_parentid($newparentid);
+
+ // OK - all set.
+ return $current->update();
+ }
+
+ /**
+ * Update the details for a competency.
+ *
+ * Requires tool/lp:competencymanage capability at the system context.
+ *
+ * @param stdClass $record The new details for the competency. Note - must contain an id that points to the competency to update.
+ * @return boolean
+ */
+ public static function update_competency($record) {
+ // First we do a permissions check.
+ require_capability('tool/lp:competencymanage', context_system::instance());
+
+ // Some things should not be changed in an update - they should use a more specific method.
+ $current = new competency($record->id);
+ $record->sortorder = $current->get_sortorder();
+ $record->parentid = $current->get_parentid();
+ $record->competencyframeworkid = $current->get_competencyframeworkid();
+
+ // OK - all set.
+ $competency = new competency(0, $record);
+ return $competency->update();
+ }
+
+ /**
+ * Read a the details for a single competency and return a record.
+ *
+ * Requires tool/lp:competencyread capability at the system context.
+ *
+ * @param int $id The id of the competency to read.
+ * @return stdClass
+ */
+ public static function read_competency($id) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ if (!has_any_capability(array('tool/lp:competencyread', 'tool/lp:competencymanage'), $context)) {
+ throw new required_capability_exception($context, 'tool/lp:competencyread', 'nopermission', '');
+ }
+
+ // OK - all set.
+ return new competency($id);
+ }
+
+ /**
+ * Perform a text search based and return all results and their parents.
+ *
+ * Requires tool/lp:competencyread capability at the system context.
+ *
+ * @param string $textsearch A string to search for.
+ * @param int $competencyframeworkid The id of the framework to limit the search.
+ * @return array of competencies
+ */
+ public static function search_competencies($textsearch, $competencyframeworkid) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ if (!has_any_capability(array('tool/lp:competencyread', 'tool/lp:competencymanage'), $context)) {
+ throw new required_capability_exception($context, 'tool/lp:competencyread', 'nopermission', '');
+ }
+
+ // OK - all set.
+ $competency = new competency();
+ return $competency->search($textsearch, $competencyframeworkid);
+ }
+
+ /**
+ * Perform a search based on the provided filters and return a paginated list of records.
+ *
+ * Requires tool/lp:competencyread capability at the system context.
+ *
+ * @param array $filters A list of filters to apply to the list.
+ * @param string $sort The column to sort on
+ * @param string $order ('ASC' or 'DESC')
+ * @param int $skip Number of records to skip (pagination)
+ * @param int $limit Max of records to return (pagination)
+ * @return array of competencies
+ */
+ public static function list_competencies($filters, $sort, $order, $skip, $limit) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ if (!has_any_capability(array('tool/lp:competencyread', 'tool/lp:competencymanage'), $context)) {
+ throw new required_capability_exception($context, 'tool/lp:competencyread', 'nopermission', '');
+ }
+
+ // OK - all set.
+ $competency = new competency();
+ return $competency->get_records($filters, $sort, $order, $skip, $limit);
+ }
+
+ /**
+ * Perform a search based on the provided filters and return a paginated list of records.
+ *
+ * Requires tool/lp:competencyread capability at the system context.
+ *
+ * @param array $filters A list of filters to apply to the list.
+ * @return int
+ */
+ public static function count_competencies($filters) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ if (!has_any_capability(array('tool/lp:competencyread', 'tool/lp:competencymanage'), $context)) {
+ throw new required_capability_exception($context, 'tool/lp:competencyread', 'nopermission', '');
+ }
+
+ // OK - all set.
+ $competency = new competency();
+ return $competency->count_records($filters);
+ }
+
+ /**
+ * Create a competency framework from a record containing all the data for the class.
+ *
+ * Requires tool/lp:competencymanage capability at the system context.
+ *
+ * @param stdClass $record Record containing all the data for an instance of the class.
+ * @return competency_framework
+ */
+ public static function create_framework(stdClass $record) {
+ // First we do a permissions check.
+ require_capability('tool/lp:competencymanage', context_system::instance());
+
+ // OK - all set.
+ $framework = new competency_framework(0, $record);
+ $id = $framework->create();
+ return $framework;
+ }
+
+ /**
+ * Delete a competency framework by id.
+ *
+ * Requires tool/lp:competencymanage capability at the system context.
+ *
+ * @param int $id The record to delete. This will delete alot of related data - you better be sure.
+ * @return boolean
+ */
+ public static function delete_framework($id) {
+ // First we do a permissions check.
+ require_capability('tool/lp:competencymanage', context_system::instance());
+
+ // OK - all set.
+ $framework = new competency_framework();
+ $framework->set_id($id);
+ return $framework->delete();
+ }
+
+ /**
+ * Update the details for a competency framework.
+ *
+ * Requires tool/lp:competencymanage capability at the system context.
+ *
+ * @param stdClass $record The new details for the framework. Note - must contain an id that points to the framework to update.
+ * @return boolean
+ */
+ public static function update_framework($record) {
+ // First we do a permissions check.
+ require_capability('tool/lp:competencymanage', context_system::instance());
+
+ // OK - all set.
+ $framework = new competency_framework(0, $record);
+ return $framework->update();
+ }
+
+ /**
+ * Read a the details for a single competency framework and return a record.
+ *
+ * Requires tool/lp:competencyread capability at the system context.
+ *
+ * @param int $id The id of the framework to read.
+ * @return stdClass
+ */
+ public static function read_framework($id) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ if (!has_any_capability(array('tool/lp:competencyread', 'tool/lp:competencymanage'), $context)) {
+ throw new required_capability_exception($context, 'tool/lp:competencyread', 'nopermission', '');
+ }
+
+ // OK - all set.
+ return new competency_framework($id);
+ }
+
+ /**
+ * Move the competency framework up or down in the display list.
+ *
+ * Requires tool/lp:competencymanage capability at the system context.
+ *
+ * @param int $frameworkidfrom The framework we are moving.
+ * @param int $frameworkidto Where we are moving to. If moving down, it will go after this framework,
+ * If moving up, it will go before this framework.
+ * @return boolean
+ */
+ public static function reorder_framework($frameworkidfrom, $frameworkidto) {
+ require_capability('tool/lp:competencymanage', context_system::instance());
+ $down = true;
+ $frameworkfrom = new competency_framework($frameworkidfrom);
+ $frameworkto = new competency_framework($frameworkidto);
+
+ $all = self::list_frameworks(array(), 'sortorder', 'ASC', 0, 0);
+
+ if ($frameworkfrom->get_sortorder() > $frameworkto->get_sortorder()) {
+ // We are moving down, so put it after the "to" item.
+ $down = false;
+ }
+
+ foreach ($all as $id => $framework) {
+ $sort = $framework->get_sortorder();
+ if ($down && $sort > $frameworkfrom->get_sortorder() && $sort <= $frameworkto->get_sortorder()) {
+ $framework->set_sortorder($framework->get_sortorder() - 1);
+ $framework->update();
+ } else if (!$down && $sort >= $frameworkto->get_sortorder() && $sort < $frameworkfrom->get_sortorder()) {
+ $framework->set_sortorder($framework->get_sortorder() + 1);
+ $framework->update();
+ }
+ }
+ $frameworkfrom->set_sortorder($frameworkto->get_sortorder());
+ return $frameworkfrom->update();
+ }
+
+ /**
+ * Perform a search based on the provided filters and return a paginated list of records.
+ *
+ * Requires tool/lp:competencyread capability at the system context.
+ *
+ * @param array $filters A list of filters to apply to the list.
+ * @param string $sort The column to sort on
+ * @param string $order ('ASC' or 'DESC')
+ * @param int $skip Number of records to skip (pagination)
+ * @param int $limit Max of records to return (pagination)
+ * @return array of competency_framework
+ */
+ public static function list_frameworks($filters, $sort, $order, $skip, $limit) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ if (!has_any_capability(array('tool/lp:competencyread', 'tool/lp:competencymanage'), $context)) {
+ throw new required_capability_exception($context, 'tool/lp:competencyread', 'nopermission', '');
+ }
+
+ // OK - all set.
+ $framework = new competency_framework();
+ return $framework->get_records($filters, $sort, $order, $skip, $limit);
+ }
+
+ /**
+ * Perform a search based on the provided filters and return a paginated list of records.
+ *
+ * Requires tool/lp:competencyread capability at the system context.
+ *
+ * @param array $filters A list of filters to apply to the list.
+ * @return int
+ */
+ public static function count_frameworks($filters) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ if (!has_any_capability(array('tool/lp:competencyread', 'tool/lp:competencymanage'), $context)) {
+ throw new required_capability_exception($context, 'tool/lp:competencyread', 'nopermission', '');
+ }
+
+ // OK - all set.
+ $framework = new competency_framework();
+ return $framework->count_records($filters);
+ }
+
+ /**
+ * Count all the courses using a competency.
+ *
+ * @param int $competencyid The id of the competency to check.
+ * @return int
+ */
+ public static function count_courses_using_competency($competencyid) {
+
+ // OK - all set.
+ $coursecompetency = new course_competency();
+ $courses = $coursecompetency->list_courses_min($competencyid);
+ $count = 0;
+ // Now check permissions on each course.
+ foreach ($courses as $course) {
+ $context = context_course::instance($course->id);
+ $capabilities = array('tool/lp:coursecompetencyread', 'tool/lp:coursecompetencymanage');
+ if (!has_any_capability($capabilities, $context)) {
+ continue;
+ }
+
+ if (!$course->visible && !has_capability('course:viewhidden', $context)) {
+ continue;
+ }
+
+ $count++;
+ }
+
+ return $count;
+ }
+
+ /**
+ * List all the courses using a competency.
+ *
+ * @param int $competencyid The id of the competency to check.
+ * @return array[stdClass] Array of stdClass containing id and shortname.
+ */
+ public static function list_courses_using_competency($competencyid) {
+
+ // OK - all set.
+ $coursecompetency = new course_competency();
+ $courses = $coursecompetency->list_courses($competencyid);
+ $count = 0;
+ $result = array();
+ // Now check permissions on each course.
+ foreach ($courses as $id => $course) {
+ $context = context_course::instance($course->id);
+ $capabilities = array('tool/lp:coursecompetencyread', 'tool/lp:coursecompetencymanage');
+ if (!has_any_capability($capabilities, $context)) {
+ unset($courses[$id]);
+ continue;
+ }
+
+ if (!$course->visible && !has_capability('course:viewhidden', $context)) {
+ unset($courses[$id]);
+ continue;
+ }
+ $course->fullnameformatted = format_text($course->fullname, array('context' => $context));
+ $course->shortnameformatted = format_text($course->shortname, array('context' => $context));
+ array_push($result, $course);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Count all the competencies in a course.
+ *
+ * @param int $courseid The id of the course to check.
+ * @return int
+ */
+ public static function count_competencies_in_course($courseid) {
+ // First we do a permissions check.
+ $context = context_course::instance($courseid);
+ $onlyvisible = 1;
+
+ $capabilities = array('tool/lp:coursecompetencyread', 'tool/lp:coursecompetencymanage');
+ if (!has_any_capability($capabilities, $context)) {
+ throw new required_capability_exception($context, 'tool/lp:coursecompetencyread', 'nopermission', '');
+ }
+
+ if (has_capability('tool/lp:coursecompetencymanage', $context)) {
+ $onlyvisible = 0;
+ }
+
+ // OK - all set.
+ $coursecompetency = new course_competency();
+ return $coursecompetency->count_competencies($courseid, $onlyvisible);
+ }
+
+ /**
+ * List all the competencies in a course.
+ *
+ * @param int $courseid The id of the course to check.
+ * @return array of competencies
+ */
+ public static function list_competencies_in_course($courseid) {
+ // First we do a permissions check.
+ $context = context_course::instance($courseid);
+ $onlyvisible = 1;
+
+ $capabilities = array('tool/lp:coursecompetencyread', 'tool/lp:coursecompetencymanage');
+ if (!has_any_capability($capabilities, $context)) {
+ throw new required_capability_exception($context, 'tool/lp:coursecompetencyread', 'nopermission', '');
+ }
+
+ if (has_capability('tool/lp:coursecompetencymanage', $context)) {
+ $onlyvisible = 0;
+ }
+
+ // OK - all set.
+ $coursecompetency = new course_competency();
+ return $coursecompetency->list_competencies($courseid, $onlyvisible);
+ }
+
+ /**
+ * Add a competency to this course.
+ *
+ * @param int $courseid The id of the course
+ * @param int $competencyid The id of the competency
+ * @return bool
+ */
+ public static function add_competency_to_course($courseid, $competencyid) {
+ // First we do a permissions check.
+ $context = context_course::instance($courseid);
+
+ if (!has_capability('tool/lp:coursecompetencymanage', $context)) {
+ throw new required_capability_exception($context, 'tool/lp:coursecompetencymanage', 'nopermission', '');
+ }
+ $record = new stdClass();
+ $record->courseid = $courseid;
+ $record->competencyid = $competencyid;
+
+ $competency = new competency();
+ $competency->set_id($competencyid);
+ if (!$competency->read()) {
+ throw new coding_exception('The competency does not exist');
+ }
+
+ $coursecompetency = new course_competency();
+ $exists = $coursecompetency->get_records(array('courseid' => $courseid, 'competencyid' => $competencyid));
+ if (!$exists) {
+ $coursecompetency->from_record($record);
+ if ($coursecompetency->create()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Remove a competency from this course.
+ *
+ * @param int $courseid The id of the course
+ * @param int $competencyid The id of the competency
+ * @return bool
+ */
+ public static function remove_competency_from_course($courseid, $competencyid) {
+ // First we do a permissions check.
+ $context = context_course::instance($courseid);
+
+ if (!has_capability('tool/lp:coursecompetencymanage', $context)) {
+ throw new required_capability_exception($context, 'tool/lp:coursecompetencymanage', 'nopermission', '');
+ }
+ $record = new stdClass();
+ $record->courseid = $courseid;
+ $record->competencyid = $competencyid;
+
+ $competency = new competency();
+ $competency->set_id($competencyid);
+ if (!$competency->read()) {
+ throw new coding_exception('The competency does not exist');
+ }
+
+ $coursecompetency = new course_competency();
+ $exists = $coursecompetency->get_records(array('courseid' => $courseid, 'competencyid' => $competencyid));
+ if ($exists) {
+ $competency = array_pop($exists);
+ return $competency->delete();
+ }
+ return false;
+ }
+
+ /**
+ * Move the course competency up or down in the display list.
+ *
+ * Requires tool/lp:coursecompetencymanage capability at the course context.
+ *
+ * @param int $courseid The course
+ * @param int $competencyidfrom The id of the competency we are moving.
+ * @param int $competencyidto The id of the competency we are moving to.
+ * @return boolean
+ */
+ public static function reorder_course_competency($courseid, $competencyidfrom, $competencyidto) {
+ // First we do a permissions check.
+ $context = context_course::instance($courseid);
+
+ if (!has_capability('tool/lp:coursecompetencymanage', $context)) {
+ throw new required_capability_exception($context, 'tool/lp:coursecompetencymanage', 'nopermission', '');
+ }
+
+ $down = true;
+ $coursecompetency = new course_competency();
+ $matches = $coursecompetency->get_records(array('courseid' => $courseid, 'competencyid' => $competencyidfrom));
+ if (count($matches) == 0) {
+ throw new coding_exception('The link does not exist');
+ }
+
+ $competencyfrom = array_pop($matches);
+ $matches = $coursecompetency->get_records(array('courseid' => $courseid, 'competencyid' => $competencyidto));
+ if (count($matches) == 0) {
+ throw new coding_exception('The link does not exist');
+ }
+
+ $competencyto = array_pop($matches);
+
+ $all = $coursecompetency->get_records(array('courseid' => $courseid), 'sortorder', 'ASC', 0, 0);
+
+ if ($competencyfrom->get_sortorder() > $competencyto->get_sortorder()) {
+ // We are moving up, so put it before the "to" item.
+ $down = false;
+ }
+
+ foreach ($all as $id => $coursecompetency) {
+ $sort = $coursecompetency->get_sortorder();
+ if ($down && $sort > $competencyfrom->get_sortorder() && $sort <= $competencyto->get_sortorder()) {
+ $coursecompetency->set_sortorder($coursecompetency->get_sortorder() - 1);
+ $coursecompetency->update();
+ } else if (!$down && $sort >= $competencyto->get_sortorder() && $sort < $competencyfrom->get_sortorder()) {
+ $coursecompetency->set_sortorder($coursecompetency->get_sortorder() + 1);
+ $coursecompetency->update();
+ }
+ }
+ $competencyfrom->set_sortorder($competencyto->get_sortorder());
+ return $competencyfrom->update();
+ }
+
+ /**
+ * Create a learning plan template from a record containing all the data for the class.
+ *
+ * Requires tool/lp:templatemanage capability at the system context.
+ *
+ * @param stdClass $record Record containing all the data for an instance of the class.
+ * @return template
+ */
+ public static function create_template(stdClass $record) {
+ // First we do a permissions check.
+ require_capability('tool/lp:templatemanage', context_system::instance());
+
+ // OK - all set.
+ $template = new template(0, $record);
+ $id = $template->create();
+ return $template;
+ }
+
+ /**
+ * Delete a learning plan template by id.
+ *
+ * Requires tool/lp:templatemanage capability at the system context.
+ *
+ * @param int $id The record to delete.
+ * @return boolean
+ */
+ public static function delete_template($id) {
+ // First we do a permissions check.
+ require_capability('tool/lp:templatemanage', context_system::instance());
+
+ // OK - all set.
+ $template = new template();
+ $template->set_id($id);
+ return $template->delete();
+ }
+
+ /**
+ * Update the details for a learning plan template.
+ *
+ * Requires tool/lp:templatemanage capability at the system context.
+ *
+ * @param stdClass $record The new details for the template. Note - must contain an id that points to the template to update.
+ * @return boolean
+ */
+ public static function update_template($record) {
+ // First we do a permissions check.
+ require_capability('tool/lp:templatemanage', context_system::instance());
+
+ // OK - all set.
+ $template = new template(0, $record);
+ return $template->update();
+ }
+
+ /**
+ * Read a the details for a single learning plan template and return a record.
+ *
+ * Requires tool/lp:templateread capability at the system context.
+ *
+ * @param int $id The id of the template to read.
+ * @return stdClass
+ */
+ public static function read_template($id) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ $caps = array('tool/lp:templateread', 'tool/lp:templatemanage');
+ if (!has_any_capability($caps, $context)) {
+ throw new required_capability_exception($context, 'tool/lp:templateread', 'nopermission', '');
+ }
+
+ // OK - all set.
+ return new template($id);
+ }
+
+ /**
+ * Move the learning plan template up or down in the display list.
+ *
+ * Requires tool/lp:templatemanage capability at the system context.
+ *
+ * @param int $templateidfrom The template we are moving.
+ * @param int $templateidto Where we are moving to. If moving down, it will go after this template,
+ * If moving up, it will go before this template.
+ * @return boolean
+ */
+ public static function reorder_template($templateidfrom, $templateidto) {
+ require_capability('tool/lp:templatemanage', context_system::instance());
+ $down = true;
+ $templatefrom = new template($templateidfrom);
+ $templateto = new template($templateidto);
+
+ $all = self::list_templates(array(), 'sortorder', 'ASC', 0, 0);
+
+ if ($templatefrom->get_sortorder() > $templateto->get_sortorder()) {
+ // We are moving down, so put it after the "to" item.
+ $down = false;
+ }
+
+ foreach ($all as $id => $template) {
+ $sort = $template->get_sortorder();
+ if ($down && $sort > $templatefrom->get_sortorder() && $sort <= $templateto->get_sortorder()) {
+ $template->set_sortorder($template->get_sortorder() - 1);
+ $template->update();
+ } else if (!$down && $sort >= $templateto->get_sortorder() && $sort < $templatefrom->get_sortorder()) {
+ $template->set_sortorder($template->get_sortorder() + 1);
+ $template->update();
+ }
+ }
+ $templatefrom->set_sortorder($templateto->get_sortorder());
+ return $templatefrom->update();
+ }
+
+ /**
+ * Perform a search based on the provided filters and return a paginated list of records.
+ *
+ * Requires tool/lp:templateread capability at the system context.
+ *
+ * @param array $filters A list of filters to apply to the list.
+ * @param string $sort The column to sort on
+ * @param string $order ('ASC' or 'DESC')
+ * @param int $skip Number of records to skip (pagination)
+ * @param int $limit Max of records to return (pagination)
+ * @return array of competency_framework
+ */
+ public static function list_templates($filters, $sort, $order, $skip, $limit) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ $caps = array('tool/lp:templateread', 'tool/lp:templatemanage');
+ if (!has_any_capability($caps, $context)) {
+ throw new required_capability_exception($context, 'tool/lp:templateread', 'nopermission', '');
+ }
+
+ // OK - all set.
+ $template = new template();
+ return $template->get_records($filters, $sort, $order, $skip, $limit);
+ }
+
+ /**
+ * Perform a search based on the provided filters and return how many results there are.
+ *
+ * Requires tool/lp:templateread capability at the system context.
+ *
+ * @param array $filters A list of filters to apply to the list.
+ * @return int
+ */
+ public static function count_templates($filters) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ $caps = array('tool/lp:templateread', 'tool/lp:templatemanage');
+ if (!has_any_capability($caps, $context)) {
+ throw new required_capability_exception($context, 'tool/lp:templateread', 'nopermission', '');
+ }
+
+ // OK - all set.
+ $template = new template();
+ return $template->count_records($filters);
+ }
+
+ /**
+ * Count all the templates using a competency.
+ *
+ * @param int $competencyid The id of the competency to check.
+ * @return int
+ */
+ public static function count_templates_using_competency($competencyid) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ $onlyvisible = 1;
+
+ $capabilities = array('tool/lp:templateread', 'tool/lp:templatemanage');
+ if (!has_any_capability($capabilities, $context)) {
+ throw new required_capability_exception($context, 'tool/lp:templateread', 'nopermission', '');
+ }
+
+ if (has_capability('tool/lp:templatemanage', $context)) {
+ $onlyvisible = 0;
+ }
+
+ // OK - all set.
+ $templatecompetency = new template_competency();
+ return $templatecompetency->count_competencies($templateid, $onlyvisible);
+ }
+
+ /**
+ * List all the learning plan templatesd using a competency.
+ *
+ * @param int $competencyid The id of the competency to check.
+ * @return array[stdClass] Array of stdClass containing id and shortname.
+ */
+ public static function list_templates_using_competency($competencyid) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ $onlyvisible = 1;
+
+ $capabilities = array('tool/lp:templateread', 'tool/lp:templatemanage');
+ if (!has_any_capability($capabilities, $context)) {
+ throw new required_capability_exception($context, 'tool/lp:templateread', 'nopermission', '');
+ }
+
+ if (has_capability('tool/lp:templatemanage', $context)) {
+ $onlyvisible = 0;
+ }
+
+ // OK - all set.
+ $templatecompetency = new template_competency();
+ return $templatecompetency->list_templates($competencyid, $onlyvisible);
+
+ }
+
+ /**
+ * Count all the competencies in a learning plan template.
+ *
+ * @param int $templateid The id of the template to check.
+ * @return int
+ */
+ public static function count_competencies_in_template($templateid) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ $onlyvisible = 1;
+
+ $capabilities = array('tool/lp:templateread', 'tool/lp:templatemanage');
+ if (!has_any_capability($capabilities, $context)) {
+ throw new required_capability_exception($context, 'tool/lp:templateread', 'nopermission', '');
+ }
+
+ if (has_capability('tool/lp:templatemanage', $context)) {
+ $onlyvisible = 0;
+ }
+
+ // OK - all set.
+ $templatecompetency = new template_competency();
+ return $templatecompetency->count_competencies($templateid, $onlyvisible);
+ }
+
+ /**
+ * List all the competencies in a template.
+ *
+ * @param int $templateid The id of the template to check.
+ * @return array of competencies
+ */
+ public static function list_competencies_in_template($templateid) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+ $onlyvisible = 1;
+
+ $capabilities = array('tool/lp:templateread', 'tool/lp:templatemanage');
+ if (!has_any_capability($capabilities, $context)) {
+ throw new required_capability_exception($context, 'tool/lp:templateread', 'nopermission', '');
+ }
+
+ if (has_capability('tool/lp:templatemanage', $context)) {
+ $onlyvisible = 0;
+ }
+
+ // OK - all set.
+ $templatecompetency = new template_competency();
+ return $templatecompetency->list_competencies($templateid, $onlyvisible);
+ }
+
+ /**
+ * Add a competency to this template.
+ *
+ * @param int $templateid The id of the template
+ * @param int $competencyid The id of the competency
+ * @return bool
+ */
+ public static function add_competency_to_template($templateid, $competencyid) {
+ // First we do a permissions check.
+ $context = context_course::instance($courseid);
+
+ require_capability('tool/lp:templatemanage', $context);
+
+ $record = new stdClass();
+ $record->templateid = $templateid;
+ $record->competencyid = $competencyid;
+
+ $competency = new competency();
+ $competency->set_id($competencyid);
+ if (!$competency->read()) {
+ throw new coding_exception('The competency does not exist');
+ }
+
+ $templatecompetency = new template_competency();
+ $exists = $templatecompetency->get_records(array('templateid' => $templateid, 'competencyid' => $competencyid));
+ if (!$exists) {
+ $templatecompetency->from_record($record);
+ if ($templatecompetency->create()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Remove a competency from this template.
+ *
+ * @param int $templateid The id of the template
+ * @param int $competencyid The id of the competency
+ * @return bool
+ */
+ public static function remove_competency_from_template($templateid, $competencyid) {
+ // First we do a permissions check.
+ $context = context_system::instance();
+
+ require_capability('tool/lp:templatemanage', $context);
+
+ $record = new stdClass();
+ $record->templateid = $templateid;
+ $record->competencyid = $competencyid;
+
+ $competency = new competency();
+ $competency->set_id($competencyid);
+ if (!$competency->read()) {
+ throw new coding_exception('The competency does not exist');
+ }
+
+ $template = new template();
+ $template->set_id($template);
+ if (!$template->read()) {
+ throw new coding_exception('The learning plan template does not exist');
+ }
+
+ $templatecompetency = new template_competency();
+ $exists = $templatecompetency->get_records(array('templateid' => $templateid, 'competencyid' => $competencyid));
+ if ($exists) {
+ $link = array_pop($exists);
+ return $link->delete();
+ }
+ return false;
+ }
+}
diff --git a/admin/tool/lp/classes/competency.php b/admin/tool/lp/classes/competency.php
new file mode 100644
index 00000000000..77449c1a74e
--- /dev/null
+++ b/admin/tool/lp/classes/competency.php
@@ -0,0 +1,439 @@
+.
+
+/**
+ * Class for loading/storing competencies from the DB.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_lp;
+
+use stdClass;
+use context_system;
+
+/**
+ * Class for loading/storing competencies from the DB.
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class competency extends persistent {
+
+ /** @var string $shortname Short name for this competency */
+ private $shortname = '';
+
+ /** @var string $idnumber Unique idnumber for this competency - must be unique within the framework if it is non-empty */
+ private $idnumber = '';
+
+ /** @var string $description Description for this competency */
+ private $description = '';
+
+ /** @var int $descriptionformat Format for the description */
+ private $descriptionformat = 0;
+
+ /** @var int $sortorder A number used to influence sorting */
+ private $sortorder = 0;
+
+ /** @var bool $visible Used to show/hide this competency */
+ private $visible = true;
+
+ /** @var int $parentid id of the parent of this competency (0 means root competency) */
+ private $parentid = 0;
+
+ /** @var string $path ids of all the parents up the tree separated with slashes */
+ private $path = '/0/';
+
+ /** @var int $id of the competency framework this competency belongs to */
+ private $competencyframeworkid = 0;
+
+ /**
+ * Method that provides the table name matching this class.
+ *
+ * @return string
+ */
+ public function get_table_name() {
+ return 'tool_lp_competency';
+ }
+
+ /**
+ * Get the short name.
+ *
+ * @return string The short name
+ */
+ public function get_shortname() {
+ return $this->shortname;
+ }
+
+ /**
+ * Set the short name.
+ *
+ * @param string $shortname The short name
+ */
+ public function set_shortname($shortname) {
+ $this->shortname = $shortname;
+ }
+
+ /**
+ * Get the description format.
+ *
+ * @return int The description format
+ */
+ public function get_descriptionformat() {
+ return $this->descriptionformat;
+ }
+
+ /**
+ * Set the description format
+ *
+ * @param int $descriptionformat The description format
+ */
+ public function set_descriptionformat($descriptionformat) {
+ $this->descriptionformat = $descriptionformat;
+ }
+
+ /**
+ * Get the id number.
+ *
+ * @return string The id number
+ */
+ public function get_idnumber() {
+ return $this->idnumber;
+ }
+
+ /**
+ * Set the id number.
+ *
+ * @param string $idnumber The id number
+ */
+ public function set_idnumber($idnumber) {
+ $this->idnumber = $idnumber;
+ }
+
+ /**
+ * Get the description.
+ *
+ * @return string The description
+ */
+ public function get_description() {
+ return $this->description;
+ }
+
+ /**
+ * Set the description.
+ *
+ * @param string $description The description
+ */
+ public function set_description($description) {
+ $this->description = $description;
+ }
+
+ /**
+ * Get the sort order index.
+ *
+ * @return string The sort order index
+ */
+ public function get_sortorder() {
+ return $this->sortorder;
+ }
+
+ /**
+ * Set the sort order index.
+ *
+ * @param string $sortorder The sort order index
+ */
+ public function set_sortorder($sortorder) {
+ $this->sortorder = $sortorder;
+ }
+
+ /**
+ * Get the visible flag.
+ *
+ * @return string The visible flag
+ */
+ public function get_visible() {
+ return $this->visible;
+ }
+
+ /**
+ * Set the visible flag.
+ *
+ * @param string $visible The visible flag
+ */
+ public function set_visible($visible) {
+ $this->visible = $visible;
+ }
+
+ /**
+ * Get the parentid
+ *
+ * @return int The id of the parent
+ */
+ public function get_parentid() {
+ return $this->parentid;
+ }
+
+ /**
+ * Set the parent id
+ *
+ * @param int $parentid The parent id number (can be null)
+ */
+ public function set_parentid($id) {
+ $this->parentid = $id;
+ }
+
+ /**
+ * Get the path
+ *
+ * @return string The ids of all the parents joined with a slash.
+ */
+ public function get_path() {
+ return $this->path;
+ }
+
+ /**
+ * Set the path.
+ *
+ * @param string $path The ids of all the parents joined with a slash.
+ */
+ public function set_path($path) {
+ $this->path = $path;
+ }
+
+ /**
+ * Get the competencyframeworkid
+ *
+ * @return int The competency framework id.
+ */
+ public function get_competencyframeworkid() {
+ return $this->competencyframeworkid;
+ }
+
+ /**
+ * Set the competencyframeworkid.
+ *
+ * @param int $competencyframeworkid The competency framework id.
+ */
+ public function set_competencyframeworkid($competencyframeworkid) {
+ $this->competencyframeworkid = $competencyframeworkid;
+ }
+
+ /**
+ * Populate this class with data from a DB record.
+ *
+ * @param stdClass $record A DB record.
+ * @return framework
+ */
+ public function from_record($record) {
+ if (isset($record->id)) {
+ $this->set_id($record->id);
+ }
+ if (isset($record->shortname)) {
+ $this->set_shortname($record->shortname);
+ }
+ if (isset($record->idnumber)) {
+ $this->set_idnumber($record->idnumber);
+ }
+ if (isset($record->description)) {
+ $this->set_description($record->description);
+ }
+ if (isset($record->descriptionformat)) {
+ $this->set_descriptionformat($record->descriptionformat);
+ }
+ if (isset($record->sortorder)) {
+ $this->set_sortorder($record->sortorder);
+ }
+ if (isset($record->visible)) {
+ $this->set_visible($record->visible);
+ }
+ 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);
+ }
+ if (isset($record->competencyframeworkid)) {
+ $this->set_competencyframeworkid($record->competencyframeworkid);
+ }
+ if (isset($record->parentid)) {
+ $this->set_parentid($record->parentid);
+ }
+ if (isset($record->path)) {
+ $this->set_path($record->path);
+ }
+ return $this;
+ }
+
+ /**
+ * Create a DB record from this class.
+ *
+ * @return stdClass
+ */
+ public function to_record() {
+ $record = new stdClass();
+ $record->id = $this->get_id();
+ $record->shortname = $this->get_shortname();
+ $record->idnumber = $this->get_idnumber();
+ $record->description = $this->get_description();
+ $record->descriptionformat = $this->get_descriptionformat();
+ $options = array('context' => context_system::instance());
+ $record->descriptionformatted = format_text($this->get_description(), $this->get_descriptionformat(), $options);
+ $record->sortorder = $this->get_sortorder();
+ $record->visible = $this->get_visible();
+ $record->timecreated = $this->get_timecreated();
+ $record->timemodified = $this->get_timemodified();
+ $record->usermodified = $this->get_usermodified();
+ $record->competencyframeworkid = $this->get_competencyframeworkid();
+ $record->parentid = $this->get_parentid();
+ $record->path = $this->get_path();
+
+ return $record;
+ }
+
+ /**
+ * Add a default for the sortorder field to the default create logic.
+ *
+ * @return persistent
+ */
+ public function create() {
+ if ($this->parentid) {
+ // Load the parent so we can set the path.
+ $parent = new competency($this->parentid);
+ $this->path = $parent->path . $this->parentid . '/';
+ } else {
+ $this->path = '/0/';
+ }
+ $this->sortorder = $this->count_records(array('parentid' => $this->parentid, 'competencyframeworkid' => $this->competencyframeworkid));
+ return parent::create();
+ }
+
+ /**
+ * Fix all paths when moving to a new parent.
+ *
+ * @return persistent
+ */
+ public function update() {
+ global $DB;
+
+ // See if the parentid changed, if so we have work to do.
+ $before = new competency($this->get_id());
+ if ($before->parentid != $this->parentid) {
+ if ($this->parentid) {
+ $parent = new competency($this->parentid);
+ $this->path = $parent->path . $this->parentid . '/';
+ } else {
+ $this->path = '/0/';
+ }
+
+ $search = array('parentid' => $this->parentid,
+ 'competencyframeworkid' => $this->competencyframeworkid);
+ $this->sortorder = $this->count_records($search);
+
+ // We need to fix all the paths of the children.
+ $like = $DB->sql_like('path', '?');
+ $likesearch = $DB->sql_like_escape($before->path . $before->id . '/') . '%';
+ $sql = 'UPDATE {tool_lp_competency} SET path = REPLACE(path, ?, ?) WHERE ' . $like;
+ $DB->execute($sql, array($before->path . $this->id . '/', $this->path . $this->id . '/', $likesearch));
+ }
+ // Do the default update.
+ return parent::update();
+ }
+
+ /**
+ * This does a specialised search that finds all nodes in the tree with matching text on any text like field,
+ * and returns this node and all its parents in a displayable sort order.
+ *
+ * @param string $searchText The text to search for.
+ * @param int $competencyframeworkid The competency framework to limit the search.
+ * @return persistent
+ */
+ public function search($searchText, $competencyframeworkid) {
+ global $DB;
+
+ $like1 = $DB->sql_like('shortname', ':like1', false);
+ $like2 = $DB->sql_like('idnumber', ':like2', false);
+ $like3 = $DB->sql_like('description', ':like3', false);
+
+ $params = array(
+ 'like1' => '%' . $DB->sql_like_escape($searchText) . '%',
+ 'like2' => '%' . $DB->sql_like_escape($searchText) . '%',
+ 'like3' => '%' . $DB->sql_like_escape($searchText) . '%',
+ 'frameworkid' => $competencyframeworkid
+ );
+
+ $sql = 'competencyframeworkid = :frameworkid AND ((' . $like1 . ') OR (' . $like2 . ') OR (' . $like3 . '))';
+ $records = $DB->get_records_select($this->get_table_name(), $sql, $params, 'path, sortorder ASC', '*');
+
+ // Now get all the parents.
+ $parents = array();
+ foreach ($records as $record) {
+ $parents = explode('/', $record->path);
+ foreach ($parents as $parent) {
+ $parents[intval($parent)] = true;
+ }
+ }
+ $parents = array_keys($parents);
+
+ // Skip ones we already fetched.
+ foreach ($parents as $idx => $parent) {
+ if ($parent == 0 || isset($records[$parent])) {
+ unset($parents[$idx]);
+ }
+ }
+
+ if (count($parents)) {
+ list($parentsql, $parentparams) = $DB->get_in_or_equal($parents, SQL_PARAMS_NAMED);
+
+ $parentrecords = $DB->get_records_select($this->get_table_name(), 'id ' . $parentsql, $parentparams, 'path, sortorder ASC', '*');
+
+ foreach ($parentrecords as $id => $record) {
+ $records[$id] = $record;
+ }
+ }
+
+ $instances = array();
+ // Convert to instances of this class.
+ foreach ($records as $record) {
+ $newrecord = new static(0, $record);
+ array_push($instances, $newrecord);
+ }
+ return $instances;
+ }
+
+ /**
+ * Delete a competency (drastic). Will delete all child nodes in the tree.
+ *
+ * @return persistent
+ */
+ public function delete() {
+ global $DB;
+
+ $deletepath = $DB->sql_like_escape($this->path . $this->get_id() . '/') . '%';
+
+ // We need to delete all the children.
+ $like = $DB->sql_like('path', ':deletepath');
+ $DB->delete_records_select('tool_lp_competency', $like, array('deletepath' => $deletepath));
+
+ // And all the links to courses.
+ $DB->delete_records('tool_lp_course_competency', array('competencyid' => $this->get_id()));
+ // Do the default delete.
+ return parent::delete();
+ }
+}
diff --git a/admin/tool/lp/classes/competency_framework.php b/admin/tool/lp/classes/competency_framework.php
new file mode 100644
index 00000000000..a4f3eb85504
--- /dev/null
+++ b/admin/tool/lp/classes/competency_framework.php
@@ -0,0 +1,243 @@
+.
+
+/**
+ * Class for loading/storing competency frameworks from the DB.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_lp;
+
+use stdClass;
+
+/**
+ * Class for loading/storing competency frameworks from the DB.
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class competency_framework extends persistent {
+
+ /** @var string $shortname Short name for this framework */
+ private $shortname = '';
+
+ /** @var string $idnumber Unique idnumber for this framework - must be unique if it is non-empty */
+ private $idnumber = '';
+
+ /** @var string $description Description for this framework */
+ private $description = '';
+
+ /** @var int $descriptionformat Format for the description */
+ private $descriptionformat = 0;
+
+ /** @var int $sortorder A number used to influence sorting */
+ private $sortorder = 0;
+
+ /** @var bool $visible Used to show/hide this framework */
+ private $visible = true;
+
+ /**
+ * Method that provides the table name matching this class.
+ *
+ * @return string
+ */
+ public function get_table_name() {
+ return 'tool_lp_competency_framework';
+ }
+
+ /**
+ * Get the short name.
+ *
+ * @return string The short name
+ */
+ public function get_shortname() {
+ return $this->shortname;
+ }
+
+ /**
+ * Set the short name.
+ *
+ * @param string $shortname The short name
+ */
+ public function set_shortname($shortname) {
+ $this->shortname = $shortname;
+ }
+
+ /**
+ * Get the description format.
+ *
+ * @return int The description format
+ */
+ public function get_descriptionformat() {
+ return $this->descriptionformat;
+ }
+
+ /**
+ * Set the description format
+ *
+ * @param int $descriptionformat The description format
+ */
+ public function set_descriptionformat($descriptionformat) {
+ $this->descriptionformat = $descriptionformat;
+ }
+ /**
+ * Get the id number.
+ *
+ * @return string The id number
+ */
+ public function get_idnumber() {
+ return $this->idnumber;
+ }
+
+ /**
+ * Set the id number.
+ *
+ * @param string $idnumber The id number
+ */
+ public function set_idnumber($idnumber) {
+ $this->idnumber = $idnumber;
+ }
+
+ /**
+ * Get the description.
+ *
+ * @return string The description
+ */
+ public function get_description() {
+ return $this->description;
+ }
+
+ /**
+ * Set the description.
+ *
+ * @param string $description The description
+ */
+ public function set_description($description) {
+ $this->description = $description;
+ }
+
+ /**
+ * Get the sort order index.
+ *
+ * @return string The sort order index
+ */
+ public function get_sortorder() {
+ return $this->sortorder;
+ }
+
+ /**
+ * Set the sort order index.
+ *
+ * @param string $sortorder The sort order index
+ */
+ public function set_sortorder($sortorder) {
+ $this->sortorder = $sortorder;
+ }
+
+ /**
+ * Get the visible flag.
+ *
+ * @return string The visible flag
+ */
+ public function get_visible() {
+ return $this->visible;
+ }
+
+ /**
+ * Set the visible flag.
+ *
+ * @param string $visible The visible flag
+ */
+ public function set_visible($visible) {
+ $this->visible = $visible;
+ }
+
+ /**
+ * Populate this class with data from a DB record.
+ *
+ * @param stdClass $record A DB record.
+ * @return framework
+ */
+ public function from_record($record) {
+ if (isset($record->id)) {
+ $this->set_id($record->id);
+ }
+ if (isset($record->shortname)) {
+ $this->set_shortname($record->shortname);
+ }
+ if (isset($record->idnumber)) {
+ $this->set_idnumber($record->idnumber);
+ }
+ if (isset($record->description)) {
+ $this->set_description($record->description);
+ }
+ if (isset($record->descriptionformat)) {
+ $this->set_descriptionformat($record->descriptionformat);
+ }
+ if (isset($record->sortorder)) {
+ $this->set_sortorder($record->sortorder);
+ }
+ if (isset($record->visible)) {
+ $this->set_visible($record->visible);
+ }
+ 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);
+ }
+ return $this;
+ }
+
+ /**
+ * Create a DB record from this class.
+ *
+ * @return stdClass
+ */
+ public function to_record() {
+ $record = new stdClass();
+ $record->id = $this->get_id();
+ $record->shortname = $this->get_shortname();
+ $record->idnumber = $this->get_idnumber();
+ $record->description = $this->get_description();
+ $record->descriptionformat = $this->get_descriptionformat();
+ $record->descriptionformatted = format_text($this->get_description(), $this->get_descriptionformat());
+ $record->sortorder = $this->get_sortorder();
+ $record->visible = $this->get_visible();
+ $record->timecreated = $this->get_timecreated();
+ $record->timemodified = $this->get_timemodified();
+ $record->usermodified = $this->get_usermodified();
+
+ return $record;
+ }
+
+ /**
+ * Add a default for the sortorder field to the default create logic.
+ *
+ * @return persistent
+ */
+ public function create() {
+ $this->sortorder = $this->count_records();
+ return parent::create();
+ }
+
+
+}
diff --git a/admin/tool/lp/classes/course_competency.php b/admin/tool/lp/classes/course_competency.php
new file mode 100644
index 00000000000..045e0e389a8
--- /dev/null
+++ b/admin/tool/lp/classes/course_competency.php
@@ -0,0 +1,267 @@
+.
+
+/**
+ * Class for loading/storing competencies from the DB.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_lp;
+
+use stdClass;
+use context_system;
+
+/**
+ * Class for loading/storing course_competencies from the DB.
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class course_competency extends persistent {
+
+ /** @var int $courseid The course id */
+ private $courseid = 0;
+
+ /** @var int $competencyid The competency id */
+ private $competencyid = 0;
+
+ /** @var int $sortorder A number used to influence sorting */
+ private $sortorder = 0;
+
+ /**
+ * Method that provides the table name matching this class.
+ *
+ * @return string
+ */
+ public function get_table_name() {
+ return 'tool_lp_course_competency';
+ }
+
+ /**
+ * Get the competency id
+ *
+ * @return int The competency id
+ */
+ public function get_competencyid() {
+ return $this->competencyid;
+ }
+
+ /**
+ * Set the competency id
+ *
+ * @param int $competencyid The competency id
+ */
+ public function set_competencyid($competencyid) {
+ $this->competencyid = $competencyid;
+ }
+
+ /**
+ * Get the sort order index.
+ *
+ * @return string The sort order index
+ */
+ public function get_sortorder() {
+ return $this->sortorder;
+ }
+
+ /**
+ * Set the sort order index.
+ *
+ * @param string $sortorder The sort order index
+ */
+ public function set_sortorder($sortorder) {
+ $this->sortorder = $sortorder;
+ }
+
+ /**
+ * Get the course id
+ *
+ * @return int The course id
+ */
+ public function get_courseid() {
+ return $this->courseid;
+ }
+
+ /**
+ * Set the course id
+ *
+ * @param int $courseid The course id
+ */
+ public function set_courseid($courseid) {
+ $this->courseid = $courseid;
+ }
+
+ /**
+ * Populate this class with data from a DB record.
+ *
+ * @param stdClass $record A DB record.
+ * @return framework
+ */
+ public function from_record($record) {
+ if (isset($record->id)) {
+ $this->set_id($record->id);
+ }
+ if (isset($record->courseid)) {
+ $this->set_courseid($record->courseid);
+ }
+ if (isset($record->competencyid)) {
+ $this->set_competencyid($record->competencyid);
+ }
+ if (isset($record->sortorder)) {
+ $this->set_sortorder($record->sortorder);
+ }
+ 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);
+ }
+ return $this;
+ }
+
+ /**
+ * Create a DB record from this class.
+ *
+ * @return stdClass
+ */
+ public function to_record() {
+ $record = new stdClass();
+ $record->id = $this->get_id();
+ $record->courseid = $this->get_courseid();
+ $record->competencyid = $this->get_competencyid();
+ $record->sortorder = $this->get_sortorder();
+ $record->timecreated = $this->get_timecreated();
+ $record->timemodified = $this->get_timemodified();
+ $record->usermodified = $this->get_usermodified();
+
+ return $record;
+ }
+
+ /**
+ * Return the course ids and visible flags that include this competency. Only the ids and visible flag are returned,
+ * for the full records use list_courses.
+ *
+ * @param int $competencyid The competency id
+ * @return int
+ */
+ public function list_courses_min($competencyid) {
+ global $DB;
+
+ $results = $DB->get_records_sql('SELECT course.id as id, course.visible as visible
+ FROM {' . self::get_table_name() . '} coursecomp
+ JOIN {course} course
+ ON coursecomp.courseid = course.id
+ WHERE coursecomp.competencyid = ? ', array($competencyid));
+
+ return $results;
+ }
+
+ /**
+ * Return partial course records foreach course that contains this competency.
+ *
+ * @param int $competencyid The competency id
+ * @return array[stdClass] Array of course records containg id, visible, shortname, idnumber, fullname
+ */
+ public function list_courses($competencyid) {
+ global $DB;
+
+ $results = $DB->get_records_sql('SELECT course.id, course.visible, course.shortname, course.idnumber, course.fullname
+ FROM {course} course
+ JOIN {' . self::get_table_name() . '} coursecomp
+ ON coursecomp.courseid = course.id
+ WHERE coursecomp.competencyid = ? ', array($competencyid));
+
+ return $results;
+ }
+
+ /**
+ * Count the competencies in this course.
+ *
+ * @param int $courseid The course id
+ * @param bool $onlyvisible If true, only count visible competencies in this course.
+ * @return int
+ */
+ public function count_competencies($courseid, $onlyvisible) {
+ global $DB;
+
+
+ $sql = 'SELECT COUNT(comp.id)
+ FROM {' . self::get_table_name() . '} coursecomp
+ JOIN {' . competency::get_table_name() . '} comp
+ ON coursecomp.competencyid = comp.id
+ WHERE coursecomp.courseid = ? ';
+ $params = array($courseid);
+
+ if ($onlyvisible) {
+ $sql .= ' AND comp.visible = ?';
+ $params[] = 1;
+ }
+
+ $results = $DB->count_records_sql($sql, $params);
+
+ return $results;
+ }
+
+ /**
+ * List the competencies in this course.
+ *
+ * @param int $courseid The course id
+ * @param bool $onlyvisible If true, only count visible competencies in this course.
+ * @return array[competency]
+ */
+ public function list_competencies($courseid, $onlyvisible) {
+ global $DB;
+
+ $competency = new competency();
+
+ $sql = 'SELECT comp.*
+ FROM {' . $competency->get_table_name() . '} comp
+ JOIN {' . self::get_table_name() . '} coursecomp
+ ON coursecomp.competencyid = comp.id
+ WHERE coursecomp.courseid = ? ORDER BY coursecomp.sortorder ASC';
+ $params = array($courseid);
+
+ if ($onlyvisible) {
+ $sql .= ' AND comp.visible = ?';
+ $params[] = 1;
+ }
+
+ $results = $DB->get_records_sql($sql, $params);
+
+ $instances = array();
+ foreach ($results as $result) {
+ array_push($instances, new competency(0, $result));
+ }
+
+ return $instances;
+ }
+
+ /**
+ * Add a default for the sortorder field to the default create logic.
+ *
+ * @return persistent
+ */
+ public function create() {
+ $this->sortorder = $this->count_records(array('courseid' => $this->get_courseid()));
+ return parent::create();
+ }
+
+}
diff --git a/admin/tool/lp/classes/external.php b/admin/tool/lp/classes/external.php
new file mode 100644
index 00000000000..f63ab611de4
--- /dev/null
+++ b/admin/tool/lp/classes/external.php
@@ -0,0 +1,2956 @@
+.
+
+/**
+ * This is the external API for this tool.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_lp;
+
+require_once("$CFG->libdir/externallib.php");
+
+use external_api;
+use external_function_parameters;
+use external_value;
+use external_format_value;
+use external_single_structure;
+use external_multiple_structure;
+use invalid_parameter_exception;
+
+/**
+ * This is the external API for this tool.
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class external extends external_api {
+
+ /**
+ * Returns description of a generic list() parameters.
+ *
+ * @return external_function_parameters
+ */
+ protected static function list_parameters_structure() {
+ $filters = new external_multiple_structure(new external_single_structure(
+ array(
+ 'column' => new external_value(PARAM_ALPHANUMEXT, 'Column name to filter by'),
+ 'value' => new external_value(PARAM_TEXT, 'Value to filter by. Must be exact match')
+ )
+ ));
+ $sort = new external_value(
+ PARAM_ALPHANUMEXT,
+ 'Column to sort by.',
+ VALUE_DEFAULT,
+ ''
+ );
+ $order = new external_value(
+ PARAM_ALPHA,
+ 'Sort direction. Should be either ASC or DESC',
+ VALUE_DEFAULT,
+ ''
+ );
+ $skip = new external_value(
+ PARAM_INT,
+ 'Skip this number of records before returning results',
+ VALUE_DEFAULT,
+ 0
+ );
+ $limit = new external_value(
+ PARAM_INT,
+ 'Return this number of records at most.',
+ VALUE_DEFAULT,
+ 0
+ );
+
+ $params = array(
+ 'filters' => $filters,
+ 'sort' => $sort,
+ 'order' => $order,
+ 'skip' => $skip,
+ 'limit' => $limit
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Returns description of a generic count_x() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function count_parameters_structure() {
+ $filters = new external_multiple_structure(new external_single_structure(
+ array(
+ 'column' => new external_value(PARAM_ALPHANUMEXT, 'Column name to filter by'),
+ 'value' => new external_value(PARAM_TEXT, 'Value to filter by. Must be exact match')
+ )
+ ));
+
+ $params = array(
+ 'filters' => $filters,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Returns the external structure of a full competency_framework record.
+ *
+ * @return external_single_structure
+ */
+ protected static function get_competency_framework_external_structure() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Database record id'
+ );
+ $shortname = new external_value(
+ PARAM_TEXT,
+ 'Short name for the competency framework'
+ );
+ $idnumber = new external_value(
+ PARAM_TEXT,
+ 'If provided, must be a unique string to identify this competency framework'
+ );
+ $description = new external_value(
+ PARAM_RAW,
+ 'Description for the framework'
+ );
+ $descriptionformat = new external_format_value(
+ 'Description format for the framework'
+ );
+ $descriptionformatted = new external_value(
+ PARAM_RAW,
+ 'Description that has been formatted for display'
+ );
+ $visible = new external_value(
+ PARAM_BOOL,
+ 'Is this framework visible?'
+ );
+ $sortorder = new external_value(
+ PARAM_INT,
+ 'Relative sort order of this framework'
+ );
+ $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'
+ );
+
+ $returns = array(
+ 'id' => $id,
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'descriptionformatted' => $descriptionformatted,
+ 'visible' => $visible,
+ 'sortorder' => $sortorder,
+ 'timecreated' => $timecreated,
+ 'timemodified' => $timemodified,
+ 'usermodified' => $usermodified,
+ );
+ return new external_single_structure($returns);
+ }
+
+ /**
+ * Returns description of create_competency_framework() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function create_competency_framework_parameters() {
+ $shortname = new external_value(
+ PARAM_TEXT,
+ 'Short name for the competency framework.',
+ VALUE_REQUIRED
+ );
+ $idnumber = new external_value(
+ PARAM_TEXT,
+ 'If provided, must be a unique string to identify this competency framework.',
+ VALUE_DEFAULT,
+ ''
+ );
+ $description = new external_value(
+ PARAM_RAW,
+ 'Optional description for the framework',
+ VALUE_DEFAULT,
+ ''
+ );
+ $descriptionformat = new external_format_value(
+ 'Optional description format for the framework',
+ VALUE_DEFAULT,
+ FORMAT_HTML
+ );
+ $visible = new external_value(
+ PARAM_BOOL,
+ 'Is this framework visible?',
+ VALUE_DEFAULT,
+ true
+ );
+
+ $params = array(
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'visible' => $visible,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function create_competency_framework_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Create a new competency framework
+ *
+ * @param string $shortname The short name
+ * @param string $idnumber The idnumber
+ * @param string $description The description
+ * @param int $descriptionformat The description format
+ * @param bool $visible Is this framework visible.
+ * @return stdClass The new record
+ */
+ public static function create_competency_framework($shortname, $idnumber, $description, $descriptionformat, $visible) {
+ $params = self::validate_parameters(self::create_competency_framework_parameters(),
+ array(
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'visible' => $visible,
+ ));
+
+ $params = (object) $params;
+
+ $result = api::create_framework($params);
+ return $result->to_record();
+ }
+
+ /**
+ * Returns description of create_competency_framework() result value.
+ *
+ * @return external_description
+ */
+ public static function create_competency_framework_returns() {
+ return self::get_competency_framework_external_structure();
+ }
+
+ /**
+ * Returns description of read_competency_framework() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function read_competency_framework_parameters() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Data base record id for the framework',
+ VALUE_REQUIRED
+ );
+
+ $params = array(
+ 'id' => $id,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function read_competency_framework_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Read a competency framework by id.
+ *
+ * @param int $id The id of the framework.
+ * @return stdClass
+ */
+ public static function read_competency_framework($id) {
+ $params = self::validate_parameters(self::read_competency_framework_parameters(),
+ array(
+ 'id' => $id,
+ ));
+
+ $result = api::read_framework($params['id']);
+ return $result->to_record();
+ }
+
+ /**
+ * Returns description of read_competency_framework() result value.
+ *
+ * @return external_description
+ */
+ public static function read_competency_framework_returns() {
+ return self::get_competency_framework_external_structure();
+ }
+
+ /**
+ * Returns description of delete_competency_framework() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function delete_competency_framework_parameters() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Data base record id for the framework',
+ VALUE_REQUIRED
+ );
+
+ $params = array(
+ 'id' => $id,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function delete_competency_framework_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Delete a competency framework
+ *
+ * @param int $id The competency framework id
+ * @return boolean
+ */
+ public static function delete_competency_framework($id) {
+ $params = self::validate_parameters(self::delete_competency_framework_parameters(),
+ array(
+ 'id' => $id,
+ ));
+
+ return api::delete_framework($params['id']);
+ }
+
+ /**
+ * Returns description of delete_competency_framework() result value.
+ *
+ * @return external_description
+ */
+ public static function delete_competency_framework_returns() {
+ return new external_value(PARAM_BOOL, 'True if the delete was successful');
+ }
+
+ /**
+ * Returns description of update_competency_framework() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function update_competency_framework_parameters() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Data base record id for the framework',
+ VALUE_REQUIRED
+ );
+ $shortname = new external_value(
+ PARAM_TEXT,
+ 'Short name for the competency framework.',
+ VALUE_REQUIRED
+ );
+ $idnumber = new external_value(
+ PARAM_TEXT,
+ 'If provided, must be a unique string to identify this competency framework.',
+ VALUE_REQUIRED
+ );
+ $description = new external_value(
+ PARAM_RAW,
+ 'Description for the framework',
+ VALUE_REQUIRED
+ );
+ $descriptionformat = new external_format_value(
+ 'Description format for the framework',
+ VALUE_REQUIRED
+ );
+ $visible = new external_value(
+ PARAM_BOOL,
+ 'Is this framework visible?',
+ VALUE_REQUIRED
+ );
+
+ $params = array(
+ 'id' => $id,
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'visible' => $visible,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function update_competency_framework_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Update an existing competency framework
+ *
+ * @param int $id The competency framework id
+ * @param string $shortname
+ * @param string $idnumber
+ * @param string $description
+ * @param int $descriptionformat
+ * @param boolean $visible
+ * @return boolean
+ */
+ public static function update_competency_framework($id,
+ $shortname,
+ $idnumber,
+ $description,
+ $descriptionformat,
+ $visible) {
+
+ $params = self::validate_parameters(self::update_competency_framework_parameters(),
+ array(
+ 'id' => $id,
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'visible' => $visible
+ ));
+ $params = (object) $params;
+
+ return api::update_framework($params);
+ }
+
+ /**
+ * Returns description of update_competency_framework() result value.
+ *
+ * @return external_description
+ */
+ public static function update_competency_framework_returns() {
+ return new external_value(PARAM_BOOL, 'True if the update was successful');
+ }
+
+ /**
+ * Returns description of list_competency_frameworks() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function list_competency_frameworks_parameters() {
+ return self::list_parameters_structure();
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function list_competency_frameworks_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * List the existing competency frameworks
+ *
+ * @return boolean
+ */
+ public static function list_competency_frameworks($filters, $sort, $order, $skip, $limit) {
+ $params = self::validate_parameters(self::list_competency_frameworks_parameters(),
+ array(
+ 'filters' => $filters,
+ 'sort' => $sort,
+ 'order' => $order,
+ 'skip' => $skip,
+ 'limit' => $limit
+ ));
+
+ if ($params['order'] !== '' && $params['order'] !== 'ASC' && $params['order'] !== 'DESC') {
+ throw new invalid_parameter_exception('Invalid order param. Must be ASC, DESC or empty.');
+ }
+
+ $safefilters = array();
+ $validcolumns = array('id', 'shortname', 'description', 'sortorder', 'idnumber', 'visible');
+ foreach ($params['filters'] as $filter) {
+ if (!in_array($filter->column, $validcolumns)) {
+ throw new invalid_parameter_exception('Filter column was invalid');
+ }
+ $safefilters[$filter->column] = $filter->value;
+ }
+
+ $results = api::list_frameworks($safefilters,
+ $params['sort'],
+ $params['order'],
+ $params['skip'],
+ $params['limit']);
+ $records = array();
+ foreach ($results as $result) {
+ $record = $result->to_record();
+ array_push($records, $record);
+ }
+ return $records;
+ }
+
+ /**
+ * Returns description of list_competency_frameworks() result value.
+ *
+ * @return external_description
+ */
+ public static function list_competency_frameworks_returns() {
+ return new external_multiple_structure(self::get_competency_framework_external_structure());
+ }
+
+ /**
+ * Returns description of count_competency_frameworks() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function count_competency_frameworks_parameters() {
+ $filters = new external_multiple_structure(new external_single_structure(
+ array(
+ 'column' => new external_value(PARAM_ALPHANUMEXT, 'Column name to filter by'),
+ 'value' => new external_value(PARAM_TEXT, 'Value to filter by. Must be exact match')
+ )
+ ));
+
+ $params = array(
+ 'filters' => $filters,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function count_competency_frameworks_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Count the existing competency frameworks
+ *
+ * @return boolean
+ */
+ public static function count_competency_frameworks($filters) {
+ $params = self::validate_parameters(self::count_competency_frameworks_parameters(),
+ array(
+ 'filters' => $filters
+ ));
+
+ $safefilters = array();
+ $validcolumns = array('id', 'shortname', 'description', 'sortorder', 'idnumber', 'visible');
+ foreach ($params['filters'] as $filter) {
+ if (!in_array($filter->column, $validcolumns)) {
+ throw new invalid_parameter_exception('Filter column was invalid');
+ }
+ $safefilters[$filter->column] = $filter->value;
+ }
+
+ return api::count_frameworks($safefilters);
+ }
+
+ /**
+ * Returns description of count_competency_frameworks() result value.
+ *
+ * @return external_description
+ */
+ public static function count_competency_frameworks_returns() {
+ return new external_value(PARAM_INT, 'The number of competency frameworks found.');
+ }
+
+ /**
+ * Returns description of data_for_competency_frameworks_manage_page() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function data_for_competency_frameworks_manage_page_parameters() {
+ // No params required.
+ $params = array();
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function data_for_competency_frameworks_manage_page_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Loads the data required to render the competency_frameworks_manage_page template.
+ *
+ * @return boolean
+ */
+ public static function data_for_competency_frameworks_manage_page() {
+ global $PAGE;
+
+ $renderable = new \tool_lp\output\manage_competency_frameworks_page();
+ $renderer = $PAGE->get_renderer('tool_lp');
+
+ $data = $renderable->export_for_template($renderer);
+
+ return $data;
+ }
+
+ /**
+ * Returns description of data_for_competency_frameworks_manage_page() result value.
+ *
+ * @return external_description
+ */
+ public static function data_for_competency_frameworks_manage_page_returns() {
+ return new external_single_structure(array (
+ 'canmanage' => new external_value(PARAM_BOOL, 'True if this user has permission to manage competency frameworks'),
+ 'competencyframeworks' => new external_multiple_structure(
+ self::get_competency_framework_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')
+ )
+ ));
+
+ }
+
+ /**
+ * Move a competency framework and adjust sort order of all affected.
+ *
+ * @return external_function_parameters
+ */
+ public static function reorder_competency_framework_parameters() {
+ $from = new external_value(
+ PARAM_INT,
+ 'Framework id to reorder.',
+ VALUE_REQUIRED
+ );
+ $to = new external_value(
+ PARAM_INT,
+ 'Framework id to move to.',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'from' => $from,
+ 'to' => $to
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function reorder_competency_framework_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Move this competency_framework to a new relative sort order.
+ *
+ * @param int $from
+ * @param int $to
+ * @return boolean
+ */
+ public static function reorder_competency_framework($from, $to) {
+ $params = self::validate_parameters(self::reorder_competency_framework_parameters(),
+ array(
+ 'from' => $from,
+ 'to' => $to
+ ));
+ return api::reorder_framework($params['from'], $params['to']);
+ }
+
+ /**
+ * Returns description of reorder_competency_framework return value.
+ *
+ * @return external_description
+ */
+ public static function reorder_competency_framework_returns() {
+ return new external_value(PARAM_BOOL, 'True if this framework was moved.');
+ }
+
+ /**
+ * Returns the external structure of a full competency record.
+ *
+ * @return external_single_structure
+ */
+ protected static function get_competency_external_structure() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Database record id'
+ );
+ $shortname = new external_value(
+ PARAM_TEXT,
+ 'Short name for the competency'
+ );
+ $idnumber = new external_value(
+ PARAM_TEXT,
+ 'If provided, must be a unique string to identify this competency'
+ );
+ $description = new external_value(
+ PARAM_RAW,
+ 'Description for the competency'
+ );
+ $descriptionformat = new external_format_value(
+ 'Description format for the competency'
+ );
+ $descriptionformatted = new external_value(
+ PARAM_RAW,
+ 'Description formatted for display'
+ );
+ $visible = new external_value(
+ PARAM_BOOL,
+ 'Is this competency visible?'
+ );
+ $sortorder = new external_value(
+ PARAM_INT,
+ 'Relative sort order of this competency'
+ );
+ $competencyframeworkid = new external_value(
+ PARAM_INT,
+ 'Competency framework id that this competency belongs to'
+ );
+ $parentid = new external_value(
+ PARAM_INT,
+ 'Parent competency id. 0 means top level node.'
+ );
+ $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'
+ );
+ $parentid = new external_value(
+ PARAM_INT,
+ 'The id of the parent competency.'
+ );
+ $path = new external_value(
+ PARAM_RAW,
+ 'The path of parents all the way to the root of the tree.'
+ );
+
+ $returns = array(
+ 'id' => $id,
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'descriptionformatted' => $descriptionformatted,
+ 'visible' => $visible,
+ 'sortorder' => $sortorder,
+ 'timecreated' => $timecreated,
+ 'timemodified' => $timemodified,
+ 'usermodified' => $usermodified,
+ 'parentid' => $parentid,
+ 'competencyframeworkid' => $competencyframeworkid,
+ 'path' => $path,
+ );
+ return new external_single_structure($returns);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function create_competency_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Returns description of create_competency() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function create_competency_parameters() {
+ $shortname = new external_value(
+ PARAM_TEXT,
+ 'Short name for the competency framework.',
+ VALUE_REQUIRED
+ );
+ $idnumber = new external_value(
+ PARAM_TEXT,
+ 'If provided, must be a unique string to identify this competency framework.',
+ VALUE_DEFAULT,
+ ''
+ );
+ $description = new external_value(
+ PARAM_RAW,
+ 'Optional description for the framework',
+ VALUE_DEFAULT,
+ ''
+ );
+ $descriptionformat = new external_format_value(
+ 'Optional description format for the framework',
+ VALUE_DEFAULT,
+ FORMAT_HTML
+ );
+ $visible = new external_value(
+ PARAM_BOOL,
+ 'Is this competency visible?',
+ VALUE_DEFAULT,
+ true
+ );
+ $competencyframeworkid = new external_value(
+ PARAM_INT,
+ 'Which competency framework does this competency belong to?'
+ );
+ $parentid = new external_value(
+ PARAM_INT,
+ 'The parent competency. 0 means this is a top level competency.'
+ );
+
+ $params = array(
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'visible' => $visible,
+ 'competencyframeworkid' => $competencyframeworkid,
+ 'parentid' => $parentid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Create a new competency framework
+ *
+ * @param string $shortname
+ * @param string $idnumber
+ * @param string $description
+ * @param int $descriptionformat
+ * @param bool $visible
+ * @param int $competencyframeworkid
+ * @param int $parentid
+ * @return string the template
+ */
+ public static function create_competency($shortname,
+ $idnumber,
+ $description,
+ $descriptionformat,
+ $visible,
+ $competencyframeworkid,
+ $parentid) {
+ $params = self::validate_parameters(self::create_competency_parameters(),
+ array(
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'visible' => $visible,
+ 'competencyframeworkid' => $competencyframeworkid,
+ 'parentid' => $parentid,
+ ));
+
+ $params = (object) $params;
+
+ $result = api::create_competency($params);
+ return $result->to_record();
+ }
+
+ /**
+ * Returns description of create_competency() result value.
+ *
+ * @return external_description
+ */
+ public static function create_competency_returns() {
+ return self::get_competency_external_structure();
+ }
+
+ /**
+ * Returns description of read_competency() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function read_competency_parameters() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Data base record id for the competency',
+ VALUE_REQUIRED
+ );
+
+ $params = array(
+ 'id' => $id,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function read_competency_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Read a competency by id.
+ *
+ * @param int $id The id of the competency
+ * @return stdClass
+ */
+ public static function read_competency($id) {
+ $params = self::validate_parameters(self::read_competency_parameters(),
+ array(
+ 'id' => $id,
+ ));
+
+ $result = api::read_competency($params['id']);
+ return $result->to_record();
+ }
+
+ /**
+ * Returns description of read_competency() result value.
+ *
+ * @return external_description
+ */
+ public static function read_competency_returns() {
+ return self::get_competency_external_structure();
+ }
+
+ /**
+ * Returns description of delete_competency() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function delete_competency_parameters() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Data base record id for the competency',
+ VALUE_REQUIRED
+ );
+
+ $params = array(
+ 'id' => $id,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function delete_competency_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Delete a competency
+ *
+ * @param int $id The competency id
+ * @return boolean
+ */
+ public static function delete_competency($id) {
+ $params = self::validate_parameters(self::delete_competency_parameters(),
+ array(
+ 'id' => $id,
+ ));
+
+ return api::delete_competency($params['id']);
+ }
+
+ /**
+ * Returns description of delete_competency() result value.
+ *
+ * @return external_description
+ */
+ public static function delete_competency_returns() {
+ return new external_value(PARAM_BOOL, 'True if the delete was successful');
+ }
+
+ /**
+ * Returns description of update_competency() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function update_competency_parameters() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Data base record id for the competency',
+ VALUE_REQUIRED
+ );
+ $shortname = new external_value(
+ PARAM_TEXT,
+ 'Short name for the competency.',
+ VALUE_REQUIRED
+ );
+ $idnumber = new external_value(
+ PARAM_TEXT,
+ 'If provided, must be a unique string to identify this competency.',
+ VALUE_REQUIRED
+ );
+ $description = new external_value(
+ PARAM_RAW,
+ 'Description for the framework',
+ VALUE_REQUIRED
+ );
+ $descriptionformat = new external_format_value(
+ 'Description format for the framework',
+ VALUE_REQUIRED
+ );
+ $visible = new external_value(
+ PARAM_BOOL,
+ 'Is this framework visible?',
+ VALUE_REQUIRED
+ );
+
+ $params = array(
+ 'id' => $id,
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'visible' => $visible,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function update_competency_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Update an existing competency
+ *
+ * @param int $id The competency id
+ * @param string $shortname
+ * @param string $idnumber
+ * @param string $description
+ * @param int $descriptionformat
+ * @param boolean $visible
+ * @return boolean
+ */
+ public static function update_competency($id,
+ $shortname,
+ $idnumber,
+ $description,
+ $descriptionformat,
+ $visible) {
+
+ $params = self::validate_parameters(self::update_competency_parameters(),
+ array(
+ 'id' => $id,
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'visible' => $visible
+ ));
+ $params = (object) $params;
+
+ return api::update_competency($params);
+ }
+
+ /**
+ * Returns description of update_competency_framework() result value.
+ *
+ * @return external_description
+ */
+ public static function update_competency_returns() {
+ return new external_value(PARAM_BOOL, 'True if the update was successful');
+ }
+
+ /**
+ * Returns description of list_competencies() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function list_competencies_parameters() {
+ return self::list_parameters_structure();
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function list_competencies_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * List the existing competency frameworks
+ *
+ * @return boolean
+ */
+ public static function list_competencies($filters, $sort, $order, $skip, $limit) {
+ $params = self::validate_parameters(self::list_competencies_parameters(),
+ array(
+ 'filters' => $filters,
+ 'sort' => $sort,
+ 'order' => $order,
+ 'skip' => $skip,
+ 'limit' => $limit
+ ));
+
+ if ($params['order'] !== '' && $params['order'] !== 'ASC' && $params['order'] !== 'DESC') {
+ throw new invalid_parameter_exception('Invalid order param. Must be ASC, DESC or empty.');
+ }
+
+ $safefilters = array();
+ $validcolumns = array('id', 'shortname', 'description', 'sortorder', 'idnumber', 'visible', 'parentid', 'competencyframeworkid');
+ foreach ($params['filters'] as $filter) {
+ if (!in_array($filter->column, $validcolumns)) {
+ throw new invalid_parameter_exception('Filter column was invalid');
+ }
+ $safefilters[$filter->column] = $filter->value;
+ }
+
+ $results = api::list_competencies($safefilters,
+ $params['sort'],
+ $params['order'],
+ $params['skip'],
+ $params['limit']);
+ $records = array();
+ foreach ($results as $result) {
+ $record = $result->to_record();
+ array_push($records, $record);
+ }
+ return $records;
+ }
+
+ /**
+ * Returns description of list_competencies() result value.
+ *
+ * @return external_description
+ */
+ public static function list_competencies_returns() {
+ return new external_multiple_structure(self::get_competency_external_structure());
+ }
+
+ /**
+ * Returns description of search_competencies() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function search_competencies_parameters() {
+ $searchtext = new external_value(
+ PARAM_RAW,
+ 'Text to search for',
+ VALUE_REQUIRED
+ );
+ $frameworkid = new external_value(
+ PARAM_INT,
+ 'Competency framework id',
+ VALUE_REQUIRED
+ );
+
+ $params = array(
+ 'searchtext' => $searchtext,
+ 'competencyframeworkid' => $frameworkid
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function search_competencies_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * List the existing competency frameworks
+ *
+ * @return boolean
+ */
+ public static function search_competencies($searchtext, $competencyframeworkid) {
+ $params = self::validate_parameters(self::search_competencies_parameters(),
+ array(
+ 'searchtext' => $searchtext,
+ 'competencyframeworkid' => $competencyframeworkid
+ ));
+
+ $results = api::search_competencies($searchtext, $competencyframeworkid);
+ $records = array();
+ foreach ($results as $result) {
+ $record = $result->to_record();
+ array_push($records, $record);
+ }
+ return $records;
+ }
+
+ /**
+ * Returns description of search_competencies() result value.
+ *
+ * @return external_description
+ */
+ public static function search_competencies_returns() {
+ return new external_multiple_structure(self::get_competency_external_structure());
+ }
+
+
+ /**
+ * Returns description of count_competencies() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function count_competencies_parameters() {
+ return self::count_parameters_structure();
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function count_competencies_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Count the existing competency frameworks
+ *
+ * @return boolean
+ */
+ public static function count_competencies($filters) {
+ $params = self::validate_parameters(self::count_competencies_parameters(),
+ array(
+ 'filters' => $filters
+ ));
+
+ $safefilters = array();
+ $validcolumns = array('id', 'shortname', 'description', 'sortorder', 'idnumber', 'visible', 'parentid', 'competencyframeworkid');
+ foreach ($params['filters'] as $filter) {
+ if (!in_array($filter->column, $validcolumns)) {
+ throw new invalid_parameter_exception('Filter column was invalid');
+ }
+ $safefilters[$filter->column] = $filter->value;
+ }
+
+ return api::count_competencies($safefilters);
+ }
+
+ /**
+ * Returns description of count_competencies() result value.
+ *
+ * @return external_description
+ */
+ public static function count_competencies_returns() {
+ return new external_value(PARAM_INT, 'The number of competencies found.');
+ }
+
+ /**
+ * Returns description of data_for_competencies_manage_page() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function data_for_competencies_manage_page_parameters() {
+ $competencyframeworkid = new external_value(
+ PARAM_INT,
+ 'The competency framework id',
+ VALUE_REQUIRED
+ );
+ $search = new external_value(
+ PARAM_RAW,
+ 'A search string',
+ VALUE_DEFAULT,
+ ''
+ );
+ $params = array(
+ 'competencyframeworkid' => $competencyframeworkid,
+ 'search' => $search
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function data_for_competencies_manage_page_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Loads the data required to render the competencies_manage_page template.
+ *
+ * @return boolean
+ */
+ public static function data_for_competencies_manage_page($competencyframeworkid, $search) {
+ global $PAGE;
+ $params = self::validate_parameters(self::data_for_competencies_manage_page_parameters(),
+ array(
+ 'competencyframeworkid' => $competencyframeworkid,
+ 'search' => $search
+ ));
+
+ $framework = new \tool_lp\competency_framework($params['competencyframeworkid']);
+
+ $renderable = new \tool_lp\output\manage_competencies_page($framework, $params['search']);
+ $renderer = $PAGE->get_renderer('tool_lp');
+
+ $data = $renderable->export_for_template($renderer);
+
+ return $data;
+ }
+
+ /**
+ * Returns description of data_for_competencies_manage_page() result value.
+ *
+ * @return external_description
+ */
+ public static function data_for_competencies_manage_page_returns() {
+ return new external_single_structure(array (
+ 'framework' => self::get_competency_framework_external_structure(),
+ 'canmanage' => new external_value(PARAM_BOOL, 'True if this user has permission to manage competency frameworks'),
+ 'competencies' => new external_multiple_structure(
+ self::get_competency_external_structure()
+ )
+ ));
+
+ }
+
+ /**
+ * Returns description of set_parent_competency() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function set_parent_competency_parameters() {
+ $competencyid = new external_value(
+ PARAM_INT,
+ 'The competency id',
+ VALUE_REQUIRED
+ );
+ $parentid = new external_value(
+ PARAM_INT,
+ 'The new competency parent id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'competencyid' => $competencyid,
+ 'parentid' => $parentid
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function set_parent_competency_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Move the competency to a new parent.
+ *
+ * @return boolean
+ */
+ public static function set_parent_competency($competencyid, $parentid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::set_parent_competency_parameters(),
+ array(
+ 'competencyid' => $competencyid,
+ 'parentid' => $parentid
+ ));
+
+ return api::set_parent_competency($competencyid, $parentid);
+ }
+
+ /**
+ * Returns description of set_parent_competency() result value.
+ *
+ * @return external_description
+ */
+ public static function set_parent_competency_returns() {
+ return new external_value(PARAM_BOOL, 'True if the update was successful');
+ }
+
+ /**
+ * Returns description of move_up_competency() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function move_up_competency_parameters() {
+ $competencyid = new external_value(
+ PARAM_INT,
+ 'The competency id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'id' => $competencyid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function move_up_competency_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Change the sort order of a competency.
+ *
+ * @return boolean
+ */
+ public static function move_up_competency($competencyid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::move_up_competency_parameters(),
+ array(
+ 'id' => $competencyid,
+ ));
+
+ return api::move_up_competency($params['id']);
+ }
+
+ /**
+ * Returns description of move_up_competency() result value.
+ *
+ * @return external_description
+ */
+ public static function move_up_competency_returns() {
+ return new external_value(PARAM_BOOL, 'True if the update was successful');
+ }
+
+ /**
+ * Returns description of move_down_competency() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function move_down_competency_parameters() {
+ $competencyid = new external_value(
+ PARAM_INT,
+ 'The competency id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'id' => $competencyid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function move_down_competency_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Change the sort order of a competency.
+ *
+ * @return boolean
+ */
+ public static function move_down_competency($competencyid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::move_down_competency_parameters(),
+ array(
+ 'id' => $competencyid,
+ ));
+
+ return api::move_down_competency($params['id']);
+ }
+
+ /**
+ * Returns description of move_down_competency() result value.
+ *
+ * @return external_description
+ */
+ public static function move_down_competency_returns() {
+ return new external_value(PARAM_BOOL, 'True if the update was successful');
+ }
+
+ /**
+ * Returns description of count_courses_using_competency() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function count_courses_using_competency_parameters() {
+ $competencyid = new external_value(
+ PARAM_INT,
+ 'The competency id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'id' => $competencyid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function count_courses_using_competency_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Count the courses (visible to this user) that use this competency.
+ *
+ * @return int
+ */
+ public static function count_courses_using_competency($competencyid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::count_courses_using_competency_parameters(),
+ array(
+ 'id' => $competencyid,
+ ));
+
+ return api::count_courses_using_competency($params['id']);
+ }
+
+ /**
+ * Returns description of count_courses_using_competency() result value.
+ *
+ * @return external_description
+ */
+ public static function count_courses_using_competency_returns() {
+ return new external_value(PARAM_INT, 'The number of courses using this competency');
+ }
+
+ /**
+ * Returns description of list_courses_using_competency() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function list_courses_using_competency_parameters() {
+ $competencyid = new external_value(
+ PARAM_INT,
+ 'The competency id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'id' => $competencyid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function list_courses_using_competency_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Count the courses (visible to this user) that use this competency.
+ *
+ * @return array
+ */
+ public static function list_courses_using_competency($competencyid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::list_courses_using_competency_parameters(),
+ array(
+ 'id' => $competencyid,
+ ));
+
+ return api::list_courses_using_competency($params['id']);
+ }
+
+ /**
+ * Returns description of list_courses_using_competency() result value.
+ *
+ * @return external_description
+ */
+ public static function list_courses_using_competency_returns() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Course id'
+ );
+ $visible = new external_value(
+ PARAM_BOOL,
+ 'Is the course visible.'
+ );
+ $idnumber = new external_value(
+ PARAM_TEXT,
+ 'Course id number'
+ );
+ $shortname = new external_value(
+ PARAM_TEXT,
+ 'Course short name'
+ );
+ $shortnameformatted = new external_value(
+ PARAM_RAW,
+ 'Shortname that has been formatted for display'
+ );
+ $fullname = new external_value(
+ PARAM_TEXT,
+ 'Course fullname'
+ );
+ $fullnameformatted = new external_value(
+ PARAM_RAW,
+ 'Fullname that has been formatted for display'
+ );
+
+ $returns = array(
+ 'id' => $id,
+ 'shortname' => $shortname,
+ 'shortnameformatted' => $shortnameformatted,
+ 'idnumber' => $idnumber,
+ 'fullname' => $fullname,
+ 'fullnameformatted' => $fullnameformatted,
+ 'visible' => $visible
+ );
+ return new external_multiple_structure(new external_single_structure($returns));
+ }
+
+ /**
+ * Returns description of count_competencies_in_course() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function count_competencies_in_course_parameters() {
+ $courseid = new external_value(
+ PARAM_INT,
+ 'The course id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'id' => $courseid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function count_competencies_in_course_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Count the competencies (visible to this user) in this course.
+ *
+ * @param int $couseid The course id to check.
+ * @return int
+ */
+ public static function count_competencies_in_course($courseid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::count_competencies_in_course_parameters(),
+ array(
+ 'id' => $courseid,
+ ));
+
+ return api::count_competencies_in_course($params['id']);
+ }
+
+ /**
+ * Returns description of count_competencies_in_course() result value.
+ *
+ * @return external_description
+ */
+ public static function count_competencies_in_course_returns() {
+ return new external_value(PARAM_INT, 'The number of competencies in this course.');
+ }
+
+ /**
+ * Returns description of list_competencies_in_course() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function list_competencies_in_course_parameters() {
+ $courseid = new external_value(
+ PARAM_INT,
+ 'The course id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'id' => $courseid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function list_competencies_in_course_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * List the competencies (visible to this user) in this course.
+ *
+ * @return array
+ */
+ public static function list_competencies_in_course($courseid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::list_competencies_in_course_parameters(),
+ array(
+ 'id' => $courseid,
+ ));
+
+ $competencies = api::list_competencies_in_course($params['id']);
+ $results = array();
+ foreach ($competencies as $competency) {
+ $record = $competency->to_record();
+ array_push($results, $record);
+ }
+ return $results;
+ }
+
+ /**
+ * Returns description of list_competencies_in_course() result value.
+ *
+ * @return external_description
+ */
+ public static function list_competencies_in_course_returns() {
+ return new external_multiple_structure(self::get_competency_external_structure());
+ }
+
+ /**
+ * Returns description of add_competency_to_course() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function add_competency_to_course_parameters() {
+ $courseid = new external_value(
+ PARAM_INT,
+ 'The course id',
+ VALUE_REQUIRED
+ );
+ $competencyid = new external_value(
+ PARAM_INT,
+ 'The competency id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'courseid' => $courseid,
+ 'competencyid' => $competencyid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function add_competency_to_course_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Count the competencies (visible to this user) in this course.
+ *
+ * @return int
+ */
+ public static function add_competency_to_course($courseid, $competencyid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::add_competency_to_course_parameters(),
+ array(
+ 'courseid' => $courseid,
+ 'competencyid' => $competencyid,
+ ));
+
+ return api::add_competency_to_course($params['courseid'], $params['competencyid']);
+ }
+
+ /**
+ * Returns description of add_competency_to_course() result value.
+ *
+ * @return external_description
+ */
+ public static function add_competency_to_course_returns() {
+ return new external_value(PARAM_BOOL, 'True if successful.');
+ }
+
+ /**
+ * Returns description of remove_competency_from_course() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function remove_competency_from_course_parameters() {
+ $courseid = new external_value(
+ PARAM_INT,
+ 'The course id',
+ VALUE_REQUIRED
+ );
+ $competencyid = new external_value(
+ PARAM_INT,
+ 'The competency id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'courseid' => $courseid,
+ 'competencyid' => $competencyid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function remove_competency_from_course_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Count the competencies (visible to this user) in this course.
+ *
+ * @return int
+ */
+ public static function remove_competency_from_course($courseid, $competencyid) {
+ $params = self::validate_parameters(self::remove_competency_from_course_parameters(),
+ array(
+ 'courseid' => $courseid,
+ 'competencyid' => $competencyid,
+ ));
+
+ return api::remove_competency_from_course($params['courseid'], $params['competencyid']);
+ }
+
+ /**
+ * Returns description of remove_competency_from_course() result value.
+ *
+ * @return external_description
+ */
+ public static function remove_competency_from_course_returns() {
+ return new external_value(PARAM_BOOL, 'True if successful.');
+ }
+
+ /**
+ * Returns description of data_for_course_competenies_page() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function data_for_course_competencies_page_parameters() {
+ $courseid = new external_value(
+ PARAM_INT,
+ 'The course id',
+ VALUE_REQUIRED
+ );
+ $params = array('courseid' => $courseid);
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function data_for_course_competencies_page_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Loads the data required to render the course_competencies_page template.
+ *
+ * @return boolean
+ */
+ public static function data_for_course_competencies_page($courseid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::data_for_course_competencies_page_parameters(),
+ array(
+ 'courseid' => $courseid,
+ ));
+
+ $renderable = new \tool_lp\output\course_competencies_page($params['courseid']);
+ $renderer = $PAGE->get_renderer('tool_lp');
+
+ $data = $renderable->export_for_template($renderer);
+
+ return $data;
+ }
+
+ /**
+ * Returns description of data_for_course_competencies_page() result value.
+ *
+ * @return external_description
+ */
+ public static function data_for_course_competencies_page_returns() {
+ return new external_single_structure(array (
+ 'courseid' => new external_value(PARAM_INT, 'The current course id'),
+ 'canmanagecompetencyframeworks' => new external_value(PARAM_BOOL, 'User can manage competency frameworks'),
+ 'canmanagecoursecompetencies' => new external_value(PARAM_BOOL, 'User can manage linked course competencies'),
+ 'competencies' => new external_multiple_structure(
+ self::get_competency_external_structure()
+ ),
+ 'manageurl' => new external_value(PARAM_LOCALURL, 'Url to the manage competencies page.'),
+ ));
+
+ }
+
+ /**
+ * Returns description of reorder_course_competency() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function reorder_course_competency_parameters() {
+ $courseid = new external_value(
+ PARAM_INT,
+ 'The course id',
+ VALUE_REQUIRED
+ );
+ $competencyidfrom = new external_value(
+ PARAM_INT,
+ 'The competency id we are moving',
+ VALUE_REQUIRED
+ );
+ $competencyidto = new external_value(
+ PARAM_INT,
+ 'The competency id we are moving to',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'courseid' => $courseid,
+ 'competencyidfrom' => $competencyidfrom,
+ 'competencyidto' => $competencyidto,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function reorder_course_competency_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Change the order of course competencies.
+ *
+ * @param int $courseid The course id
+ * @param int $competencyidfrom The competency to move.
+ * @param int $competencyidto The competency to move to.
+ * @return bool
+ */
+ public static function reorder_course_competency($courseid, $competencyidfrom, $competencyidto) {
+ $params = self::validate_parameters(self::reorder_course_competency_parameters(),
+ array(
+ 'courseid' => $courseid,
+ 'competencyidfrom' => $competencyidfrom,
+ 'competencyidto' => $competencyidto,
+ ));
+
+ return api::reorder_course_competency($params['courseid'], $params['competencyidfrom'], $params['competencyidto']);
+ }
+
+ /**
+ * Returns description of reorder_course_competency() result value.
+ *
+ * @return external_description
+ */
+ public static function reorder_course_competency_returns() {
+ return new external_value(PARAM_BOOL, 'True if successful.');
+ }
+
+ /**
+ * Returns the external structure of a full template record.
+ *
+ * @return external_single_structure
+ */
+ protected static function get_template_external_structure() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Database record id'
+ );
+ $shortname = new external_value(
+ PARAM_TEXT,
+ 'Short name for the learning plan template'
+ );
+ $idnumber = new external_value(
+ PARAM_TEXT,
+ 'If provided, must be a unique string to identify this learning plan template'
+ );
+ $duedate = new external_value(
+ PARAM_INT,
+ 'The default due date for instances of this plan.'
+ );
+ $duedateformatted = new external_value(
+ PARAM_RAW,
+ 'Due date that has been formatted for display'
+ );
+ $description = new external_value(
+ PARAM_RAW,
+ 'Description for the template'
+ );
+ $descriptionformat = new external_format_value(
+ 'Description format for the template'
+ );
+ $descriptionformatted = new external_value(
+ PARAM_RAW,
+ 'Description that has been formatted for display'
+ );
+ $visible = new external_value(
+ PARAM_BOOL,
+ 'Is this template visible?'
+ );
+ $sortorder = new external_value(
+ PARAM_INT,
+ 'Relative sort order of this template'
+ );
+ $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'
+ );
+
+ $returns = array(
+ 'id' => $id,
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'descriptionformatted' => $descriptionformatted,
+ 'visible' => $visible,
+ 'sortorder' => $sortorder,
+ 'timecreated' => $timecreated,
+ 'timemodified' => $timemodified,
+ 'usermodified' => $usermodified,
+ );
+ return new external_single_structure($returns);
+ }
+
+ /**
+ * Returns description of create_template() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function create_template_parameters() {
+ $shortname = new external_value(
+ PARAM_TEXT,
+ 'Short name for the learning plan template.',
+ VALUE_REQUIRED
+ );
+ $idnumber = new external_value(
+ PARAM_TEXT,
+ 'If provided, must be a unique string to identify this learning plan template.',
+ VALUE_DEFAULT,
+ ''
+ );
+ $duedate = new external_value(
+ PARAM_INT,
+ 'The default due date for instances of this plan',
+ VALUE_DEFAULT,
+ 0
+ );
+ $description = new external_value(
+ PARAM_RAW,
+ 'Optional description for the learning plan template',
+ VALUE_DEFAULT,
+ ''
+ );
+ $descriptionformat = new external_format_value(
+ 'Optional description format for the learning plan template',
+ VALUE_DEFAULT,
+ FORMAT_HTML
+ );
+ $visible = new external_value(
+ PARAM_BOOL,
+ 'Is this learning plan template visible?',
+ VALUE_DEFAULT,
+ true
+ );
+
+ $params = array(
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'duedate' => $duedate,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'visible' => $visible,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function create_template_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Create a new learning plan template
+ *
+ * @param string $shortname The short name of the template.
+ * @param string $idnumber The idnumber of the template.
+ * @param int $duedate The due date for instances of this plan.
+ * @param string $description The description of the template.
+ * @param int $descriptionformat The format of the description
+ * @param bool $visible Is this template visible.
+ * @return stdClass Record of new template.
+ */
+ public static function create_template($shortname, $idnumber, $description, $descriptionformat, $visible) {
+ $params = self::validate_parameters(self::create_template_parameters(),
+ array(
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'duedate' => $duedate,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'visible' => $visible,
+ ));
+
+ $params = (object) $params;
+
+ $result = api::create_template($params);
+ return $result->to_record();
+ }
+
+ /**
+ * Returns description of create_template() result value.
+ *
+ * @return external_description
+ */
+ public static function create_template_returns() {
+ return self::get_template_external_structure();
+ }
+
+ /**
+ * Returns description of read_template() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function read_template_parameters() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Data base record id for the template',
+ VALUE_REQUIRED
+ );
+
+ $params = array(
+ 'id' => $id,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function read_template_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Read a learning plan template by id.
+ *
+ * @param int $id The id of the template.
+ * @return stdClass
+ */
+ public static function read_template($id) {
+ $params = self::validate_parameters(self::read_template_parameters(),
+ array(
+ 'id' => $id,
+ ));
+
+ $result = api::read_template($params['id']);
+ return $result->to_record();
+ }
+
+ /**
+ * Returns description of read_template() result value.
+ *
+ * @return external_description
+ */
+ public static function read_template_returns() {
+ return self::get_template_external_structure();
+ }
+
+ /**
+ * Returns description of delete_template() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function delete_template_parameters() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Data base record id for the template',
+ VALUE_REQUIRED
+ );
+
+ $params = array(
+ 'id' => $id,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function delete_template_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Delete a learning plan template
+ *
+ * @param int $id The learning plan template id
+ * @return boolean
+ */
+ public static function delete_template($id) {
+ $params = self::validate_parameters(self::delete_template_parameters(),
+ array(
+ 'id' => $id,
+ ));
+
+ return api::delete_template($params['id']);
+ }
+
+ /**
+ * Returns description of delete_template() result value.
+ *
+ * @return external_description
+ */
+ public static function delete_template_returns() {
+ return new external_value(PARAM_BOOL, 'True if the delete was successful');
+ }
+
+ /**
+ * Returns description of update_template() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function update_template_parameters() {
+ $id = new external_value(
+ PARAM_INT,
+ 'Data base record id for the template',
+ VALUE_REQUIRED
+ );
+ $shortname = new external_value(
+ PARAM_TEXT,
+ 'Short name for the learning plan template.',
+ VALUE_REQUIRED
+ );
+ $idnumber = new external_value(
+ PARAM_TEXT,
+ 'If provided, must be a unique string to identify this learning plan template.',
+ VALUE_REQUIRED
+ );
+ $duedate = new external_value(
+ PARAM_INT,
+ 'Default due date for instances of this plan',
+ VALUE_REQUIRED
+ );
+ $description = new external_value(
+ PARAM_RAW,
+ 'Description for the template',
+ VALUE_REQUIRED
+ );
+ $descriptionformat = new external_format_value(
+ 'Description format for the template',
+ VALUE_REQUIRED
+ );
+ $visible = new external_value(
+ PARAM_BOOL,
+ 'Is this template visible?',
+ VALUE_REQUIRED
+ );
+
+ $params = array(
+ 'id' => $id,
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'duedate' => $duedate,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'visible' => $visible,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function update_template_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Update an existing learning plan template
+ *
+ * @param int $id The learning plan template id
+ * @param string $shortname
+ * @param string $idnumber
+ * @param int $duedate
+ * @param string $description
+ * @param int $descriptionformat
+ * @param boolean $visible
+ * @return boolean
+ */
+ public static function update_template($id,
+ $shortname,
+ $idnumber,
+ $duedate,
+ $description,
+ $descriptionformat,
+ $visible) {
+
+ $params = self::validate_parameters(self::update_template_parameters(),
+ array(
+ 'id' => $id,
+ 'shortname' => $shortname,
+ 'idnumber' => $idnumber,
+ 'duedate' => $duedate,
+ 'description' => $description,
+ 'descriptionformat' => $descriptionformat,
+ 'visible' => $visible
+ ));
+ $params = (object) $params;
+
+ return api::update_template($params);
+ }
+
+ /**
+ * Returns description of update_template() result value.
+ *
+ * @return external_description
+ */
+ public static function update_template_returns() {
+ return new external_value(PARAM_BOOL, 'True if the update was successful');
+ }
+
+ /**
+ * Returns description of list_templates() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function list_templates_parameters() {
+ return self::list_parameters_structure();
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function list_templates_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * List the existing learning plan templates
+ *
+ * @return boolean
+ */
+ public static function list_templates($filters, $sort, $order, $skip, $limit) {
+ $params = self::validate_parameters(self::list_templates_parameters(),
+ array(
+ 'filters' => $filters,
+ 'sort' => $sort,
+ 'order' => $order,
+ 'skip' => $skip,
+ 'limit' => $limit
+ ));
+
+ if ($params['order'] !== '' && $params['order'] !== 'ASC' && $params['order'] !== 'DESC') {
+ throw new invalid_parameter_exception('Invalid order param. Must be ASC, DESC or empty.');
+ }
+
+ $safefilters = array();
+ $validcolumns = array('id', 'shortname', 'description', 'sortorder', 'idnumber', 'visible');
+ foreach ($params['filters'] as $filter) {
+ if (!in_array($filter->column, $validcolumns)) {
+ throw new invalid_parameter_exception('Filter column was invalid');
+ }
+ $safefilters[$filter->column] = $filter->value;
+ }
+
+ $results = api::list_templates($safefilters,
+ $params['sort'],
+ $params['order'],
+ $params['skip'],
+ $params['limit']);
+ $records = array();
+ foreach ($results as $result) {
+ $record = $result->to_record();
+ array_push($records, $record);
+ }
+ return $records;
+ }
+
+ /**
+ * Returns description of list_templates() result value.
+ *
+ * @return external_description
+ */
+ public static function list_templates_returns() {
+ return new external_multiple_structure(self::get_template_external_structure());
+ }
+
+ /**
+ * Returns description of count_templates() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function count_templates_parameters() {
+ $filters = new external_multiple_structure(new external_single_structure(
+ array(
+ 'column' => new external_value(PARAM_ALPHANUMEXT, 'Column name to filter by'),
+ 'value' => new external_value(PARAM_TEXT, 'Value to filter by. Must be exact match')
+ )
+ ));
+
+ $params = array(
+ 'filters' => $filters,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function count_templates_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Count the existing learning plan templates
+ *
+ * @return boolean
+ */
+ public static function count_templates($filters) {
+ $params = self::validate_parameters(self::count_templates_parameters(),
+ array(
+ 'filters' => $filters
+ ));
+
+ $safefilters = array();
+ $validcolumns = array('id', 'shortname', 'description', 'sortorder', 'idnumber', 'visible');
+ foreach ($params['filters'] as $filter) {
+ if (!in_array($filter->column, $validcolumns)) {
+ throw new invalid_parameter_exception('Filter column was invalid');
+ }
+ $safefilters[$filter->column] = $filter->value;
+ }
+
+ return api::count_templates($safefilters);
+ }
+
+ /**
+ * Returns description of count_templates() result value.
+ *
+ * @return external_description
+ */
+ public static function count_templates_returns() {
+ return new external_value(PARAM_INT, 'The number of learning plan templates found.');
+ }
+
+ /**
+ * Move a learning plan template and adjust sort order of all affected.
+ *
+ * @return external_function_parameters
+ */
+ public static function reorder_template_parameters() {
+ $from = new external_value(
+ PARAM_INT,
+ 'Template id to reorder.',
+ VALUE_REQUIRED
+ );
+ $to = new external_value(
+ PARAM_INT,
+ 'Template id to move to.',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'from' => $from,
+ 'to' => $to
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function reorder_template_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Move this template to a new relative sort order.
+ *
+ * @param int $from
+ * @param int $to
+ * @return boolean
+ */
+ public static function reorder_template($from, $to) {
+ $params = self::validate_parameters(self::reorder_template_parameters(),
+ array(
+ 'from' => $from,
+ 'to' => $to
+ ));
+ return api::reorder_template($params['from'], $params['to']);
+ }
+
+ /**
+ * Returns description of reorder_template return value.
+ *
+ * @return external_description
+ */
+ public static function reorder_template_returns() {
+ return new external_value(PARAM_BOOL, 'True if this template was moved.');
+ }
+
+ /**
+ * Returns description of data_for_templates_manage_page() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function data_for_templates_manage_page_parameters() {
+ // No params required.
+ $params = array();
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function data_for_templates_manage_page_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Loads the data required to render the templates_manage_page template.
+ *
+ * @return boolean
+ */
+ public static function data_for_templates_manage_page() {
+ global $PAGE;
+
+ $renderable = new \tool_lp\output\manage_templates_page();
+ $renderer = $PAGE->get_renderer('tool_lp');
+
+ $data = $renderable->export_for_template($renderer);
+
+ return $data;
+ }
+
+ /**
+ * Returns description of data_for_templates_manage_page() result value.
+ *
+ * @return external_description
+ */
+ public static function data_for_templates_manage_page_returns() {
+ return new external_single_structure(array (
+ 'canmanage' => new external_value(PARAM_BOOL, 'True if this user has permission to manage learning plan templates'),
+ 'templates' => new external_multiple_structure(
+ self::get_template_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')
+ )
+ ));
+
+ }
+
+ /**
+ * Returns description of count_templates_using_competency() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function count_templates_using_competency_parameters() {
+ $competencyid = new external_value(
+ PARAM_INT,
+ 'The competency id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'id' => $competencyid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function count_templates_using_competency_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Count the learning plan templates (visible to this user) that use this competency.
+ *
+ * @return int
+ */
+ public static function count_templates_using_competency($competencyid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::count_templates_using_competency_parameters(),
+ array(
+ 'id' => $competencyid,
+ ));
+
+ return api::count_templates_using_competency($params['id']);
+ }
+
+ /**
+ * Returns description of count_templates_using_competency() result value.
+ *
+ * @return external_description
+ */
+ public static function count_templates_using_competency_returns() {
+ return new external_value(PARAM_INT, 'The number of learning plan templates using this competency');
+ }
+
+ /**
+ * Returns description of list_templates_using_competency() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function list_templates_using_competency_parameters() {
+ $competencyid = new external_value(
+ PARAM_INT,
+ 'The competency id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'id' => $competencyid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function list_templates_using_competency_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * List the learning plan templates (visible to this user) that use this competency.
+ *
+ * @return array
+ */
+ public static function list_templates_using_competency($competencyid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::list_templates_using_competency_parameters(),
+ array(
+ 'id' => $competencyid,
+ ));
+
+ return api::list_templates_using_competency($params['id']);
+ }
+
+ /**
+ * Returns description of list_templates_using_competency() result value.
+ *
+ * @return external_description
+ */
+ public static function list_templates_using_competency_returns() {
+ return new external_multiple_structure(self::get_template_external_structure());
+ }
+
+ /**
+ * Returns description of count_competencies_in_template() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function count_competencies_in_template_parameters() {
+ $templateid = new external_value(
+ PARAM_INT,
+ 'The template id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'id' => $templateid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function count_competencies_in_template_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Count the competencies (visible to this user) in this learning plan template.
+ *
+ * @param int $templateid The template id to check
+ * @return int
+ */
+ public static function count_competencies_in_template($templateid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::count_competencies_in_template_parameters(),
+ array(
+ 'id' => $templateid,
+ ));
+
+ return api::count_competencies_in_template($params['id']);
+ }
+
+ /**
+ * Returns description of count_competencies_in_template() result value.
+ *
+ * @return external_description
+ */
+ public static function count_competencies_in_template_returns() {
+ return new external_value(PARAM_INT, 'The number of competencies in this learning plan template.');
+ }
+
+ /**
+ * Returns description of list_competencies_in_template() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function list_competencies_in_template_parameters() {
+ $templateid = new external_value(
+ PARAM_INT,
+ 'The template id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'id' => $courseid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function list_competencies_in_template_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * List the competencies (visible to this user) in this learning plan template.
+ *
+ * @return array
+ */
+ public static function list_competencies_in_template($templateid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::list_competencies_in_template_parameters(),
+ array(
+ 'id' => $templateid,
+ ));
+
+ $competencies = api::list_competencies_in_template($params['id']);
+ $results = array();
+ foreach ($competencies as $competency) {
+ $record = $competency->to_record();
+ array_push($results, $record);
+ }
+ return $results;
+ }
+
+ /**
+ * Returns description of list_competencies_in_template() result value.
+ *
+ * @return external_description
+ */
+ public static function list_competencies_in_template_returns() {
+ return new external_multiple_structure(self::get_competency_external_structure());
+ }
+
+ /**
+ * Returns description of add_competency_to_template() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function add_competency_to_template_parameters() {
+ $templateid = new external_value(
+ PARAM_INT,
+ 'The template id',
+ VALUE_REQUIRED
+ );
+ $competencyid = new external_value(
+ PARAM_INT,
+ 'The competency id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'templateid' => $templateid,
+ 'competencyid' => $competencyid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function add_competency_to_template_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Count the competencies (visible to this user) in this template.
+ *
+ * @return int
+ */
+ public static function add_competency_to_template($templateid, $competencyid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::add_competency_to_template_parameters(),
+ array(
+ 'templateid' => $templateid,
+ 'competencyid' => $competencyid,
+ ));
+
+ return api::add_competency_to_template($params['templateid'], $params['competencyid']);
+ }
+
+ /**
+ * Returns description of add_competency_to_template() result value.
+ *
+ * @return external_description
+ */
+ public static function add_competency_to_template_returns() {
+ return new external_value(PARAM_BOOL, 'True if successful.');
+ }
+
+ /**
+ * Returns description of remove_competency_from_template() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function remove_competency_from_template_parameters() {
+ $templateid = new external_value(
+ PARAM_INT,
+ 'The template id',
+ VALUE_REQUIRED
+ );
+ $competencyid = new external_value(
+ PARAM_INT,
+ 'The competency id',
+ VALUE_REQUIRED
+ );
+ $params = array(
+ 'templateid' => $templateid,
+ 'competencyid' => $competencyid,
+ );
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function remove_competency_from_template_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Count the competencies (visible to this user) in this learning plan template.
+ *
+ * @return int
+ */
+ public static function remove_competency_from_template($templateid, $competencyid) {
+ $params = self::validate_parameters(self::remove_competency_from_template_parameters(),
+ array(
+ 'templateid' => $templateid,
+ 'competencyid' => $competencyid,
+ ));
+
+ return api::remove_competency_from_template($params['templateid'], $params['competencyid']);
+ }
+
+ /**
+ * Returns description of remove_competency_from_template() result value.
+ *
+ * @return external_description
+ */
+ public static function remove_competency_from_template_returns() {
+ return new external_value(PARAM_BOOL, 'True if successful.');
+ }
+
+ /**
+ * Returns description of data_for_template_competenies_page() parameters.
+ *
+ * @return external_function_parameters
+ */
+ public static function data_for_template_competencies_page_parameters() {
+ $templateid = new external_value(
+ PARAM_INT,
+ 'The template id',
+ VALUE_REQUIRED
+ );
+ $params = array('templateid' => $templateid);
+ return new external_function_parameters($params);
+ }
+
+ /**
+ * Expose to AJAX
+ * @return boolean
+ */
+ public static function data_for_template_competencies_page_is_allowed_from_ajax() {
+ return true;
+ }
+
+ /**
+ * Loads the data required to render the template_competencies_page template.
+ *
+ * @return boolean
+ */
+ public static function data_for_template_competencies_page($templateid) {
+ global $PAGE;
+ $params = self::validate_parameters(self::data_for_template_competencies_page_parameters(),
+ array(
+ 'templateid' => $templateid,
+ ));
+
+ $renderable = new \tool_lp\output\template_competencies_page($params['templateid']);
+ $renderer = $PAGE->get_renderer('tool_lp');
+
+ $data = $renderable->export_for_template($renderer);
+
+ return $data;
+ }
+
+ /**
+ * Returns description of data_for_template_competencies_page() result value.
+ *
+ * @return external_description
+ */
+ public static function data_for_template_competencies_page_returns() {
+ return new external_single_structure(array (
+ 'templateid' => new external_value(PARAM_INT, 'The current template id'),
+ 'canmanagecompetencyframeworks' => new external_value(PARAM_BOOL, 'User can manage competency frameworks'),
+ 'canmanagetemplates' => new external_value(PARAM_BOOL, 'User can manage learning plan templates'),
+ 'competencies' => new external_multiple_structure(
+ self::get_competency_external_structure()
+ ),
+ 'manageurl' => new external_value(PARAM_LOCALURL, 'Url to the manage competencies page.'),
+ ));
+
+ }
+}
diff --git a/admin/tool/lp/classes/form/competency.php b/admin/tool/lp/classes/form/competency.php
new file mode 100644
index 00000000000..3f7224b8da0
--- /dev/null
+++ b/admin/tool/lp/classes/form/competency.php
@@ -0,0 +1,107 @@
+.
+
+/**
+ * This file contains the form add/update a competency framework.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @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');
+
+/**
+ * Competency framework form.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class competency extends moodleform {
+
+ /**
+ * Define the form - called by parent constructor
+ */
+ public function definition() {
+ $mform = $this->_form;
+ $id = $this->_customdata['id'];
+ $framework = $this->_customdata['competencyframework'];
+ $parent = $this->_customdata['parent'];
+
+ $mform->addElement('hidden', 'id');
+ $mform->setType('id', PARAM_INT);
+ $mform->setDefault('id', 0);
+
+ $mform->addElement('hidden', 'parentid');
+ $mform->setType('parentid', PARAM_INT);
+ if ($parent) {
+ $mform->setDefault('parentid', $parent->get_id());
+ } else {
+ $mform->setDefault('parentid', 0);
+ }
+
+ $mform->addElement('hidden', 'competencyframeworkid');
+ $mform->setType('competencyframeworkid', PARAM_INT);
+ $mform->setDefault('competencyframeworkid', $framework->get_id());
+
+ $mform->addElement('static',
+ 'frameworkdesc',
+ get_string('competencyframework', 'tool_lp'),
+ s($framework->get_shortname()));
+ if ($parent) {
+ $mform->addElement('static',
+ 'parentdesc',
+ get_string('parentcompetency', 'tool_lp'),
+ s($parent->get_shortname()));
+ }
+
+ $mform->addElement('text', 'shortname',
+ get_string('shortname', 'tool_lp'));
+ $mform->setType('shortname', PARAM_TEXT);
+ $mform->addRule('shortname', null, 'required', null, 'client');
+ $mform->addElement('editor', 'description',
+ get_string('description', 'tool_lp'), array('rows'=>4));
+ $mform->setType('description', PARAM_TEXT);
+ $mform->addElement('text', 'idnumber',
+ get_string('idnumber', 'tool_lp'));
+ $mform->setType('idnumber', PARAM_TEXT);
+ $mform->addElement('selectyesno', 'visible',
+ get_string('visible', 'tool_lp'));
+ $mform->setDefault('visible', true);
+ $mform->addHelpButton('visible', 'visible', 'tool_lp');
+
+ $this->add_action_buttons(true, get_string('savechanges', 'tool_lp'));
+
+ if (!empty($id)) {
+ if (!$this->is_submitted()) {
+ $competency = api::read_competency($id);
+ $record = $competency->to_record();
+ // Massage for editor API.
+ $record->description = array('text'=>$record->description, 'format'=>$record->descriptionformat);
+ $this->set_data($record);
+ }
+ }
+
+ }
+}
diff --git a/admin/tool/lp/classes/form/competency_framework.php b/admin/tool/lp/classes/form/competency_framework.php
new file mode 100644
index 00000000000..203ae2708c2
--- /dev/null
+++ b/admin/tool/lp/classes/form/competency_framework.php
@@ -0,0 +1,82 @@
+.
+
+/**
+ * This file contains the form add/update a competency framework.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @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');
+
+/**
+ * Competency framework form.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class competency_framework extends moodleform {
+
+ /**
+ * Define the form - called by parent constructor
+ */
+ public function definition() {
+ $mform = $this->_form;
+ $id = $this->_customdata;
+
+ $mform->addElement('hidden', 'id');
+ $mform->setType('id', PARAM_INT);
+ $mform->setDefault('id', 0);
+
+ $mform->addElement('text', 'shortname',
+ get_string('shortname', 'tool_lp'));
+ $mform->setType('shortname', PARAM_TEXT);
+ $mform->addRule('shortname', null, 'required', null, 'client');
+ $mform->addElement('editor', 'description',
+ get_string('description', 'tool_lp'), array('rows'=>4));
+ $mform->setType('description', PARAM_TEXT);
+ $mform->addElement('text', 'idnumber',
+ get_string('idnumber', 'tool_lp'));
+ $mform->setType('idnumber', PARAM_TEXT);
+ $mform->addElement('selectyesno', 'visible',
+ get_string('visible', 'tool_lp'));
+ $mform->setDefault('visible', true);
+ $mform->addHelpButton('visible', 'visible', 'tool_lp');
+
+ $this->add_action_buttons(true, get_string('savechanges', 'tool_lp'));
+
+ if (!empty($id)) {
+ if (!$this->is_submitted()) {
+ $framework = api::read_framework($id);
+ $record = $framework->to_record();
+ // Massage for editor API.
+ $record->description = array('text'=>$record->description, 'format'=>$record->descriptionformat);
+ $this->set_data($record);
+ }
+ }
+
+ }
+}
diff --git a/admin/tool/lp/classes/form/template.php b/admin/tool/lp/classes/form/template.php
new file mode 100644
index 00000000000..dd951523868
--- /dev/null
+++ b/admin/tool/lp/classes/form/template.php
@@ -0,0 +1,88 @@
+.
+
+/**
+ * This file contains the form add/update a competency framework.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @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 template form.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class template extends moodleform {
+
+ /**
+ * Define the form - called by parent constructor
+ */
+ public function definition() {
+ $mform = $this->_form;
+ $id = $this->_customdata;
+
+ $mform->addElement('hidden', 'id');
+ $mform->setType('id', PARAM_INT);
+ $mform->setDefault('id', 0);
+
+ $mform->addElement('text', 'shortname',
+ get_string('shortname', 'tool_lp'));
+ $mform->setType('shortname', PARAM_TEXT);
+ $mform->addRule('shortname', null, 'required', null, 'client');
+ $mform->addElement('editor', 'description',
+ get_string('description', 'tool_lp'), array('rows'=>4));
+ $mform->setType('description', PARAM_TEXT);
+ $mform->addElement('text', 'idnumber',
+ get_string('idnumber', 'tool_lp'));
+ $mform->setType('idnumber', PARAM_TEXT);
+ $mform->addElement('selectyesno', 'visible',
+ get_string('visible', 'tool_lp'));
+ $mform->addElement('date_time_selector',
+ 'duedate',
+ get_string('duedate', 'tool_lp'),
+ array('optional'=>true));
+ $mform->addHelpButton('duedate', 'duedate', 'tool_lp');
+
+ $mform->setDefault('visible', true);
+ $mform->addHelpButton('visible', 'visible', 'tool_lp');
+
+ $this->add_action_buttons(true, get_string('savechanges', 'tool_lp'));
+
+ if (!empty($id)) {
+ if (!$this->is_submitted()) {
+ $template = api::read_template($id);
+ $record = $template->to_record();
+ // Massage for editor API.
+ $record->description = array('text'=>$record->description, 'format'=>$record->descriptionformat);
+ $this->set_data($record);
+ }
+ }
+
+ }
+}
diff --git a/admin/tool/lp/classes/output/course_competencies_page.php b/admin/tool/lp/classes/output/course_competencies_page.php
new file mode 100644
index 00000000000..0532eac62e4
--- /dev/null
+++ b/admin/tool/lp/classes/output/course_competencies_page.php
@@ -0,0 +1,78 @@
+.
+
+/**
+ * Class containing data for course competencies page
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @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 moodle_url;
+use context_system;
+use context_course;
+use tool_lp\api;
+
+/**
+ * Class containing data for course competencies page
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class course_competencies_page implements renderable, templatable {
+
+ /** @var stdClass $course Course record for this page. */
+ var $course = null;
+
+ /**
+ * Construct this renderable.
+ * @param stdClass $course The course record for this page.
+ */
+ public function __construct($courseid) {
+ $context = context_course::instance($courseid);
+ $this->courseid = $courseid;
+ $this->competencies = api::list_competencies_in_course($courseid);
+ $this->canmanagecompetencyframeworks = has_capability('tool/lp:competencymanage', context_system::instance());
+ $this->canmanagecoursecompetencies = has_capability('tool/lp:coursecompetencymanage', $context);
+ $this->manageurl = new moodle_url('/admin/tool/lp/competencyframeworks.php');
+ }
+
+ /**
+ * Export this data so it can be used as the context for a mustache template.
+ *
+ * @return stdClass
+ */
+ public function export_for_template(renderer_base $output) {
+ $data = new stdClass();
+ $data->courseid = $this->courseid;
+ $data->competencies = array();
+ foreach ($this->competencies as $competency) {
+ $record = $competency->to_record();
+ array_push($data->competencies, $record);
+ }
+ $data->canmanagecompetencyframeworks = $this->canmanagecompetencyframeworks;
+ $data->canmanagecoursecompetencies = $this->canmanagecoursecompetencies;
+ $data->manageurl = $this->manageurl->out(true);
+
+ return $data;
+ }
+}
diff --git a/admin/tool/lp/classes/output/manage_competencies_page.php b/admin/tool/lp/classes/output/manage_competencies_page.php
new file mode 100644
index 00000000000..7408d09a3c5
--- /dev/null
+++ b/admin/tool/lp/classes/output/manage_competencies_page.php
@@ -0,0 +1,120 @@
+.
+
+/**
+ * Class containing data for managecompetencyframeworks page
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @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 single_button;
+use stdClass;
+use moodle_url;
+use context_system;
+use tool_lp\api;
+
+/**
+ * Class containing data for managecompetencies page
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class manage_competencies_page implements renderable, templatable {
+
+ /** @var \tool_lp\competency_framework $framework This competency framework. */
+ var $framework = null;
+
+ /** @var array $competencies List of competencies. */
+ var $competencies = array();
+
+ /** @var string $search Text to search for. */
+ var $search = '';
+
+ /** @var bool $canmanage Result of permissions checks. */
+ var $canmanage = false;
+
+ /** @var moodle_url $pluginurlbase Base url to use constructing links. */
+ var $pluginbaseurl = null;
+
+ /**
+ * Construct this renderable.
+ * @param \tool_lp\competency_framework $framework
+ */
+ public function __construct($framework, $search) {
+ $this->framework = $framework;
+ $this->search = $search;
+ $addpage = new single_button(
+ new moodle_url('/admin/tool/lp/editcompetencyframework.php'),
+ get_string('addnewcompetency', 'tool_lp')
+ );
+ $this->navigation[] = $addpage;
+
+ $this->competencies = api::search_competencies($search, $framework->get_id());
+
+ $context = context_system::instance();
+ $this->canmanage = has_capability('tool/lp:competencymanage', $context);
+ }
+
+ /**
+ * Recursively build up the tree of nodes.
+ *
+ * @param stdClass $parent - the exported parent node
+ * @param array $all - List of all competency classes.
+ */
+ private function add_competency_children($parent, $all) {
+ foreach ($all as $one) {
+ if ($one->get_parentid() == $parent->id) {
+ $parent->haschildren = true;
+ $record = $one->to_record();
+ $record->children = array();
+ $record->haschildren = false;
+ $parent->children[] = $record;
+ $this->add_competency_children($record, $all);
+ }
+ }
+ }
+
+ /**
+ * Export this data so it can be used as the context for a mustache template.
+ *
+ * @return stdClass
+ */
+ public function export_for_template(renderer_base $output) {
+ $data = new stdClass();
+ $data->framework = $this->framework->to_record();
+ $data->canmanage = $this->canmanage;
+ $data->competencies = array();
+ $data->search = $this->search;
+
+ foreach ($this->competencies as $competency) {
+ if ($competency->get_parentid() == 0) {
+ $record = $competency->to_record();
+ $record->children = array();
+ $record->haschildren = false;
+ $data->competencies[] = $record;
+ $this->add_competency_children($record, $this->competencies);
+ }
+ }
+
+ return $data;
+ }
+}
diff --git a/admin/tool/lp/classes/output/manage_competency_frameworks_page.php b/admin/tool/lp/classes/output/manage_competency_frameworks_page.php
new file mode 100644
index 00000000000..f74eb7b1061
--- /dev/null
+++ b/admin/tool/lp/classes/output/manage_competency_frameworks_page.php
@@ -0,0 +1,94 @@
+.
+
+/**
+ * Class containing data for managecompetencyframeworks page
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @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 single_button;
+use stdClass;
+use moodle_url;
+use context_system;
+use tool_lp\api;
+
+/**
+ * Class containing data for managecompetencyframeworks page
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class manage_competency_frameworks_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 array $competencyframeworks List of competency frameworks. */
+ var $competencyframeworks = array();
+
+ /** @var bool $canmanage Result of permissions checks. */
+ var $canmanage = false;
+
+ /** @var moodle_url $pluginurlbase Base url to use constructing links. */
+ var $pluginbaseurl = null;
+
+ /**
+ * Construct this renderable.
+ */
+ public function __construct() {
+ $addpage = new single_button(
+ new moodle_url('/admin/tool/lp/editcompetencyframework.php'),
+ get_string('addnewcompetencyframework', 'tool_lp')
+ );
+ $this->navigation[] = $addpage;
+
+ $this->competencyframeworks = api::list_frameworks(array(), 'sortorder', 'ASC', 0, 0);
+
+ $context = context_system::instance();
+ $this->canmanage = has_capability('tool/lp:competencymanage', $context);
+ }
+
+ /**
+ * Export this data so it can be used as the context for a mustache template.
+ *
+ * @return stdClass
+ */
+ public function export_for_template(renderer_base $output) {
+ $data = new stdClass();
+ $data->canmanage = $this->canmanage;
+ $data->competencyframeworks = array();
+ foreach ($this->competencyframeworks as $framework) {
+ $record = $framework->to_record();
+ $filters = array('competencyframeworkid' => $framework->get_id());
+ $record->competencies_count = api::count_competencies($filters);
+ $data->competencyframeworks[] = $record;
+ }
+ $data->pluginbaseurl = (new moodle_url('/admin/tool/lp'))->out(true);
+ $data->navigation = array();
+ foreach ($this->navigation as $button) {
+ $data->navigation[] = $output->render($button);
+ }
+
+ return $data;
+ }
+}
diff --git a/admin/tool/lp/classes/output/manage_templates_page.php b/admin/tool/lp/classes/output/manage_templates_page.php
new file mode 100644
index 00000000000..43708c06980
--- /dev/null
+++ b/admin/tool/lp/classes/output/manage_templates_page.php
@@ -0,0 +1,89 @@
+.
+
+/**
+ * Class containing data for managelearningplans page
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @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 single_button;
+use stdClass;
+use moodle_url;
+use context_system;
+use tool_lp\api;
+
+/**
+ * Class containing data for managecompetencyframeworks page
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class manage_templates_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 array $templates List of learning plan templates. */
+ var $templates = array();
+
+ /** @var bool $canmanage Result of permissions checks. */
+ var $canmanage = false;
+
+ /**
+ * Construct this renderable.
+ */
+ public function __construct() {
+ $addpage = new single_button(
+ new moodle_url('/admin/tool/lp/edittemplate.php'),
+ get_string('addnewtemplate', 'tool_lp')
+ );
+ $this->navigation[] = $addpage;
+
+ $this->templates = api::list_templates(array(), 'sortorder', 'ASC', 0, 0);
+
+ $context = context_system::instance();
+ $this->canmanage = has_capability('tool/lp:learningplanmanage', $context);
+ }
+
+ /**
+ * Export this data so it can be used as the context for a mustache template.
+ *
+ * @return stdClass
+ */
+ public function export_for_template(renderer_base $output) {
+ $data = new stdClass();
+ $data->canmanage = $this->canmanage;
+ $data->templates = array();
+ foreach ($this->templates as $template) {
+ $record = $template->to_record();
+ $data->templates[] = $record;
+ }
+ $data->pluginbaseurl = (new moodle_url('/admin/tool/lp'))->out(true);
+ $data->navigation = array();
+ foreach ($this->navigation as $button) {
+ $data->navigation[] = $output->render($button);
+ }
+
+ return $data;
+ }
+}
diff --git a/admin/tool/lp/classes/output/renderer.php b/admin/tool/lp/classes/output/renderer.php
new file mode 100644
index 00000000000..71cd64844e5
--- /dev/null
+++ b/admin/tool/lp/classes/output/renderer.php
@@ -0,0 +1,88 @@
+.
+
+/**
+ * Renderer class for learning plans
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace tool_lp\output;
+
+defined('MOODLE_INTERNAL') || die;
+
+use plugin_renderer_base;
+
+/**
+ * Renderer class for learning plans
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class renderer extends plugin_renderer_base {
+
+ /**
+ * Defer to template.
+ *
+ * @param manage_competency_frameworks_page $page
+ *
+ * @return string html for the page
+ */
+ public function render_manage_competency_frameworks_page($page) {
+ $data = $page->export_for_template($this);
+ return parent::render_from_template('tool_lp/manage_competency_frameworks_page', $data);
+ }
+
+ /**
+ * Defer to template.
+ *
+ * @param manage_competencies_page $page
+ *
+ * @return string html for the page
+ */
+ public function render_manage_competencies_page($page) {
+ $data = $page->export_for_template($this);
+ return parent::render_from_template('tool_lp/manage_competencies_page', $data);
+ }
+
+ /**
+ * Defer to template.
+ *
+ * @param course_competencies_page $page
+ *
+ * @return string html for the page
+ */
+ public function render_course_competencies_page($page) {
+ $data = $page->export_for_template($this);
+ return parent::render_from_template('tool_lp/course_competencies_page', $data);
+ }
+
+ /**
+ * Defer to template.
+ *
+ * @param manage_templates_page $page
+ *
+ * @return string html for the page
+ */
+ public function render_manage_templates_page($page) {
+ $data = $page->export_for_template($this);
+ return parent::render_from_template('tool_lp/manage_templates_page', $data);
+ }
+
+}
diff --git a/admin/tool/lp/classes/output/template_competencies_page.php b/admin/tool/lp/classes/output/template_competencies_page.php
new file mode 100644
index 00000000000..705d036284c
--- /dev/null
+++ b/admin/tool/lp/classes/output/template_competencies_page.php
@@ -0,0 +1,73 @@
+.
+
+/**
+ * Class containing data for learning plan template competencies page
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @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 moodle_url;
+use context_system;
+use tool_lp\api;
+
+/**
+ * Class containing data for learning plan template competencies page
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class template_competencies_page implements renderable, templatable {
+
+ /**
+ * Construct this renderable.
+ * @param int $templateid The learning plan template id for this page.
+ */
+ public function __construct($templateid) {
+ $this->courseid = $templateid;
+ $this->competencies = api::list_competencies_in_template($templateid);
+ $this->canmanagecompetencyframeworks = has_capability('tool/lp:competencymanage', context_system::instance());
+ $this->canmanagetemplates = has_capability('tool/lp:templatesmanage', $context);
+ $this->manageurl = new moodle_url('/admin/tool/lp/competencyframeworks.php');
+ }
+
+ /**
+ * Export this data so it can be used as the context for a mustache template.
+ *
+ * @return stdClass
+ */
+ public function export_for_template(renderer_base $output) {
+ $data = new stdClass();
+ $data->templateid = $this->templateid;
+ $data->competencies = array();
+ foreach ($this->competencies as $competency) {
+ $record = $competency->to_record();
+ array_push($data->competencies, $record);
+ }
+ $data->canmanagecompetencyframeworks = $this->canmanagecompetencyframeworks;
+ $data->canmanagecoursecompetencies = $this->canmanagecoursecompetencies;
+ $data->manageurl = $this->manageurl->out(true);
+
+ return $data;
+ }
+}
diff --git a/admin/tool/lp/classes/persistent.php b/admin/tool/lp/classes/persistent.php
new file mode 100644
index 00000000000..2a98c2fec09
--- /dev/null
+++ b/admin/tool/lp/classes/persistent.php
@@ -0,0 +1,260 @@
+.
+
+/**
+ * Abstract class for tool_lp objects saved to the DB.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_lp;
+
+use external_function_parameters;
+use external_value;
+
+/**
+ * Abstract class for tool_lp objects saved to the DB.
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+abstract class persistent {
+
+ /** @var int|null $id Database id for this framework */
+ private $id = null;
+
+ /** @var int $timecreated Creation timestamp */
+ private $timecreated = 0;
+
+ /** @var int $timemodified Modification timestamp */
+ private $timemodified = 0;
+
+ /** @var int $usermodified The user who last modified this framework */
+ private $usermodified = 0;
+
+ /**
+ * Abstract method that provides the table name matching this class.
+ *
+ * @return string
+ */
+ abstract public function get_table_name();
+
+ /**
+ * Create an instance of this class.
+ * @param int $id If set, this is the id of an existing record, used to load the data.
+ * @param stdClass $record If set, the data for this class will be taken from the record.
+ */
+ public function __construct($id = 0, $record = null) {
+ if ($id > 0) {
+ $this->id = $id;
+ $this->read();
+ }
+ if (!empty($record)) {
+ $this->from_record($record);
+ }
+ }
+
+ /**
+ * Get the record id
+ *
+ * @return int
+ */
+ public function get_id() {
+ return $this->id;
+ }
+
+ /**
+ * Set the record id
+ *
+ * @param int $id The record id
+ */
+ public function set_id($id) {
+ $this->id = $id;
+ }
+
+ /**
+ * Get the time the record was created.
+ *
+ * @return string The time the record was created.
+ */
+ public function get_timecreated() {
+ return $this->timecreated;
+ }
+
+ /**
+ * Set the time created timestamp
+ *
+ * @param int $timecreated The timestamp
+ */
+ public function set_timecreated($timecreated) {
+ $this->timecreated = $timecreated;
+ }
+
+ /**
+ * Get the last time the record was modified.
+ *
+ * @return string The last time the record was modified
+ */
+ public function get_timemodified() {
+ return $this->timemodified;
+ }
+
+ /**
+ * Set the last modified timestamp
+ *
+ * @param int $timemodified The timestamp
+ */
+ public function set_timemodified($timemodified) {
+ $this->timemodified = $timemodified;
+ }
+
+ /**
+ * Get the user who last modified the record.
+ *
+ * @return string The user who last modified the record
+ */
+ public function get_usermodified() {
+ return $this->usermodified;
+ }
+
+ /**
+ * Set the user id that last modified the record.
+ *
+ * @param int $usermodified The user id
+ */
+ public function set_usermodified($usermodified) {
+ $this->usermodified = $usermodified;
+ }
+
+ /**
+ * Populate this class with data from a DB record.
+ *
+ * @param stdClass $record A DB record.
+ * @return persistent
+ */
+ abstract public function from_record($record);
+
+ /**
+ * Create a DB record from this class.
+ *
+ * @return stdClass
+ */
+ abstract public function to_record();
+
+ /**
+ * Reload the data for this class from the DB.
+ *
+ * @return framework
+ */
+ public function read() {
+ global $DB;
+
+ if ($this->id <= 0) {
+ throw new coding_exception('id is required to load');
+ }
+ $record = $DB->get_record($this->get_table_name(), array('id' => $this->id), '*', MUST_EXIST);
+ return $this->from_record($record);
+ }
+
+ /**
+ * Insert a record in the DB
+ *
+ * @return persistent
+ */
+ public function create() {
+ global $DB, $USER;
+
+ $this->id = 0;
+ $this->timecreated = $this->timemodified = time();
+ $this->usermodified = $USER->id;
+ $record = $this->to_record();
+
+ $id = $DB->insert_record($this->get_table_name(), $record);
+ $this->set_id($id);
+ return $this;
+ }
+
+
+
+ /**
+ * Update the existing record in the DB.
+ *
+ * @return bool Success
+ */
+ public function update() {
+ global $DB, $USER;
+
+ if ($this->id <= 0) {
+ throw new coding_exception('id is required to update');
+ }
+ $record = $this->to_record();
+ unset($record->timecreated);
+ $record->timemodified = time();
+ $record->usermodified = $USER->id;
+ $record = (array) $record;
+ return $DB->update_record($this->get_table_name(), $record);
+ }
+
+ /**
+ * Delete the existing record in the DB.
+ *
+ * @return bool Success
+ */
+ public function delete() {
+ global $DB;
+
+ if ($this->id <= 0) {
+ throw new coding_exception('id is required to delete');
+ }
+ return $DB->delete_records($this->get_table_name(), array('id' => $this->id));
+ }
+
+ /**
+ * Load a list of records.
+ *
+ * @return array of persistent instances.
+ */
+ public function get_records($filters = array(), $sort = '', $order = 'ASC', $skip = 0, $limit = 0) {
+ global $DB;
+
+ $orderby = '';
+ if (!empty($sort)) {
+ $orderby = $sort . ' ' . $order;
+ }
+
+ $records = $DB->get_records($this->get_table_name(), $filters, $orderby, '*', $skip, $limit);
+ $instances = array();
+
+ foreach ($records as $record) {
+ $newrecord = new static(0, $record);
+ array_push($instances, $newrecord);
+ }
+ return $instances;
+ }
+
+ /**
+ * Count a list of records.
+ *
+ * @return int
+ */
+ public function count_records($filters = array()) {
+ global $DB;
+
+ $count = $DB->count_records($this->get_table_name(), $filters);
+ return $count;
+ }
+}
diff --git a/admin/tool/lp/classes/template.php b/admin/tool/lp/classes/template.php
new file mode 100644
index 00000000000..8f5988faf5b
--- /dev/null
+++ b/admin/tool/lp/classes/template.php
@@ -0,0 +1,274 @@
+.
+
+/**
+ * Class for loading/storing learning plan templates from the DB.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_lp;
+
+use stdClass;
+
+/**
+ * Class for loading/storing learning plan templates from the DB.
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class template extends persistent {
+
+ /** @var string $shortname Short name for this template */
+ private $shortname = '';
+
+ /** @var string $description Description for this framework */
+ private $description = '';
+
+ /** @var int $descriptionformat Format for the description */
+ private $descriptionformat = 0;
+
+ /** @var int $sortorder A number used to influence sorting */
+ private $sortorder = 0;
+
+ /** @var string $idnumber Unique idnumber for this template - must be unique if it is non-empty */
+ private $idnumber = '';
+
+ /** @var int $duedate A default due date for instances of this plan */
+ private $duedate = 0;
+
+ /** @var bool $visible Used to show/hide this template */
+ private $visible = true;
+
+ /**
+ * Method that provides the table name matching this class.
+ *
+ * @return string
+ */
+ public function get_table_name() {
+ return 'tool_lp_plan_template';
+ }
+
+ /**
+ * Get the short name.
+ *
+ * @return string The short name
+ */
+ public function get_shortname() {
+ return $this->shortname;
+ }
+
+ /**
+ * Set the short name.
+ *
+ * @param string $shortname The short name
+ */
+ public function set_shortname($shortname) {
+ $this->shortname = $shortname;
+ }
+
+ /**
+ * Get the description format.
+ *
+ * @return int The description format
+ */
+ public function get_descriptionformat() {
+ return $this->descriptionformat;
+ }
+
+ /**
+ * Set the description format
+ *
+ * @param int $descriptionformat The description format
+ */
+ public function set_descriptionformat($descriptionformat) {
+ $this->descriptionformat = $descriptionformat;
+ }
+
+ /**
+ * Get the id number.
+ *
+ * @return string The id number
+ */
+ public function get_idnumber() {
+ return $this->idnumber;
+ }
+
+ /**
+ * Set the id number.
+ *
+ * @param string $idnumber The id number
+ */
+ public function set_idnumber($idnumber) {
+ $this->idnumber = $idnumber;
+ }
+
+ /**
+ * Get the description.
+ *
+ * @return string The description
+ */
+ public function get_description() {
+ return $this->description;
+ }
+
+ /**
+ * Set the description.
+ *
+ * @param string $description The description
+ */
+ public function set_description($description) {
+ $this->description = $description;
+ }
+
+ /**
+ * Get the sort order index.
+ *
+ * @return string The sort order index
+ */
+ public function get_sortorder() {
+ return $this->sortorder;
+ }
+
+ /**
+ * Set the sort order index.
+ *
+ * @param string $sortorder The sort order index
+ */
+ public function set_sortorder($sortorder) {
+ $this->sortorder = $sortorder;
+ }
+
+ /**
+ * Get the due date
+ *
+ * @return string The due date
+ */
+ public function get_duedate() {
+ return $this->duedate;
+ }
+
+ /**
+ * Set the due date
+ *
+ * @param string $duedate The due date
+ */
+ public function set_duedate($duedate) {
+ $this->duedate = $duedate;
+ }
+
+
+ /**
+ * Get the visible flag.
+ *
+ * @return string The visible flag
+ */
+ public function get_visible() {
+ return $this->visible;
+ }
+
+ /**
+ * Set the visible flag.
+ *
+ * @param string $visible The visible flag
+ */
+ public function set_visible($visible) {
+ $this->visible = $visible;
+ }
+
+ /**
+ * Populate this class with data from a DB record.
+ *
+ * @param stdClass $record A DB record.
+ * @return template
+ */
+ public function from_record($record) {
+ if (isset($record->id)) {
+ $this->set_id($record->id);
+ }
+ if (isset($record->shortname)) {
+ $this->set_shortname($record->shortname);
+ }
+ if (isset($record->idnumber)) {
+ $this->set_idnumber($record->idnumber);
+ }
+ if (isset($record->description)) {
+ $this->set_description($record->description);
+ }
+ if (isset($record->descriptionformat)) {
+ $this->set_descriptionformat($record->descriptionformat);
+ }
+ if (isset($record->sortorder)) {
+ $this->set_sortorder($record->sortorder);
+ }
+ if (isset($record->visible)) {
+ $this->set_visible($record->visible);
+ }
+ 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);
+ }
+ return $this;
+ }
+
+ /**
+ * Create a DB record from this class.
+ *
+ * @return stdClass
+ */
+ public function to_record() {
+ $record = new stdClass();
+ $record->id = $this->get_id();
+ $record->shortname = $this->get_shortname();
+ $record->idnumber = $this->get_idnumber();
+ $record->duedate = $this->get_duedate();
+ $record->duedateformatted = '';
+ if ($record->duedate) {
+ $record->duedateformatted = userdate($this->get_duedate());
+ }
+ $record->description = $this->get_description();
+ $record->descriptionformat = $this->get_descriptionformat();
+ $record->descriptionformatted = format_text($this->get_description(), $this->get_descriptionformat());
+ $record->sortorder = $this->get_sortorder();
+ $record->visible = $this->get_visible();
+ $record->timecreated = $this->get_timecreated();
+ $record->timemodified = $this->get_timemodified();
+ $record->usermodified = $this->get_usermodified();
+
+ return $record;
+ }
+
+ /**
+ * Add a default for the sortorder field to the default create logic.
+ *
+ * @return persistent
+ */
+ public function create() {
+ $this->sortorder = $this->count_records();
+ return parent::create();
+ }
+
+
+}
diff --git a/admin/tool/lp/classes/template_competency.php b/admin/tool/lp/classes/template_competency.php
new file mode 100644
index 00000000000..79bc4ae33d5
--- /dev/null
+++ b/admin/tool/lp/classes/template_competency.php
@@ -0,0 +1,254 @@
+.
+
+/**
+ * Class for loading/storing competencies from the DB.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_lp;
+
+use stdClass;
+use context_system;
+
+/**
+ * Class for loading/storing template_competencies from the DB.
+ *
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class template_competency extends persistent {
+
+ /** @var int $templateid The template id */
+ private $templateid = 0;
+
+ /** @var int $competencyid The competency id */
+ private $competencyid = 0;
+
+ /**
+ * Method that provides the table name matching this class.
+ *
+ * @return string
+ */
+ public function get_table_name() {
+ return 'tool_lp_template_competency';
+ }
+
+ /**
+ * Get the competency id
+ *
+ * @return int The competency id
+ */
+ public function get_competencyid() {
+ return $this->competencyid;
+ }
+
+ /**
+ * Set the competency id
+ *
+ * @param int $competencyid The competency id
+ */
+ public function set_competencyid($competencyid) {
+ $this->competencyid = $competencyid;
+ }
+
+ /**
+ * Get the template id
+ *
+ * @return int The template id
+ */
+ public function get_templateid() {
+ return $this->templateid;
+ }
+
+ /**
+ * Set the template id
+ *
+ * @param int $templateid The template id
+ */
+ public function set_templateid($templateid) {
+ $this->templateid = $templateid;
+ }
+
+ /**
+ * Populate this class with data from a DB record.
+ *
+ * @param stdClass $record A DB record.
+ * @return framework
+ */
+ public function from_record($record) {
+ if (isset($record->id)) {
+ $this->set_id($record->id);
+ }
+ if (isset($record->templateid)) {
+ $this->set_templateid($record->templateid);
+ }
+ if (isset($record->competencyid)) {
+ $this->set_competencyid($record->competencyid);
+ }
+ 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);
+ }
+ return $this;
+ }
+
+ /**
+ * Create a DB record from this class.
+ *
+ * @return stdClass
+ */
+ public function to_record() {
+ $record = new stdClass();
+ $record->id = $this->get_id();
+ $record->templateid = $this->get_templateid();
+ $record->competencyid = $this->get_competencyid();
+ $record->timecreated = $this->get_timecreated();
+ $record->timemodified = $this->get_timemodified();
+ $record->usermodified = $this->get_usermodified();
+
+ return $record;
+ }
+
+ /**
+ * Count the templates using this competency
+ *
+ * @param int $competencyid The competency id
+ * @param bool $onlyvisible If true, only count visible templates using this competency.
+ * @return int
+ */
+ public function count_templates($competencyid, $onlyvisible) {
+ global $DB;
+
+ $sql = 'SELECT COUNT(template.id)
+ FROM {' . self::get_table_name() . '} tplcomp
+ JOIN {' . template::get_table_name() . '} tpl
+ ON tplcomp.templateid = tpl.id
+ WHERE tplcomp.competencyid = ? ';
+ $params = array($templateid);
+
+ if ($onlyvisible) {
+ $sql .= ' AND tpl.visible = ?';
+ $params[] = 1;
+ }
+
+ $results = $DB->count_records_sql($sql, $params);
+
+ return $results;
+ }
+
+ /**
+ * List the templates using this competency.
+ *
+ * @param int $competencyid The competency id
+ * @param bool $onlyvisible If true, only count visible templates using this competency.
+ * @return array[competency]
+ */
+ public function list_templates($competencyid, $onlyvisible) {
+ global $DB;
+
+ $template = new template();
+
+ $sql = 'SELECT tpl.*
+ FROM {' . $template->get_table_name() . '} tpl
+ JOIN {' . self::get_table_name() . '} tplcomp
+ ON tplcomp.templateid = tpl.id
+ WHERE tplcomp.competencyid = ? ';
+ $params = array($competencyid);
+
+ if ($onlyvisible) {
+ $sql .= ' AND tpl.visible = ?';
+ $params[] = 1;
+ }
+
+ $results = $DB->get_records_sql($sql, $params);
+
+ $instances = array();
+ foreach ($results as $result) {
+ array_push($instances, new template(0, $result));
+ }
+
+ return $instances;
+ }
+
+ /**
+ * Count the competencies in this template.
+ *
+ * @param int $templateid The template id
+ * @param bool $onlyvisible If true, only count visible competencies in this template.
+ * @return int
+ */
+ public function count_competencies($templateid, $onlyvisible) {
+ global $DB;
+
+ $sql = 'SELECT COUNT(comp.id)
+ FROM {' . self::get_table_name() . '} tplcomp
+ JOIN {' . competency::get_table_name() . '} comp
+ ON tplcomp.competencyid = comp.id
+ WHERE tplcomp.templateid = ? ';
+ $params = array($templateid);
+
+ if ($onlyvisible) {
+ $sql .= ' AND comp.visible = ?';
+ $params[] = 1;
+ }
+
+ $results = $DB->count_records_sql($sql, $params);
+
+ return $results;
+ }
+
+ /**
+ * List the competencies in this template.
+ *
+ * @param int $templateid The template id
+ * @param bool $onlyvisible If true, only count visible competencies in this template.
+ * @return array[competency]
+ */
+ public function list_competencies($templateid, $onlyvisible) {
+ global $DB;
+
+ $competency = new competency();
+
+ $sql = 'SELECT comp.*
+ FROM {' . $competency->get_table_name() . '} comp
+ JOIN {' . self::get_table_name() . '} tplcomp
+ ON tplcomp.competencyid = comp.id
+ WHERE tplcomp.templateid = ? ';
+ $params = array($templateid);
+
+ if ($onlyvisible) {
+ $sql .= ' AND comp.visible = ?';
+ $params[] = 1;
+ }
+
+ $results = $DB->get_records_sql($sql, $params);
+
+ $instances = array();
+ foreach ($results as $result) {
+ array_push($instances, new competency(0, $result));
+ }
+
+ return $instances;
+ }
+}
diff --git a/admin/tool/lp/competencies.php b/admin/tool/lp/competencies.php
new file mode 100644
index 00000000000..82b7f352e78
--- /dev/null
+++ b/admin/tool/lp/competencies.php
@@ -0,0 +1,50 @@
+.
+
+/**
+ * This page lets users to manage site wide competencies.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(__DIR__ . '/../../../config.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+admin_externalpage_setup('toollpcompetencies');
+
+$id = required_param('competencyframeworkid', PARAM_INT);
+$search = optional_param('search', '', PARAM_RAW);
+
+$framework = \tool_lp\api::read_framework($id);
+
+$title = get_string('competencies', 'tool_lp');
+$pagetitle = get_string('competenciesforframework', 'tool_lp', $framework->get_shortname());
+// Set up the page.
+$url = new moodle_url("/admin/tool/lp/competencies.php", array('competencyframeworkid' => $framework->get_id()));
+$PAGE->set_url($url);
+$PAGE->navbar->add($framework->get_shortname(), $url);
+$PAGE->set_title($title);
+$PAGE->set_heading($title);
+$output = $PAGE->get_renderer('tool_lp');
+echo $output->header();
+echo $output->heading($pagetitle);
+
+$page = new \tool_lp\output\manage_competencies_page($framework, $search);
+echo $output->render($page);
+
+echo $output->footer();
diff --git a/admin/tool/lp/competencyframeworks.php b/admin/tool/lp/competencyframeworks.php
new file mode 100644
index 00000000000..280020879af
--- /dev/null
+++ b/admin/tool/lp/competencyframeworks.php
@@ -0,0 +1,44 @@
+.
+
+/**
+ * This page lets users to manage site wide competencies.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(__DIR__ . '/../../../config.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+admin_externalpage_setup('toollpcompetencies');
+
+$title = get_string('competencies', 'tool_lp');
+$pagetitle = get_string('competencyframeworks', 'tool_lp');
+// Set up the page.
+$url = new moodle_url("/admin/tool/lp/competencyframeworks.php");
+$PAGE->set_url($url);
+$PAGE->set_title($title);
+$PAGE->set_heading($title);
+$output = $PAGE->get_renderer('tool_lp');
+echo $output->header();
+echo $output->heading($pagetitle);
+
+$page = new \tool_lp\output\manage_competency_frameworks_page();
+echo $output->render($page);
+
+echo $output->footer();
diff --git a/admin/tool/lp/coursecompetencies.php b/admin/tool/lp/coursecompetencies.php
new file mode 100644
index 00000000000..5cf5050c1e3
--- /dev/null
+++ b/admin/tool/lp/coursecompetencies.php
@@ -0,0 +1,50 @@
+.
+
+/**
+ * This page lets users to manage site wide competencies.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(__DIR__ . '/../../../config.php');
+
+$id = required_param('courseid', PARAM_INT);
+
+$params = array('id' => $id);
+$course = $DB->get_record('course', $params, '*', MUST_EXIST);
+require_login($course);
+$context = context_course::instance($course->id);
+$urlparams = array('courseid' => $id);
+
+$url = new moodle_url('/admin/tool/lp/coursecompetencies.php', $urlparams);
+$title = get_string('coursecompetencies', 'tool_lp');
+$PAGE->set_url($url);
+$PAGE->set_title($title);
+$coursename = format_text($course->fullname, false, array('context' => $context));
+$PAGE->set_heading($coursename);
+$PAGE->set_pagelayout('incourse');
+
+$output = $PAGE->get_renderer('tool_lp');
+echo $output->header();
+echo $output->heading($title);
+
+$page = new \tool_lp\output\course_competencies_page($course->id);
+echo $output->render($page);
+
+echo $output->footer();
diff --git a/admin/tool/lp/db/access.php b/admin/tool/lp/db/access.php
new file mode 100644
index 00000000000..bc2bf2b1162
--- /dev/null
+++ b/admin/tool/lp/db/access.php
@@ -0,0 +1,94 @@
+.
+
+/**
+ * Capabilities.
+ *
+ * This files lists capabilities related to tool_lp.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$capabilities = array(
+
+ 'tool/lp:competencyread' => array(
+ 'captype' => 'read',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'archetypes' => array(
+ 'user' => CAP_ALLOW
+ ),
+ 'clonepermissionsfrom' => 'moodle/block:view'
+ ),
+ 'tool/lp:competencymanage' => array(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'archetypes' => array(
+ ),
+ 'clonepermissionsfrom' => 'moodle/site:config'
+ ),
+ 'tool/lp:templateread' => array(
+ 'captype' => 'read',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'archetypes' => array(
+ 'user' => CAP_ALLOW
+ ),
+ 'clonepermissionsfrom' => 'moodle/block:view'
+ ),
+ 'tool/lp:templatemanage' => array(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'archetypes' => 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(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'archetypes' => array(
+ ),
+ 'clonepermissionsfrom' => 'moodle/site:config'
+ ),
+ 'tool/lp:coursecompetencyread' => array(
+ 'captype' => 'read',
+ 'contextlevel' => CONTEXT_COURSE,
+ 'archetypes' => array(
+ 'user' => CAP_ALLOW
+ ),
+ 'clonepermissionsfrom' => 'moodle/block:view'
+ ),
+ 'tool/lp:coursecompetencymanage' => array(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_COURSE,
+ 'archetypes' => array(
+ 'editingteacher' => CAP_ALLOW,
+ 'manager' => CAP_ALLOW
+ ),
+ 'clonepermissionsfrom' => 'moodle/site:backup'
+ )
+
+);
diff --git a/admin/tool/lp/db/install.xml b/admin/tool/lp/db/install.xml
new file mode 100755
index 00000000000..257fae750c1
--- /dev/null
+++ b/admin/tool/lp/db/install.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/admin/tool/lp/db/services.php b/admin/tool/lp/db/services.php
new file mode 100644
index 00000000000..ffab45e86a7
--- /dev/null
+++ b/admin/tool/lp/db/services.php
@@ -0,0 +1,313 @@
+.
+
+
+/**
+ * Learning plan webservice functions.
+ *
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$functions = array(
+
+ // Learning plan related functions.
+
+ 'tool_lp_create_competency_framework' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'create_competency_framework',
+ 'classpath' => '',
+ 'description' => 'Creates new competency frameworks.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:competencymanage',
+ ),
+ 'tool_lp_read_competency_framework' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'read_competency_framework',
+ 'classpath' => '',
+ 'description' => 'Load a summary of a competency framework.',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:competencyview',
+ ),
+ 'tool_lp_delete_competency_framework' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'delete_competency_framework',
+ 'classpath' => '',
+ 'description' => 'Delete a competency framework.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:competencymanage',
+ ),
+ 'tool_lp_update_competency_framework' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'update_competency_framework',
+ 'classpath' => '',
+ 'description' => 'Update a competency framework.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:competencymanage',
+ ),
+ 'tool_lp_list_competency_frameworks' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'list_competency_frameworks',
+ 'classpath' => '',
+ 'description' => 'Load a list of a competency frameworks.',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:competencyview',
+ ),
+ 'tool_lp_count_competency_frameworks' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'count_competency_frameworks',
+ 'classpath' => '',
+ 'description' => 'Count a list of a competency frameworks.',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:competencyview',
+ ),
+ 'tool_lp_data_for_competency_frameworks_manage_page' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'data_for_competency_frameworks_manage_page',
+ 'classpath' => '',
+ 'description' => 'Load the data for the competency frameworks manage page template',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:competencyview',
+ ),
+ 'tool_lp_reorder_competency_framework' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'reorder_competency_framework',
+ 'classpath' => '',
+ 'description' => 'Move a competency framework to a new relative sort order.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:competencymanage',
+ ),
+ 'tool_lp_create_competency' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'create_competency',
+ 'classpath' => '',
+ 'description' => 'Creates new competencies.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:competencymanage',
+ ),
+ 'tool_lp_read_competency' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'read_competency',
+ 'classpath' => '',
+ 'description' => 'Load a summary of a competency.',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:competencyview',
+ ),
+ 'tool_lp_delete_competency' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'delete_competency',
+ 'classpath' => '',
+ 'description' => 'Delete a competency.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:competencymanage',
+ ),
+ 'tool_lp_update_competency' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'update_competency',
+ 'classpath' => '',
+ 'description' => 'Update a competency.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:competencymanage',
+ ),
+ 'tool_lp_list_competencies' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'list_competencies',
+ 'classpath' => '',
+ 'description' => 'Load a list of a competencies.',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:competencyview',
+ ),
+ 'tool_lp_count_competencies' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'count_competencies',
+ 'classpath' => '',
+ 'description' => 'Count a list of a competencies.',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:competencyview',
+ ),
+ 'tool_lp_search_competencies' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'search_competencies',
+ 'classpath' => '',
+ 'description' => 'Search a list of a competencies.',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:competencyview',
+ ),
+ 'tool_lp_data_for_competencies_manage_page' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'data_for_competencies_manage_page',
+ 'classpath' => '',
+ 'description' => 'Load the data for the competencies manage page template',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:competencyview',
+ ),
+ 'tool_lp_set_parent_competency' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'set_parent_competency',
+ 'classpath' => '',
+ 'description' => 'Set a new parent for a competency.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:competencymanage',
+ ),
+ 'tool_lp_move_up_competency' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'move_up_competency',
+ 'classpath' => '',
+ 'description' => 'Re-order a competency.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:competencymanage',
+ ),
+ 'tool_lp_move_down_competency' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'move_down_competency',
+ 'classpath' => '',
+ 'description' => 'Re-order a competency.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:competencymanage',
+ ),
+ 'tool_lp_list_competencies_in_course' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'list_competencies_in_course',
+ 'classpath' => '',
+ 'description' => 'List the competencies in a course',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:coursecompetencyread',
+ ),
+ 'tool_lp_list_courses_using_competency' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'list_courses_using_competency',
+ 'classpath' => '',
+ 'description' => 'List the courses using a competency',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:coursecompetencyread',
+ ),
+ 'tool_lp_count_competencies_in_course' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'count_competencies_in_course',
+ 'classpath' => '',
+ 'description' => 'List the competencies in a course',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:coursecompetencyread',
+ ),
+ 'tool_lp_count_courses_using_competency' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'count_courses_using_competency',
+ 'classpath' => '',
+ 'description' => 'List the courses using a competency',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:coursecompetencyread',
+ ),
+ 'tool_lp_add_competency_to_course' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'add_competency_to_course',
+ 'classpath' => '',
+ 'description' => 'Add the competency to a course',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:coursecompetencymanage',
+ ),
+ 'tool_lp_remove_competency_from_course' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'remove_competency_from_course',
+ 'classpath' => '',
+ 'description' => 'Remove a competency from a course',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:coursecompetencymanage',
+ ),
+ 'tool_lp_data_for_course_competencies_page' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'data_for_course_competencies_page',
+ 'classpath' => '',
+ 'description' => 'Load the data for the course competencies page template.',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:coursecompetencyread',
+ ),
+ 'tool_lp_reorder_course_competency' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'reorder_course_competency',
+ 'classpath' => '',
+ 'description' => 'Move a course competency to a new relative sort order.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:coursecompetencymanage',
+ ),
+ 'tool_lp_create_template' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'create_template',
+ 'classpath' => '',
+ 'description' => 'Creates new learning plan templates.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:templatemanage',
+ ),
+ 'tool_lp_read_template' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'read_template',
+ 'classpath' => '',
+ 'description' => 'Load a summary of a learning plan template.',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:templateview',
+ ),
+ 'tool_lp_delete_template' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'delete_template',
+ 'classpath' => '',
+ 'description' => 'Delete a learning plan template.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:templatemanage',
+ ),
+ 'tool_lp_update_template' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'update_template',
+ 'classpath' => '',
+ 'description' => 'Update a learning plan template.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:templatemanage',
+ ),
+ 'tool_lp_list_templates' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'list_templates',
+ 'classpath' => '',
+ 'description' => 'Load a list of a learning plan templates.',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:templateview',
+ ),
+ 'tool_lp_count_templates' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'count_templates',
+ 'classpath' => '',
+ 'description' => 'Count a list of a learning plan templates.',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:templateview',
+ ),
+ 'tool_lp_data_for_templates_manage_page' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'data_for_templates_manage_page',
+ 'classpath' => '',
+ 'description' => 'Load the data for the learning plan templates manage page template',
+ 'type' => 'read',
+ 'capabilities'=> 'tool/lp:templateview',
+ ),
+ 'tool_lp_reorder_template' => array(
+ 'classname' => 'tool_lp\external',
+ 'methodname' => 'reorder_template',
+ 'classpath' => '',
+ 'description' => 'Move a learning plan template to a new relative sort order.',
+ 'type' => 'write',
+ 'capabilities'=> 'tool/lp:templatemanage',
+ ),
+
+);
+
diff --git a/admin/tool/lp/editcompetency.php b/admin/tool/lp/editcompetency.php
new file mode 100644
index 00000000000..7608c7b7876
--- /dev/null
+++ b/admin/tool/lp/editcompetency.php
@@ -0,0 +1,86 @@
+.
+
+/**
+ * This page lets users to manage site wide competencies.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(__DIR__ . '/../../../config.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+admin_externalpage_setup('toollpcompetencies');
+
+$title = get_string('competencies', 'tool_lp');
+$id = optional_param('id', 0, PARAM_INT);
+$competencyframeworkid = required_param('competencyframeworkid', PARAM_INT);
+$parentid = optional_param('parentid', 0, PARAM_INT);
+
+if (empty($id)) {
+ $pagetitle = get_string('addnewcompetency', 'tool_lp');
+} else {
+ $pagetitle = get_string('editcompetency', 'tool_lp');
+}
+// Set up the page.
+$params = array('id'=>$id, 'competencyframeworkid'=>$competencyframeworkid, 'parentid'=>$parentid);
+$url = new moodle_url("/admin/tool/lp/editcompetency.php", $params);
+$PAGE->set_url($url);
+$PAGE->set_title($title);
+$PAGE->set_heading($title);
+$output = $PAGE->get_renderer('tool_lp');
+
+$competencyframework = \tool_lp\api::read_framework($competencyframeworkid);
+$parent = null;
+if ($parentid) {
+ $parent = \tool_lp\api::read_competency($parentid);
+}
+
+$form = new \tool_lp\form\competency(null, array('id' => $id, 'competencyframework' => $competencyframework, 'parent' => $parent));
+
+if ($form->is_cancelled()) {
+ redirect(new moodle_url('/admin/tool/lp/competencies.php', array('competencyframeworkid'=>$competencyframeworkid)));
+}
+
+echo $output->header();
+echo $output->heading($pagetitle);
+
+$data = $form->get_data();
+if ($data) {
+ // Save the changes and continue back to the manage page.
+ // Massage the editor data.
+ $data->descriptionformat = $data->description['format'];
+ $data->description = $data->description['text'];
+ if (empty($data->id)) {
+ // Create new framework.
+ require_sesskey();
+ \tool_lp\api::create_competency($data);
+ echo $output->notification(get_string('competencycreated', 'tool_lp'), 'notifysuccess');
+ echo $output->continue_button(new moodle_url('/admin/tool/lp/competencies.php', array('competencyframeworkid'=>$competencyframeworkid)));
+ } else {
+ require_sesskey();
+ \tool_lp\api::update_competency($data);
+ echo $output->notification(get_string('competencyupdated', 'tool_lp'), 'notifysuccess');
+ echo $output->continue_button(new moodle_url('/admin/tool/lp/competencies.php', array('competencyframeworkid'=>$competencyframeworkid)));
+ }
+} else {
+ $form->display();
+}
+
+
+echo $output->footer();
diff --git a/admin/tool/lp/editcompetencyframework.php b/admin/tool/lp/editcompetencyframework.php
new file mode 100644
index 00000000000..46735b96474
--- /dev/null
+++ b/admin/tool/lp/editcompetencyframework.php
@@ -0,0 +1,76 @@
+.
+
+/**
+ * This page lets users to manage site wide competencies.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(__DIR__ . '/../../../config.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+admin_externalpage_setup('toollpcompetencies');
+
+$title = get_string('competencies', 'tool_lp');
+$id = optional_param('id', 0, PARAM_INT);
+if (empty($id)) {
+ $pagetitle = get_string('addnewcompetencyframework', 'tool_lp');
+} else {
+ $pagetitle = get_string('editcompetencyframework', 'tool_lp');
+}
+// Set up the page.
+$url = new moodle_url("/admin/tool/lp/editcompetencyframework.php", array('id'=>$id));
+$PAGE->set_url($url);
+$PAGE->set_title($title);
+$PAGE->set_heading($title);
+$output = $PAGE->get_renderer('tool_lp');
+
+$form = new \tool_lp\form\competency_framework(null, $id);
+
+if ($form->is_cancelled()) {
+ redirect(new moodle_url('/admin/tool/lp/competencyframeworks.php'));
+}
+
+echo $output->header();
+echo $output->heading($pagetitle);
+
+$data = $form->get_data();
+if ($data) {
+ // Save the changes and continue back to the manage page.
+ // Massage the editor data.
+ $data->descriptionformat = $data->description['format'];
+ $data->description = $data->description['text'];
+ if (empty($data->id)) {
+ // Create new framework.
+ require_sesskey();
+ \tool_lp\api::create_framework($data);
+ echo $output->notification(get_string('competencyframeworkcreated', 'tool_lp'), 'notifysuccess');
+ echo $output->continue_button('/admin/tool/lp/competencyframeworks.php');
+ } else {
+ require_sesskey();
+ \tool_lp\api::update_framework($data);
+ echo $output->notification(get_string('competencyframeworkupdated', 'tool_lp'), 'notifysuccess');
+ echo $output->continue_button('/admin/tool/lp/competencyframeworks.php');
+ }
+} else {
+ $form->display();
+}
+
+
+echo $output->footer();
diff --git a/admin/tool/lp/edittemplate.php b/admin/tool/lp/edittemplate.php
new file mode 100644
index 00000000000..b2c2db53be6
--- /dev/null
+++ b/admin/tool/lp/edittemplate.php
@@ -0,0 +1,76 @@
+.
+
+/**
+ * This page lets users to manage site wide learning plan templates.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(__DIR__ . '/../../../config.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+admin_externalpage_setup('toollplearningplans');
+
+$title = get_string('templates', 'tool_lp');
+$id = optional_param('id', 0, PARAM_INT);
+if (empty($id)) {
+ $pagetitle = get_string('addnewtemplate', 'tool_lp');
+} else {
+ $pagetitle = get_string('edittemplate', 'tool_lp');
+}
+// Set up the page.
+$url = new moodle_url("/admin/tool/lp/edittemplate.php", array('id'=>$id));
+$PAGE->set_url($url);
+$PAGE->set_title($title);
+$PAGE->set_heading($title);
+$output = $PAGE->get_renderer('tool_lp');
+
+$form = new \tool_lp\form\template(null, $id);
+
+if ($form->is_cancelled()) {
+ redirect(new moodle_url('/admin/tool/lp/learningplans.php'));
+}
+
+echo $output->header();
+echo $output->heading($pagetitle);
+
+$data = $form->get_data();
+if ($data) {
+ // Save the changes and continue back to the manage page.
+ // Massage the editor data.
+ $data->descriptionformat = $data->description['format'];
+ $data->description = $data->description['text'];
+ if (empty($data->id)) {
+ // Create new template.
+ require_sesskey();
+ \tool_lp\api::create_template($data);
+ echo $output->notification(get_string('templatecreated', 'tool_lp'), 'notifysuccess');
+ echo $output->continue_button('/admin/tool/lp/learningplans.php');
+ } else {
+ require_sesskey();
+ \tool_lp\api::update_template($data);
+ echo $output->notification(get_string('templateupdated', 'tool_lp'), 'notifysuccess');
+ echo $output->continue_button('/admin/tool/lp/learningplans.php');
+ }
+} else {
+ $form->display();
+}
+
+
+echo $output->footer();
diff --git a/admin/tool/lp/lang/en/tool_lp.php b/admin/tool/lp/lang/en/tool_lp.php
new file mode 100644
index 00000000000..813c8685461
--- /dev/null
+++ b/admin/tool/lp/lang/en/tool_lp.php
@@ -0,0 +1,102 @@
+.
+
+/**
+ * Strings for component 'tool_lp', language 'en'
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$string['pluginname'] = 'Learning Plans';
+$string['lp:learningplanmanage'] = 'Manage learning plans';
+$string['lp:learningplanread'] = 'View learning plans';
+$string['lp:competencymanage'] = 'Manage competency frameworks';
+$string['lp:competencyread'] = 'View competency frameworks';
+$string['lp:coursecompetencymanage'] = 'Manage course competencies';
+$string['lp:coursecompetencyread'] = 'View course competencies';
+$string['competencies'] = 'Competencies';
+$string['competenciesforframework'] = 'Competencies for {$a}';
+$string['competencyframeworks'] = 'Competency Frameworks';
+$string['addnewcompetencyframework'] = 'Add new competency framework';
+$string['addnewtemplate'] = 'Add new learning plan template';
+$string['addnewcompetency'] = 'Add new competency';
+$string['addcompetency'] = 'Add competency';
+$string['editcompetencyframework'] = 'Edit competency framework';
+$string['listcompetencyframeworkscaption'] = 'List of competency frameworks';
+$string['listtemplatescaption'] = 'List of learning plan templates';
+$string['competencyframeworkname'] = 'Name';
+$string['actions'] = 'Actions';
+$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['shortname'] = 'Name';
+$string['savechanges'] = 'Save changes';
+$string['description'] = 'Description';
+$string['visible'] = 'Visible';
+$string['visible_help'] = 'A competency framework can be hidden from teachers. This could be useful if a framework is still in the process of being developed.';
+$string['idnumber'] = 'Id number';
+$string['competencyframework'] = 'Competency framework';
+$string['parentcompetency'] = 'Parent competency';
+$string['competencyframeworkcreated'] = 'Competency framework created.';
+$string['competencyframeworkupdated'] = 'Competency framework updated.';
+$string['editcompetencyframework'] = 'Edit competency framework';
+$string['editthiscompetencyframework'] = 'Edit';
+$string['deletethiscompetencyframework'] = 'Delete';
+$string['deletethistemplate'] = 'Delete';
+$string['hiddenhint'] = '(hidden)';
+$string['movecompetencyframework'] = 'Move competency framework';
+$string['movetonewparent'] = 'Relocate';
+$string['moveframeworkafter'] = 'Move competency framework after {$a}';
+$string['selectedcompetency'] = 'Selected competency';
+$string['nocompetencyselected'] = 'No competency selected';
+$string['search'] = 'Search...';
+$string['competencycreated'] = 'Competency created';
+$string['competencyupdated'] = 'Competency updated';
+$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['cancel'] = 'Cancel';
+$string['move'] = 'Move';
+$string['movecompetency'] = 'Move competency: {$a}';
+$string['selectcompetencymovetarget'] = 'Select a location to move this competency to:';
+$string['coursecompetencies'] = 'Course competencies';
+$string['linkcoursecompetencies'] = 'Link course competencies';
+$string['managecompetenciesandframeworks'] = 'Manage competencies and frameworks';
+$string['locatecompetency'] = 'Locate competency';
+$string['itemstoadd'] = 'Items to add';
+$string['linkedcourses'] = 'Linked courses';
+$string['nolinkedcourses'] = 'No courses are using this competency';
+$string['coursesusingthiscompetency'] = 'Courses using this competency';
+$string['learningplans'] = 'Learning plans';
+$string['movecoursecompetency'] = 'Move course competency';
+$string['movecoursecompetencyafter'] = 'Move course competency after {$a}';
+
+$string['templates'] = 'Learning plan templates';
+$string['templatename'] = 'Name';
+$string['editthistemplate'] = 'Edit';
+$string['templatecreated'] = 'Learning plan template created';
+$string['templateupdated'] = 'Learning plan template updated';
+$string['edittemplate'] = 'Edit learning plan template';
+$string['deletetemplate'] = 'Delete learning plan template? {$a}';
+$string['duedate'] = 'Due date';
+$string['duedate_help'] = 'The date that a learning plan should be completed by.';
diff --git a/admin/tool/lp/learningplans.php b/admin/tool/lp/learningplans.php
new file mode 100644
index 00000000000..bdb782cccfb
--- /dev/null
+++ b/admin/tool/lp/learningplans.php
@@ -0,0 +1,44 @@
+.
+
+/**
+ * This page lets users to manage site wide competencies.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(__DIR__ . '/../../../config.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+admin_externalpage_setup('toollplearningplans');
+
+$title = get_string('learningplans', 'tool_lp');
+$pagetitle = get_string('templates', 'tool_lp');
+// Set up the page.
+$url = new moodle_url("/admin/tool/lp/learningplans.php");
+$PAGE->set_url($url);
+$PAGE->set_title($title);
+$PAGE->set_heading($title);
+$output = $PAGE->get_renderer('tool_lp');
+echo $output->header();
+echo $output->heading($pagetitle);
+
+$page = new \tool_lp\output\manage_templates_page();
+echo $output->render($page);
+
+echo $output->footer();
diff --git a/admin/tool/lp/lib.php b/admin/tool/lp/lib.php
new file mode 100644
index 00000000000..6b72ba71d4c
--- /dev/null
+++ b/admin/tool/lp/lib.php
@@ -0,0 +1,47 @@
+.
+
+/**
+ * This page contains navigation hooks for learning plans.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die;
+
+/**
+ * This function extends the course navigation
+ *
+ * @param navigation_node $navigation The navigation node to extend
+ * @param stdClass $course The course to object for the tool
+ * @param context $coursecontext The context of the course
+ */
+function tool_lp_extend_navigation_course($navigation, $course, $coursecontext) {
+ // Just a link to course report.
+ $title = get_string('coursecompetencies', 'tool_lp');
+ $path = new moodle_url("/admin/tool/lp/coursecompetencies.php", array('courseid' => $course->id));
+ $settingsnode = navigation_node::create($title,
+ $path,
+ navigation_node::TYPE_SETTING,
+ null,
+ null,
+ new pix_icon('competency', '', 'tool_lp'));
+ if (isset($settingsnode)) {
+ $navigation->add_node($settingsnode);
+ }
+}
diff --git a/admin/tool/lp/pix/competency.png b/admin/tool/lp/pix/competency.png
new file mode 100644
index 00000000000..52fe956c0ef
Binary files /dev/null and b/admin/tool/lp/pix/competency.png differ
diff --git a/admin/tool/lp/pix/competency.svg b/admin/tool/lp/pix/competency.svg
new file mode 100644
index 00000000000..2f845cee491
--- /dev/null
+++ b/admin/tool/lp/pix/competency.svg
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/admin/tool/lp/settings.php b/admin/tool/lp/settings.php
new file mode 100644
index 00000000000..3e46a8cabe8
--- /dev/null
+++ b/admin/tool/lp/settings.php
@@ -0,0 +1,46 @@
+.
+
+/**
+ * Links and settings
+ *
+ * This file contains links and settings used by tool_lp
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+defined('MOODLE_INTERNAL') || die;
+
+// Manage competency frameworks page.
+$temp = new admin_externalpage(
+ 'toollpcompetencies',
+ get_string('competencyframeworks', 'tool_lp'),
+ new moodle_url('/admin/tool/lp/competencyframeworks.php'),
+ 'tool/lp:competencymanage'
+);
+$ADMIN->add('root', $temp, 'badges');
+// Manage learning plans page.
+$temp = new admin_externalpage(
+ 'toollplearningplans',
+ get_string('learningplans', 'tool_lp'),
+ new moodle_url('/admin/tool/lp/learningplans.php'),
+ 'tool/lp:learningplanmanage'
+);
+$ADMIN->add('root', $temp, 'toollpcompetencies');
+
+// No report settings.
+$settings = null;
diff --git a/admin/tool/lp/styles.css b/admin/tool/lp/styles.css
new file mode 100644
index 00000000000..9765b198b1f
--- /dev/null
+++ b/admin/tool/lp/styles.css
@@ -0,0 +1,59 @@
+.path-admin-tool-learningplan [data-region="managecompetencies"] 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 {
+ margin-left: -20px;
+ margin-right: 4px;
+}
+.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="competencylinktree"] ul[data-enhance="linktree"],
+.path-admin-tool-learningplan [data-region="competencymovetree"] ul[data-enhance="movetree"] {
+ border: 1px solid #ccc;
+ box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
+ transition: border linear .2s,box-shadow linear .2s;
+ border-radius: 4px;
+ padding-left: 20px;
+ padding-right: 20px;
+ margin-left: 10px;
+ margin-right: 10px;
+}
+.path-admin-tool-learningplan [data-region="managecompetencies"] 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="managecompetencies"] ul [aria-selected="true"] {
+ background-color: #dfdfdf;
+}
+.path-admin-tool-learningplan [data-region="filtercompetencies"] input {
+ margin-left: 10px;
+}
+
+.path-admin-tool-learningplan [data-region="link-buttons"],
+.path-admin-tool-learningplan [data-region="move-buttons"] {
+ text-align: center;
+}
+
+.dir-rtl.path-admin-tool-learningplan [data-region="filtercompetencies"] input {
+ margin-right: 10px;
+}
+
+.path-admin-tool-learningplan [data-region="competencyactionsmenu"] {
+ display: none;
+}
+.path-admin-tool-learningplan [data-region="competencyactionsmenu"] .moodle-actionmenu[data-enhanced].show .menu {
+ white-space: nowrap;
+}
+.path-admin-tool-learningplan .currentdragtarget {
+ border: 1px dashed;
+}
diff --git a/admin/tool/lp/templates/competencies_move_tree.mustache b/admin/tool/lp/templates/competencies_move_tree.mustache
new file mode 100644
index 00000000000..06585110285
--- /dev/null
+++ b/admin/tool/lp/templates/competencies_move_tree.mustache
@@ -0,0 +1,46 @@
+{{!
+ 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 .
+}}
+{{!
+ Manage competencies template.
+
+ Classes required for JS:
+
+ Data attibutes required for JS:
+ * data-enhance=tree
+
+ Context variables required for this template:
+ * framework -
+ * competencies - array of objects containing id, shortname, idnumber, sortorder, visible, parentid, competencyframeworkid, path
+}}
+
+
{{#str}}selectcompetencymovetarget, tool_lp{{/str}}
+
+
+ {{framework.shortname}}
+
+ {{#competencies}}
+ {{> tool_lp/competencies_tree }}
+ {{/competencies}}
+
+
+
+
+
+
+
+
+
diff --git a/admin/tool/lp/templates/competencies_tree.mustache b/admin/tool/lp/templates/competencies_tree.mustache
new file mode 100644
index 00000000000..e28a967acc2
--- /dev/null
+++ b/admin/tool/lp/templates/competencies_tree.mustache
@@ -0,0 +1,12 @@
+
+ {{^visible}}{{/visible}}
+ {{shortname}} {{idnumber}}
+ {{^visible}} {{/visible}}
+ {{#haschildren}}
+
+ {{#children}}
+ {{> tool_lp/competencies_tree }}
+ {{/children}}
+
+ {{/haschildren}}
+
diff --git a/admin/tool/lp/templates/competency_summary.mustache b/admin/tool/lp/templates/competency_summary.mustache
new file mode 100644
index 00000000000..d2cbe68a04d
--- /dev/null
+++ b/admin/tool/lp/templates/competency_summary.mustache
@@ -0,0 +1,5 @@
+{{shortname}} {{idnumber}}
+{{descriptionformatted}}
+{{^visible}}
+( {{#str}} hidden, tool_lp{{/str}})
+{{/visible}}
diff --git a/admin/tool/lp/templates/course_competencies_page.mustache b/admin/tool/lp/templates/course_competencies_page.mustache
new file mode 100644
index 00000000000..f57a4044368
--- /dev/null
+++ b/admin/tool/lp/templates/course_competencies_page.mustache
@@ -0,0 +1,56 @@
+{{!
+ 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 .
+}}
+{{!
+ Course competencies template.
+}}
+
+
+
+
+{{#competencies}}
+
+
+
+
+ {{> tool_lp/competency_summary }}
+
+
+{{/competencies}}
+
+
+{{^competencies}}
+
+ {{#str}}nocompetenciesincourse, tool_lp{{/str}}
+
+{{/competencies}}
+
+
+
+{{#js}}
+require(['tool_lp/coursecompetencies'], function(mod) {
+ (new mod({{courseid}}));
+});
+{{/js}}
diff --git a/admin/tool/lp/templates/link_course_competencies.mustache b/admin/tool/lp/templates/link_course_competencies.mustache
new file mode 100644
index 00000000000..d57e2e7c102
--- /dev/null
+++ b/admin/tool/lp/templates/link_course_competencies.mustache
@@ -0,0 +1,29 @@
+
+
{{#str}}competencyframeworks, tool_lp{{/str}}
+
+{{#frameworks}}
+{{shortname}} {{idnumber}}
+{{/frameworks}}
+
+
{{#str}}locatecompetency, tool_lp{{/str}}
+
+
+
+
+ {{framework.shortname}}
+
+ {{#competencies}}
+ {{> tool_lp/competencies_tree }}
+ {{/competencies}}
+
+
+
+
+
+
+
+
diff --git a/admin/tool/lp/templates/linked_courses_summary.mustache b/admin/tool/lp/templates/linked_courses_summary.mustache
new file mode 100644
index 00000000000..9b6490579db
--- /dev/null
+++ b/admin/tool/lp/templates/linked_courses_summary.mustache
@@ -0,0 +1,11 @@
+
+{{#str}}coursesusingthiscompetency, tool_lp{{/str}}
+
+
+{{#courses}}
+ {{{fullnameformatted}}} {{{shortnameformatted}}}
+{{/courses}}
+{{^courses}}
+ {{#str}}nolinkedcourses, tool_lp{{/str}}
+{{/courses}}
+
diff --git a/admin/tool/lp/templates/manage_competencies_page.mustache b/admin/tool/lp/templates/manage_competencies_page.mustache
new file mode 100644
index 00000000000..0108f278112
--- /dev/null
+++ b/admin/tool/lp/templates/manage_competencies_page.mustache
@@ -0,0 +1,114 @@
+{{!
+ 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 .
+}}
+{{!
+ Manage competencies template.
+
+ Classes required for JS:
+
+ Data attibutes required for JS:
+ * data-enhance=tree
+
+ Context variables required for this template:
+ * framework -
+ * competencies - array of objects containing id, shortname, idnumber, sortorder, visible, parentid, competencyframeworkid, path
+ * canmanage - true if this user has permission to manage the competencies
+}}
+
+
+
+
+
+
+
+
+ {{framework.shortname}}
+
+ {{#competencies}}
+ {{> tool_lp/competencies_tree }}
+ {{/competencies}}
+
+
+
+
+
+
+
{{#str}}selectedcompetency, tool_lp{{/str}}
+
+{{#str}}nocompetencyselected, tool_lp{{/str}}
+
+{{#canmanage}}
+
+
+{{#pix}}t/add{{/pix}} {{#str}}addcompetency, tool_lp{{/str}}
+
+
+
+
+
+{{/canmanage}}
+
+
+
+{{#js}}
+// Initialise the JS.
+require(['core/tree', 'tool_lp/competencytree', 'tool_lp/competencyactions' ], function(ariatree, treeModel, actions) {
+
+ treeModel.init({{framework.id}});
+
+ actions.init(treeModel);
+
+ var competencytree = new ariatree('[data-enhance=tree]', actions.selectionChanged);
+
+});
+{{/js}}
+
+
diff --git a/admin/tool/lp/templates/manage_competency_frameworks_page.mustache b/admin/tool/lp/templates/manage_competency_frameworks_page.mustache
new file mode 100644
index 00000000000..fbe0df59c82
--- /dev/null
+++ b/admin/tool/lp/templates/manage_competency_frameworks_page.mustache
@@ -0,0 +1,100 @@
+{{!
+ 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 .
+}}
+{{!
+ Manage competency frameworks template.
+
+ Classes required for JS:
+ * drag-parentnode
+ * drag-handlecontainer
+ * drag-samenode
+ * competencyframeworkactions
+
+ Data attibutes required for JS:
+ * data-region = managecompetencies
+ * data-frameworkid = id
+ * data-action = deletecompetencyframework
+
+ Context variables required for this template:
+ * competencyframeworks - array of objects containing id, shortname, idnumber, sortorder, visible
+ * canmanage - true if this user has permission to manage the frameworks
+ * navigation - array of strings containing buttons for navigation
+}}
+
+
+ {{#str}}listcompetencyframeworkscaption, tool_lp{{/str}}
+
+
+ {{#str}}competencyframeworkname, tool_lp{{/str}}
+ {{#str}}competencies, tool_lp{{/str}}
+ {{#str}}actions, tool_lp{{/str}}
+
+
+
+ {{#competencyframeworks}}
+
+ {{shortname}} {{idnumber}} {{^visible}}{{#str}}hiddenhint, tool_lp{{/str}}{{/visible}}
+ {{competencies_count}}
+
+ {{#canmanage}}
+
+ {{/canmanage}}
+
+
+ {{/competencyframeworks}}
+
+
+{{^competencyframeworks}}
+
+ {{#str}}nocompetencyframeworks, tool_lp{{/str}}
+
+{{/competencyframeworks}}
+
+
+{{#navigation}}
+{{{.}}}
+{{/navigation}}
+
+
+{{#js}}
+// Initialise the JS.
+require(['tool_lp/frameworkdelete',
+ 'core/menu',
+ 'tool_lp/frameworkmove'],
+ function(deleteMod, menu, moveMod) {
+
+ deleteMod.init();
+ moveMod.init();
+
+ menu.menu('{{#str}}edit{{/str}}', '.competencyframeworkactions');
+});
+
+{{/js}}
+
+
diff --git a/admin/tool/lp/templates/manage_templates_page.mustache b/admin/tool/lp/templates/manage_templates_page.mustache
new file mode 100644
index 00000000000..eb17c8cd775
--- /dev/null
+++ b/admin/tool/lp/templates/manage_templates_page.mustache
@@ -0,0 +1,98 @@
+{{!
+ 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 .
+}}
+{{!
+ Manage learning plan templates template.
+
+ Classes required for JS:
+ * drag-parentnode
+ * drag-handlecontainer
+ * drag-samenode
+ * templateactions
+
+ Data attibutes required for JS:
+ * data-region = managetemplates
+ * data-templateid = id
+ * data-action = deletetemplate
+
+ Context variables required for this template:
+ * templates - array of objects containing id, shortname, idnumber, sortorder, visible
+ * canmanage - true if this user has permission to manage the templates
+ * navigation - array of strings containing buttons for navigation
+}}
+
+
+ {{#str}}listtemplatescaption, tool_lp{{/str}}
+
+
+ {{#str}}templatename, tool_lp{{/str}}
+ {{#str}}actions, tool_lp{{/str}}
+
+
+
+ {{#templates}}
+
+ {{shortname}} {{idnumber}} {{^visible}}{{#str}}hiddenhint, tool_lp{{/str}}{{/visible}}
+
+ {{#canmanage}}
+
+ {{/canmanage}}
+
+
+ {{/templates}}
+
+
+{{^templates}}
+
+ {{#str}}notemplates, tool_lp{{/str}}
+
+{{/templates}}
+
+
+{{#navigation}}
+{{{.}}}
+{{/navigation}}
+
+
+{{#js}}
+// Initialise the JS.
+require(['tool_lp/templatedelete',
+ 'core/menu',
+ 'tool_lp/templatemove'],
+ function(deleteMod, menu, moveMod) {
+
+ deleteMod.init();
+ moveMod.init();
+
+ menu.menu('{{#str}}edit{{/str}}', '.templateactions');
+});
+
+{{/js}}
+
+
diff --git a/admin/tool/lp/templates/no_frameworks_warning.mustache b/admin/tool/lp/templates/no_frameworks_warning.mustache
new file mode 100644
index 00000000000..d93b418a970
--- /dev/null
+++ b/admin/tool/lp/templates/no_frameworks_warning.mustache
@@ -0,0 +1,3 @@
+
+ {{#str}}nocompetencyframeworks, tool_lp{{/str}}
+
diff --git a/admin/tool/lp/tests/externallib_test.php b/admin/tool/lp/tests/externallib_test.php
new file mode 100644
index 00000000000..6b2588ae04c
--- /dev/null
+++ b/admin/tool/lp/tests/externallib_test.php
@@ -0,0 +1,578 @@
+.
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+
+require_once($CFG->dirroot . '/webservice/tests/helpers.php');
+
+use tool_lp\external;
+
+/**
+ * External learning plans webservice API tests.
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class tool_lp_external_testcase extends externallib_advanced_testcase {
+
+ /** @var stdClass $learningplancreator User with enough permissions to create */
+ protected $creator = null;
+
+ /** @var stdClass $learningplanuser User with enough permissions to view */
+ protected $user = null;
+
+ /**
+ * Setup function - we will create a course and add an assign instance to it.
+ */
+ protected function setUp() {
+ global $DB;
+
+ $this->resetAfterTest(true);
+
+ // Create some users.
+ $creator = $this->getDataGenerator()->create_user();
+ $user = $this->getDataGenerator()->create_user();
+ $syscontext = context_system::instance();
+
+ $creatorrole = create_role('Creator role', 'creatorrole', 'learning plan creator role description');
+ $userrole = create_role('User role', 'userrole', 'learning plan user role description');
+
+ assign_capability('tool/lp:competencymanage', CAP_ALLOW, $creatorrole, $syscontext->id);
+ assign_capability('tool/lp:competencyview', CAP_ALLOW, $userrole, $syscontext->id);
+
+ role_assign($creatorrole, $creator->id, $syscontext->id);
+ role_assign($userrole, $user->id, $syscontext->id);
+
+ $this->creator = $creator;
+ $this->user = $user;
+ accesslib_clear_all_caches_for_unit_testing();
+ }
+
+ /**
+ * Test we can't create a competency framework with only read permissions.
+ */
+ public function test_create_competency_frameworks_with_read_permissions() {
+ $this->setExpectedException('required_capability_exception');
+ $this->setUser($this->user);
+ $result = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ }
+
+ /**
+ * Test we can create a competency framework with manage permissions.
+ */
+ public function test_create_competency_frameworks_with_manage_permissions() {
+ $this->setUser($this->creator);
+ $result = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $result);
+
+ $this->assertGreaterThan(0, $result->timecreated);
+ $this->assertGreaterThan(0, $result->timemodified);
+ $this->assertEquals($this->creator->id, $result->usermodified);
+ $this->assertEquals('shortname', $result->shortname);
+ $this->assertEquals('idnumber', $result->idnumber);
+ $this->assertEquals('description', $result->description);
+ $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
+ $this->assertEquals(true, $result->visible);
+ }
+
+ /**
+ * Test we cannot create a competency framework with nasty data.
+ */
+ public function test_create_competency_frameworks_with_nasty_data() {
+ $this->setUser($this->creator);
+ $this->setExpectedException('invalid_parameter_exception');
+ $result = external::create_competency_framework('short', 'id;"number', 'de<>\\..scription', FORMAT_HTML, true);
+ }
+
+ /**
+ * Test we can read a competency framework with manage permissions.
+ */
+ public function test_read_competency_frameworks_with_manage_permissions() {
+ $this->setUser($this->creator);
+ $result = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $result);
+
+ $id = $result->id;
+ $result = external::read_competency_framework($id);
+ $result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);
+
+ $this->assertGreaterThan(0, $result->timecreated);
+ $this->assertGreaterThan(0, $result->timemodified);
+ $this->assertEquals($this->creator->id, $result->usermodified);
+ $this->assertEquals('shortname', $result->shortname);
+ $this->assertEquals('idnumber', $result->idnumber);
+ $this->assertEquals('description', $result->description);
+ $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
+ $this->assertEquals(true, $result->visible);
+ }
+
+ /**
+ * Test we can read a competency framework with read permissions.
+ */
+ public function test_read_competency_frameworks_with_read_permissions() {
+ $this->setUser($this->creator);
+ $result = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $result);
+
+ // Switch users to someone with less permissions.
+ $this->setUser($this->user);
+ $id = $result->id;
+ $result = external::read_competency_framework($id);
+ $result = (object) external_api::clean_returnvalue(external::read_competency_framework_returns(), $result);
+
+ $this->assertGreaterThan(0, $result->timecreated);
+ $this->assertGreaterThan(0, $result->timemodified);
+ $this->assertEquals($this->creator->id, $result->usermodified);
+ $this->assertEquals('shortname', $result->shortname);
+ $this->assertEquals('idnumber', $result->idnumber);
+ $this->assertEquals('description', $result->description);
+ $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
+ $this->assertEquals(true, $result->visible);
+ }
+
+ /**
+ * Test we can delete a competency framework with manage permissions.
+ */
+ public function test_delete_competency_frameworks_with_manage_permissions() {
+ $this->setUser($this->creator);
+ $result = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $result);
+
+ $id = $result->id;
+ $result = external::delete_competency_framework($id);
+ $result = external_api::clean_returnvalue(external::delete_competency_framework_returns(), $result);
+
+ $this->assertTrue($result);
+ }
+
+ /**
+ * Test we can delete a competency framework with read permissions.
+ */
+ public function test_delete_competency_frameworks_with_read_permissions() {
+ $this->setExpectedException('required_capability_exception');
+ $this->setUser($this->creator);
+ $result = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $result);
+
+ $id = $result->id;
+ // Switch users to someone with less permissions.
+ $this->setUser($this->user);
+ $result = external::delete_competency_framework($id);
+ }
+
+ /**
+ * Test we can update a competency framework with manage permissions.
+ */
+ public function test_update_competency_frameworks_with_manage_permissions() {
+ $this->setUser($this->creator);
+ $result = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $result);
+
+ $result = external::update_competency_framework($result->id, 'shortname2', 'idnumber2', 'description2', FORMAT_PLAIN, false);
+ $result = external_api::clean_returnvalue(external::update_competency_framework_returns(), $result);
+
+ $this->assertTrue($result);
+ }
+
+ /**
+ * Test we can update a competency framework with read permissions.
+ */
+ public function test_update_competency_frameworks_with_read_permissions() {
+ $this->setExpectedException('required_capability_exception');
+ $this->setUser($this->creator);
+ $result = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $result);
+
+ $this->setUser($this->user);
+ $result = external::update_competency_framework($result->id, 'shortname2', 'idnumber2', 'description2', FORMAT_PLAIN, false);
+ }
+
+ /**
+ * Test we can list and count competency frameworks with manage permissions.
+ */
+ public function test_list_and_count_competency_frameworks_with_manage_permissions() {
+ $this->setUser($this->creator);
+ $result = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $result = external::create_competency_framework('shortname2', 'idnumber2', 'description', FORMAT_HTML, true);
+ $result = external::create_competency_framework('shortname3', 'idnumber3', 'description', FORMAT_HTML, true);
+
+ $result = external::count_competency_frameworks(array());
+ $result = external_api::clean_returnvalue(external::count_competency_frameworks_returns(), $result);
+
+ $this->assertEquals($result, 3);
+
+ $result = external::list_competency_frameworks(array(), 'shortname', 'ASC', 0, 10);
+ $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
+
+ $this->assertEquals(count($result), 3);
+ $result = (object) $result[0];
+
+ $this->assertGreaterThan(0, $result->timecreated);
+ $this->assertGreaterThan(0, $result->timemodified);
+ $this->assertEquals($this->creator->id, $result->usermodified);
+ $this->assertEquals('shortname', $result->shortname);
+ $this->assertEquals('idnumber', $result->idnumber);
+ $this->assertEquals('description', $result->description);
+ $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
+ $this->assertEquals(true, $result->visible);
+ }
+
+ /**
+ * Test we can list and count competency frameworks with read permissions.
+ */
+ public function test_list_and_count_competency_frameworks_with_read_permissions() {
+ $this->setUser($this->creator);
+ $result = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $result = external::create_competency_framework('shortname2', 'idnumber2', 'description', FORMAT_HTML, true);
+ $result = external::create_competency_framework('shortname3', 'idnumber3', 'description', FORMAT_HTML, true);
+
+ $this->setUser($this->user);
+ $result = external::count_competency_frameworks(array());
+ $result = external_api::clean_returnvalue(external::count_competency_frameworks_returns(), $result);
+
+ $this->assertEquals($result, 3);
+
+ $result = external::list_competency_frameworks(array(), 'shortname', 'ASC', 0, 10);
+ $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
+
+ $this->assertEquals(count($result), 3);
+ $result = (object) $result[0];
+
+ $this->assertGreaterThan(0, $result->timecreated);
+ $this->assertGreaterThan(0, $result->timemodified);
+ $this->assertEquals($this->creator->id, $result->usermodified);
+ $this->assertEquals('shortname', $result->shortname);
+ $this->assertEquals('idnumber', $result->idnumber);
+ $this->assertEquals('description', $result->description);
+ $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
+ $this->assertEquals(true, $result->visible);
+ }
+
+ /**
+ * Test we can re-order competency frameworks.
+ */
+ public function test_reorder_competency_framework() {
+ $this->setUser($this->creator);
+ $f1 = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $f2 = external::create_competency_framework('shortname2', 'idnumber2', 'description', FORMAT_HTML, true);
+ $f3 = external::create_competency_framework('shortname3', 'idnumber3', 'description', FORMAT_HTML, true);
+ $f4 = external::create_competency_framework('shortname4', 'idnumber4', 'description', FORMAT_HTML, true);
+ $f5 = external::create_competency_framework('shortname5', 'idnumber5', 'description', FORMAT_HTML, true);
+ $f6 = external::create_competency_framework('shortname6', 'idnumber6', 'description', FORMAT_HTML, true);
+
+ // This is a move up.
+ $result = external::reorder_competency_framework($f5->id, $f2->id);
+ $result = external::list_competency_frameworks(array(), 'sortorder', 'ASC', 0, 10);
+ $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
+
+ $r1 = (object) $result[0];
+ $r2 = (object) $result[1];
+ $r3 = (object) $result[2];
+ $r4 = (object) $result[3];
+ $r5 = (object) $result[4];
+ $r6 = (object) $result[5];
+
+ $this->assertEquals($f1->id, $r1->id);
+ $this->assertEquals($f5->id, $r2->id);
+ $this->assertEquals($f2->id, $r3->id);
+ $this->assertEquals($f3->id, $r4->id);
+ $this->assertEquals($f4->id, $r5->id);
+ $this->assertEquals($f6->id, $r6->id);
+
+ // This is a move down.
+ $result = external::reorder_competency_framework($f5->id, $f4->id);
+ $result = external::list_competency_frameworks(array(), 'sortorder', 'ASC', 0, 10);
+ $result = external_api::clean_returnvalue(external::list_competency_frameworks_returns(), $result);
+
+ $r1 = (object) $result[0];
+ $r2 = (object) $result[1];
+ $r3 = (object) $result[2];
+ $r4 = (object) $result[3];
+ $r5 = (object) $result[4];
+ $r6 = (object) $result[5];
+
+ $this->assertEquals($f1->id, $r1->id);
+ $this->assertEquals($f2->id, $r2->id);
+ $this->assertEquals($f3->id, $r3->id);
+ $this->assertEquals($f4->id, $r4->id);
+ $this->assertEquals($f5->id, $r5->id);
+ $this->assertEquals($f6->id, $r6->id);
+
+ $this->setExpectedException('required_capability_exception');
+ $this->setUser($this->user);
+ $result = external::reorder_competency_framework($f5->id, $f4->id);
+ }
+
+ /**
+ * Test we can't create a competency with only read permissions.
+ */
+ public function test_create_competency_with_read_permissions() {
+ $this->setExpectedException('required_capability_exception');
+ $framework = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $framework = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $framework);
+ $this->setUser($this->user);
+ $competency = external::create_competency('shortname', 'idnumber', 'description', FORMAT_HTML, true, $framework->id, 0);
+ }
+
+ /**
+ * Test we can create a competency with manage permissions.
+ */
+ public function test_create_competency_with_manage_permissions() {
+ $this->setUser($this->creator);
+ $framework = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $framework = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $framework);
+
+ $competency = external::create_competency('shortname', 'idnumber', 'description', FORMAT_HTML, true, $framework->id, 0);
+ $competency = (object) external_api::clean_returnvalue(external::create_competency_returns(), $competency);
+
+ $this->assertGreaterThan(0, $competency->timecreated);
+ $this->assertGreaterThan(0, $competency->timemodified);
+ $this->assertEquals($this->creator->id, $competency->usermodified);
+ $this->assertEquals('shortname', $competency->shortname);
+ $this->assertEquals('idnumber', $competency->idnumber);
+ $this->assertEquals('description', $competency->description);
+ $this->assertEquals(FORMAT_HTML, $competency->descriptionformat);
+ $this->assertEquals(true, $competency->visible);
+ $this->assertEquals(0, $competency->parentid);
+ $this->assertEquals($framework->id, $competency->competencyframeworkid);
+ }
+
+ /**
+ * Test we cannot create a competency with nasty data.
+ */
+ public function test_create_competency_with_nasty_data() {
+ $this->setUser($this->creator);
+ $framework = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $framework = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $framework);
+ $this->setExpectedException('invalid_parameter_exception');
+ $competency = external::create_competency('shortname ', 'id;"number', 'de<>\\..scription', FORMAT_HTML, true, $framework->id, 0);
+ }
+
+ /**
+ * Test we can read a competency with manage permissions.
+ */
+ public function test_read_competencies_with_manage_permissions() {
+ $this->setUser($this->creator);
+ $framework = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $framework = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $framework);
+ $result = external::create_competency('shortname', 'idnumber', 'description', FORMAT_HTML, true, $framework->id, 0);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_returns(), $result);
+
+ $id = $result->id;
+ $result = external::read_competency($id);
+ $result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);
+
+ $this->assertGreaterThan(0, $result->timecreated);
+ $this->assertGreaterThan(0, $result->timemodified);
+ $this->assertEquals($this->creator->id, $result->usermodified);
+ $this->assertEquals('shortname', $result->shortname);
+ $this->assertEquals('idnumber', $result->idnumber);
+ $this->assertEquals('description', $result->description);
+ $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
+ $this->assertEquals(true, $result->visible);
+ $this->assertEquals(0, $result->parentid);
+ $this->assertEquals(0, $result->parentid);
+ }
+
+ /**
+ * Test we can read a competency with read permissions.
+ */
+ public function test_read_competencies_with_read_permissions() {
+ $this->setUser($this->creator);
+ $framework = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $framework = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $framework);
+ $result = external::create_competency('shortname', 'idnumber', 'description', FORMAT_HTML, true, $framework->id, 0);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_returns(), $result);
+
+ // Switch users to someone with less permissions.
+ $this->setUser($this->user);
+ $id = $result->id;
+ $result = external::read_competency($id);
+ $result = (object) external_api::clean_returnvalue(external::read_competency_returns(), $result);
+
+ $this->assertGreaterThan(0, $result->timecreated);
+ $this->assertGreaterThan(0, $result->timemodified);
+ $this->assertEquals($this->creator->id, $result->usermodified);
+ $this->assertEquals('shortname', $result->shortname);
+ $this->assertEquals('idnumber', $result->idnumber);
+ $this->assertEquals('description', $result->description);
+ $this->assertEquals(FORMAT_HTML, $result->descriptionformat);
+ $this->assertEquals(true, $result->visible);
+ $this->assertEquals(0, $result->parentid);
+ $this->assertEquals(0, $result->parentid);
+ }
+
+ /**
+ * Test we can delete a competency with manage permissions.
+ */
+ public function test_delete_competency_with_manage_permissions() {
+ $this->setUser($this->creator);
+ $framework = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $framework = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $framework);
+ $result = external::create_competency('shortname', 'idnumber', 'description', FORMAT_HTML, true, $framework->id, 0);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_returns(), $result);
+
+ $id = $result->id;
+ $result = external::delete_competency($id);
+ $result = external_api::clean_returnvalue(external::delete_competency_returns(), $result);
+
+ $this->assertTrue($result);
+ }
+
+ /**
+ * Test we can delete a competency with read permissions.
+ */
+ public function test_delete_competency_with_read_permissions() {
+ $this->setExpectedException('required_capability_exception');
+ $this->setUser($this->creator);
+ $framework = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $framework = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $framework);
+ $result = external::create_competency('shortname', 'idnumber', 'description', FORMAT_HTML, true, $framework->id, 0);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_returns(), $result);
+
+ $id = $result->id;
+ // Switch users to someone with less permissions.
+ $this->setUser($this->user);
+ $result = external::delete_competency($id);
+ }
+
+ /**
+ * Test we can update a competency with manage permissions.
+ */
+ public function test_update_competency_with_manage_permissions() {
+ $this->setUser($this->creator);
+ $framework = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $framework = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $framework);
+ $result = external::create_competency('shortname', 'idnumber', 'description', FORMAT_HTML, true, $framework->id, 0);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_returns(), $result);
+
+ $result = external::update_competency($result->id, 'shortname2', 'idnumber2', 'description2', FORMAT_HTML, false);
+ $result = external_api::clean_returnvalue(external::update_competency_returns(), $result);
+
+ $this->assertTrue($result);
+ }
+
+ /**
+ * Test we can update a competency with read permissions.
+ */
+ public function test_update_competency_with_read_permissions() {
+ $this->setExpectedException('required_capability_exception');
+ $this->setUser($this->creator);
+ $framework = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $framework = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $framework);
+ $result = external::create_competency('shortname', 'idnumber', 'description', FORMAT_HTML, true, $framework->id, 0);
+ $result = (object) external_api::clean_returnvalue(external::create_competency_returns(), $result);
+
+ $this->setUser($this->user);
+ $result = external::update_competency($result->id, 'shortname2', 'idnumber2', 'description2', FORMAT_HTML, false);
+ }
+
+ /**
+ * Test we can list and count competencies with manage permissions.
+ */
+ public function test_list_and_count_competencies_with_manage_permissions() {
+ $this->setUser($this->creator);
+ $framework = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $framework = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $framework);
+ $result = external::create_competency('shortname', 'idnumber', 'description', FORMAT_HTML, true, $framework->id, 0);
+ $result = external::create_competency('shortname2', 'idnumber2', 'description2', FORMAT_HTML, true, $framework->id, 0);
+ $result = external::create_competency('shortname3', 'idnumber3', 'description3', FORMAT_HTML, true, $framework->id, 0);
+
+ $result = external::count_competencies(array());
+ $result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);
+
+ $this->assertEquals($result, 3);
+
+ $result = external::list_competencies(array(), 'shortname', 'ASC', 0, 10);
+ $result = external_api::clean_returnvalue(external::list_competencies_returns(), $result);
+
+ $this->assertEquals(count($result), 3);
+ $result = (object) $result[0];
+
+ $this->assertGreaterThan(0, $result->timecreated);
+ $this->assertGreaterThan(0, $result->timemodified);
+ $this->assertEquals($this->creator->id, $result->usermodified);
+ $this->assertEquals('shortname', $result->shortname);
+ $this->assertEquals('idnumber', $result->idnumber);
+ $this->assertEquals('description', $result->description);
+ $this->assertEquals(true, $result->visible);
+ }
+
+ /**
+ * Test we can list and count competencies with read permissions.
+ */
+ public function test_list_and_count_competencies_with_read_permissions() {
+ $this->setUser($this->creator);
+ $framework = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $framework = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $framework);
+ $result = external::create_competency('shortname', 'idnumber', 'description', FORMAT_HTML, true, $framework->id, 0);
+ $result = external::create_competency('shortname2', 'idnumber2', 'description2', FORMAT_HTML, true, $framework->id, 0);
+ $result = external::create_competency('shortname3', 'idnumber3', 'description3', FORMAT_HTML, true, $framework->id, 0);
+
+ $this->setUser($this->user);
+
+ $result = external::count_competencies(array());
+ $result = external_api::clean_returnvalue(external::count_competencies_returns(), $result);
+
+ $this->assertEquals($result, 3);
+
+ $result = external::list_competencies(array(), 'shortname', 'ASC', 0, 10);
+ $result = external_api::clean_returnvalue(external::list_competencies_returns(), $result);
+
+ $this->assertEquals(count($result), 3);
+ $result = (object) $result[0];
+
+ $this->assertGreaterThan(0, $result->timecreated);
+ $this->assertGreaterThan(0, $result->timemodified);
+ $this->assertEquals($this->creator->id, $result->usermodified);
+ $this->assertEquals('shortname', $result->shortname);
+ $this->assertEquals('idnumber', $result->idnumber);
+ $this->assertEquals('description', $result->description);
+ $this->assertEquals(true, $result->visible);
+ }
+
+ /**
+ * Test we can search for competencies.
+ */
+ public function test_search_competencies_with_read_permissions() {
+ $this->setUser($this->creator);
+ $framework = external::create_competency_framework('shortname', 'idnumber', 'description', FORMAT_HTML, true);
+ $framework = (object) external_api::clean_returnvalue(external::create_competency_framework_returns(), $framework);
+ $result = external::create_competency('shortname', 'idnumber', 'description', FORMAT_HTML, true, $framework->id, 0);
+ $result = external::create_competency('shortname2', 'idnumber2', 'description2', FORMAT_HTML, true, $framework->id, 0);
+ $result = external::create_competency('shortname3', 'idnumber3', 'description3', FORMAT_HTML, true, $framework->id, 0);
+
+ $this->setUser($this->user);
+
+ $result = external::search_competencies('short', $framework->id);
+ $result = external_api::clean_returnvalue(external::search_competencies_returns(), $result);
+
+ $this->assertEquals(count($result), 3);
+ $result = (object) $result[0];
+
+ $this->assertGreaterThan(0, $result->timecreated);
+ $this->assertGreaterThan(0, $result->timemodified);
+ $this->assertEquals($this->creator->id, $result->usermodified);
+ $this->assertEquals('shortname', $result->shortname);
+ $this->assertEquals('idnumber', $result->idnumber);
+ $this->assertEquals('description', $result->description);
+ $this->assertEquals(true, $result->visible);
+ }
+
+}
diff --git a/admin/tool/lp/version.php b/admin/tool/lp/version.php
new file mode 100644
index 00000000000..118814e480b
--- /dev/null
+++ b/admin/tool/lp/version.php
@@ -0,0 +1,30 @@
+.
+
+/**
+ * Plugin version info
+ *
+ * @package tool_lp
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$plugin->version = 2015021623; // 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).
+
diff --git a/lib/amd/src/dialogue.js b/lib/amd/src/dialogue.js
new file mode 100644
index 00000000000..034239e543c
--- /dev/null
+++ b/lib/amd/src/dialogue.js
@@ -0,0 +1,76 @@
+// 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 .
+
+/**
+ * Wrapper for the YUI M.core.notification class. Allows us to
+ * use the YUI version in AMD code until it is replaced.
+ *
+ * @module core/dialogue
+ * @package core
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+define(['core/yui'], function(Y) {
+
+ // Private variables and functions.
+ /**
+ * Constructor
+ *
+ * @param {string} title Title for the window.
+ * @param {string} content The content for the window.
+ * @param {function} afterShow Callback executed after the window is opened.
+ */
+ var dialogue = function(title, content, afterShow) {
+ this.yuiDialogue = null;
+ var parent = this;
+
+ Y.use('moodle-core-notification', function () {
+
+ parent.yuiDialogue = new M.core.dialogue({
+ headerContent: title,
+ bodyContent: content,
+ draggable: true,
+ visible: false,
+ center: true,
+ modal: true
+ });
+
+ parent.yuiDialogue.after('visibleChange', function(e) {
+ if (e.newVal) {
+ afterShow(parent);
+ }
+ });
+
+ parent.yuiDialogue.show();
+ });
+ };
+
+ /**
+ * Close this window.
+ */
+ dialogue.prototype.close = function() {
+ this.yuiDialogue.hide();
+ this.yuiDialogue.destroy();
+ };
+
+ /**
+ * Get content.
+ */
+ dialogue.prototype.getContent = function() {
+ return this.yuiDialogue.bodyNode.getDOMNode();
+ };
+
+ return /** @alias module:core/dialogue */ dialogue;
+});
diff --git a/lib/amd/src/url.js b/lib/amd/src/url.js
index b3263eec3d5..047e739e997 100644
--- a/lib/amd/src/url.js
+++ b/lib/amd/src/url.js
@@ -70,7 +70,7 @@ define(['core/config'], function(config) {
}
// Fix admin urls.
- if (config.admin !== 'admin') {
+ if (typeof config.admin != "undefined" && config.admin !== 'admin') {
relativePath = relativePath.replace(/^\/admin\//, '/' + config.admin + '/');
}
return config.wwwroot + relativePath;