diff --git a/admin/tool/lp/classes/api.php b/admin/tool/lp/classes/api.php index ede7f0ec75b..5710b434bce 100644 --- a/admin/tool/lp/classes/api.php +++ b/admin/tool/lp/classes/api.php @@ -343,6 +343,12 @@ class api { public static function create_framework(stdClass $record) { $framework = new competency_framework(0, $record); require_capability('tool/lp:competencymanage', $framework->get_context()); + + // Account for different formats of taxonomies. + if (isset($record->taxonomies)) { + $framework->set_taxonomies($record->taxonomies); + } + $id = $framework->create(); return $framework; } @@ -371,9 +377,16 @@ class api { */ public static function update_framework($record) { $framework = new competency_framework($record->id); + // Check the permissions before update. require_capability('tool/lp:competencymanage', $framework->get_context()); + + // Account for different formats of taxonomies. $framework->from_record($record); + if (isset($record->taxonomies)) { + $framework->set_taxonomies($record->taxonomies); + } + return $framework->update(); } diff --git a/admin/tool/lp/classes/competency_framework.php b/admin/tool/lp/classes/competency_framework.php index 0b98dccc2c3..da81135a5f1 100644 --- a/admin/tool/lp/classes/competency_framework.php +++ b/admin/tool/lp/classes/competency_framework.php @@ -37,6 +37,29 @@ class competency_framework extends persistent { const TABLE = 'tool_lp_competency_framework'; + /** Taxonomy constant. */ + const TAXONOMY_BEHAVIOUR = 'behaviour'; + /** Taxonomy constant. */ + const TAXONOMY_COMPETENCY = 'competency'; + /** Taxonomy constant. */ + const TAXONOMY_CONCEPT = 'concept'; + /** Taxonomy constant. */ + const TAXONOMY_DOMAIN = 'domain'; + /** Taxonomy constant. */ + const TAXONOMY_INDICATOR = 'indicator'; + /** Taxonomy constant. */ + const TAXONOMY_LEVEL = 'level'; + /** Taxonomy constant. */ + const TAXONOMY_OUTCOME = 'outcome'; + /** Taxonomy constant. */ + const TAXONOMY_PRACTICE = 'practice'; + /** Taxonomy constant. */ + const TAXONOMY_PROFICIENCY = 'proficiency'; + /** Taxonomy constant. */ + const TAXONOMY_SKILL = 'skill'; + /** Taxonomy constant. */ + const TAXONOMY_VALUE = 'value'; + /** * Get the context. * @@ -85,9 +108,66 @@ class competency_framework extends persistent { 'contextid' => array( 'type' => PARAM_INT ), + 'taxonomies' => array( + 'type' => PARAM_RAW, + 'default' => '' + ) ); } + /** + * Get the translated name for a level. + * + * @param int $level The level of the term. + * @return lang_string + */ + public function get_taxonomy($level) { + $taxonomies = $this->get_taxonomies(); + + if (empty($taxonomies[$level])) { + // If for some reason we cannot find the level, we fallback onto competency. + $constant = self::TAXONOMY_COMPETENCY; + } else { + $constant = $taxonomies[$level]; + } + + return self::get_taxonomy_from_constant($constant); + } + + /** + * Return the taxonomy constants indexed by level. + * + * @return array Contains the list of taxonomy constants indexed by level. + */ + public function get_taxonomies() { + $taxonomies = explode(',', $this->get('taxonomies')); + + // Indexing first level at 1. + array_unshift($taxonomies, null); + unset($taxonomies[0]); + + // Ensure that we do not return empty levels. + for ($i = 1; $i <= self::get_taxonomies_max_level(); $i++) { + if (empty($taxonomies[$i])) { + $taxonomies[$i] = self::TAXONOMY_COMPETENCY; + } + } + + return $taxonomies; + } + + /** + * Convenience method to set taxonomies from an array or string. + * + * @param string|array $taxonomies A string, or an array where the values are the term constants. + */ + public function set_taxonomies($taxonomies) { + if (is_array($taxonomies)) { + $taxonomies = implode(',', $taxonomies); + } + $this->set('taxonomies', $taxonomies); + } + /** * Validate the context ID. * @@ -117,4 +197,77 @@ class competency_framework extends persistent { return true; } + /** + * Validate taxonomies. + * + * @param mixed $value The taxonomies. + * @return true|lang_string + */ + protected function validate_taxonomies($value) { + $terms = explode(',', $value); + + if (count($terms) > self::get_taxonomies_max_level()) { + return new lang_string('invaliddata', 'error'); + } + + foreach ($terms as $term) { + if (!empty($term) && !array_key_exists($term, self::get_taxonomies_list())) { + return new lang_string('invalidtaxonomy', 'tool_lp', $term); + } + } + + return true; + } + + /** + * Get the string of a taxonomy from a constant + * + * @param string $constant The taxonomy constant. + * @return lang_string + */ + public static function get_taxonomy_from_constant($constant) { + return self::get_taxonomies_list()[$constant]; + } + + /** + * Return the maximum number of taxonomy levels. + * + * This is a method and not a constant because we want to make it easy to adapt + * to the number of levels desired in the future. + * + * @return int + */ + public static function get_taxonomies_max_level() { + return 4; + } + + /** + * Get the list of all taxonomies. + * + * @return array Where the key is the taxonomy constant, and the value its translation. + */ + public static function get_taxonomies_list() { + static $list = null; + + // At some point we'll have to switch to not using static cache, mainly for Unit Tests in case we + // decide to allow more taxonomies to be added dynamically from a CFG variable for instance. + if ($list === null) { + $list = array( + self::TAXONOMY_BEHAVIOUR => new lang_string('taxonomy_' . self::TAXONOMY_BEHAVIOUR, 'tool_lp'), + self::TAXONOMY_COMPETENCY => new lang_string('taxonomy_' . self::TAXONOMY_COMPETENCY, 'tool_lp'), + self::TAXONOMY_CONCEPT => new lang_string('taxonomy_' . self::TAXONOMY_CONCEPT, 'tool_lp'), + self::TAXONOMY_DOMAIN => new lang_string('taxonomy_' . self::TAXONOMY_DOMAIN, 'tool_lp'), + self::TAXONOMY_INDICATOR => new lang_string('taxonomy_' . self::TAXONOMY_INDICATOR, 'tool_lp'), + self::TAXONOMY_LEVEL => new lang_string('taxonomy_' . self::TAXONOMY_LEVEL, 'tool_lp'), + self::TAXONOMY_OUTCOME => new lang_string('taxonomy_' . self::TAXONOMY_OUTCOME, 'tool_lp'), + self::TAXONOMY_PRACTICE => new lang_string('taxonomy_' . self::TAXONOMY_PRACTICE, 'tool_lp'), + self::TAXONOMY_PROFICIENCY => new lang_string('taxonomy_' . self::TAXONOMY_PROFICIENCY, 'tool_lp'), + self::TAXONOMY_SKILL => new lang_string('taxonomy_' . self::TAXONOMY_SKILL, 'tool_lp'), + self::TAXONOMY_VALUE => new lang_string('taxonomy_' . self::TAXONOMY_VALUE, 'tool_lp'), + ); + } + + return $list; + } + } diff --git a/admin/tool/lp/classes/external.php b/admin/tool/lp/classes/external.php index c9275dc4d35..628d2f90113 100644 --- a/admin/tool/lp/classes/external.php +++ b/admin/tool/lp/classes/external.php @@ -178,6 +178,10 @@ class external extends external_api { PARAM_TEXT, 'Scale configuration.' ); + $taxonomies = new external_value( + PARAM_RAW, + 'The taxonomy terms' + ); $visible = new external_value( PARAM_BOOL, 'Is this framework visible?' @@ -204,6 +208,7 @@ class external extends external_api { 'descriptionformatted' => $descriptionformatted, 'scaleid' => $scaleid, 'scaleconfiguration' => $scaleconfiguration, + 'taxonomies' => $taxonomies, 'visible' => $visible, 'timecreated' => $timecreated, 'timemodified' => $timemodified, diff --git a/admin/tool/lp/classes/form/competency_framework.php b/admin/tool/lp/classes/form/competency_framework.php index e05913e4373..cb5a0a02430 100644 --- a/admin/tool/lp/classes/form/competency_framework.php +++ b/admin/tool/lp/classes/form/competency_framework.php @@ -54,6 +54,8 @@ class competency_framework extends moodleform { $mform->setType('id', PARAM_INT); $mform->setDefault('id', 0); + $mform->addElement('header', 'generalhdr', get_string('general')); + $mform->addElement('text', 'shortname', get_string('shortname', 'tool_lp')); $mform->setType('shortname', PARAM_TEXT); @@ -85,6 +87,16 @@ class competency_framework extends moodleform { $mform->addElement('static', 'context', get_string('context', 'core_role')); $mform->setDefault('context', $context->get_context_name()); + $mform->addElement('header', 'taxonomyhdr', get_string('taxonomies', 'tool_lp')); + $taxonomies = \tool_lp\competency_framework::get_taxonomies_list(); + $taxdefaults = array(); + for ($i = 1; $i <= \tool_lp\competency_framework::get_taxonomies_max_level(); $i++) { + $mform->addElement('select', "taxonomies[$i]", get_string('levela', 'tool_lp', $i), $taxonomies); + $taxdefaults[$i] = \tool_lp\competency_framework::TAXONOMY_COMPETENCY; + } + // Not using taxonomies[n] here or it would takes precedence over set_data(array('taxonomies' => ...)). + $mform->setDefault('taxonomies', $taxdefaults); + $this->add_action_buttons(true, get_string('savechanges', 'tool_lp')); if (!empty($id)) { @@ -93,6 +105,8 @@ class competency_framework extends moodleform { $record = $framework->to_record(); // Massage for editor API. $record->description = array('text' => $record->description, 'format' => $record->descriptionformat); + // New hair cut for taxonomies. + $record->taxonomies = $framework->get_taxonomies(); $this->set_data($record); } } diff --git a/admin/tool/lp/db/install.xml b/admin/tool/lp/db/install.xml index 00d073d23d9..52e21d67bac 100755 --- a/admin/tool/lp/db/install.xml +++ b/admin/tool/lp/db/install.xml @@ -1,5 +1,5 @@ - @@ -38,6 +38,7 @@ + diff --git a/admin/tool/lp/db/upgrade.php b/admin/tool/lp/db/upgrade.php index 10abee2c32a..c53b0241d92 100644 --- a/admin/tool/lp/db/upgrade.php +++ b/admin/tool/lp/db/upgrade.php @@ -152,6 +152,20 @@ function xmldb_tool_lp_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2015052412, 'tool', 'lp'); } + if ($oldversion < 2015052414) { + + // Define field taxonomies to be added to tool_lp_competency_framework. + $table = new xmldb_table('tool_lp_competency_framework'); + $field = new xmldb_field('taxonomies', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'visible'); + + // Conditionally launch add field taxonomies. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Lp savepoint reached. + upgrade_plugin_savepoint(true, 2015052414, 'tool', 'lp'); + } return true; } diff --git a/admin/tool/lp/lang/en/tool_lp.php b/admin/tool/lp/lang/en/tool_lp.php index fdcbea53446..6b5fc6348ab 100644 --- a/admin/tool/lp/lang/en/tool_lp.php +++ b/admin/tool/lp/lang/en/tool_lp.php @@ -66,8 +66,10 @@ $string['hidden'] = 'Hidden'; $string['hiddenhint'] = '(hidden)'; $string['idnumber'] = 'Id number'; $string['invalidpersistent'] = 'Invalid persistent'; +$string['invalidtaxonomy'] = 'Invalid taxonomy: {$a}'; $string['itemstoadd'] = 'Items to add'; $string['learningplans'] = 'Learning plans'; +$string['levela'] = 'Level {$a}'; $string['linkcoursecompetencies'] = 'Link course competencies'; $string['linkedcourses'] = 'Linked courses'; $string['linktemplatecompetencies'] = 'Link template competencies'; @@ -124,6 +126,18 @@ $string['selectcompetencymovetarget'] = 'Select a location to move this competen $string['selectedcompetency'] = 'Selected competency'; $string['shortname'] = 'Name'; $string['status'] = 'Status'; +$string['taxonomies'] = 'Taxonomies'; +$string['taxonomy_behaviour'] = 'Behaviour'; +$string['taxonomy_competency'] = 'Competency'; +$string['taxonomy_concept'] = 'Concept'; +$string['taxonomy_domain'] = 'Domain'; +$string['taxonomy_indicator'] = 'Indicator'; +$string['taxonomy_level'] = 'Level'; +$string['taxonomy_outcome'] = 'Outcome'; +$string['taxonomy_practice'] = 'Practice'; +$string['taxonomy_proficiency'] = 'Proficiency'; +$string['taxonomy_skill'] = 'Skill'; +$string['taxonomy_value'] = 'Value'; $string['templatecompetencies'] = 'Template competencies'; $string['templatecreated'] = 'Learning plan template created'; $string['templatename'] = 'Name'; diff --git a/admin/tool/lp/version.php b/admin/tool/lp/version.php index d234ec7c2a8..c4ed10a33aa 100644 --- a/admin/tool/lp/version.php +++ b/admin/tool/lp/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2015052413; // The current plugin version (Date: YYYYMMDDXX). +$plugin->version = 2015052414; // 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).