Merge branch 'MDL-76889' of https://github.com/paulholden/moodle
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace core_competency\reportbuilder\datasource;
|
||||
|
||||
use core\reportbuilder\local\entities\context;
|
||||
use core_cohort\reportbuilder\local\entities\cohort;
|
||||
use core_competency\reportbuilder\local\entities\{competency, framework, usercompetency};
|
||||
use core_reportbuilder\datasource;
|
||||
use core_reportbuilder\local\entities\user;
|
||||
use core_reportbuilder\local\filters\boolean_select;
|
||||
use core_reportbuilder\local\helpers\database;
|
||||
|
||||
/**
|
||||
* Competencies datasource
|
||||
*
|
||||
* @package core_competency
|
||||
* @copyright 2024 Paul Holden <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class competencies extends datasource {
|
||||
|
||||
/**
|
||||
* Return user friendly name of the report source
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name(): string {
|
||||
return get_string('competencies', 'core_competency');
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise report
|
||||
*/
|
||||
protected function initialise(): void {
|
||||
$frameworkentity = new framework();
|
||||
$frameworkalias = $frameworkentity->get_table_alias('competency_framework');
|
||||
|
||||
$contextentity = new context();
|
||||
$contextalias = $contextentity->get_table_alias('context');
|
||||
|
||||
$this->set_main_table('competency_framework', $frameworkalias);
|
||||
|
||||
// Join context entity (unconditionally, as table also used by both framework/competency entities).
|
||||
$this->add_join("LEFT JOIN {context} {$contextalias} ON {$contextalias}.id = {$frameworkalias}.contextid");
|
||||
$this->add_entity($contextentity);
|
||||
|
||||
$this->add_entity($frameworkentity
|
||||
->set_table_join_alias('context', $contextalias)
|
||||
);
|
||||
|
||||
// Join competency entity.
|
||||
$competencyentity = new competency();
|
||||
$competencyalias = $competencyentity->get_table_alias('competency');
|
||||
$this->add_entity($competencyentity
|
||||
->set_table_join_alias('context', $contextalias)
|
||||
->add_join("LEFT JOIN {competency} {$competencyalias}
|
||||
ON {$competencyalias}.competencyframeworkid = {$frameworkalias}.id")
|
||||
);
|
||||
|
||||
// Join user competency entity.
|
||||
$usercompetencyentity = new usercompetency();
|
||||
$usercompetencyalias = $usercompetencyentity->get_table_alias('competency_usercomp');
|
||||
$this->add_entity($usercompetencyentity
|
||||
->add_joins($competencyentity->get_joins())
|
||||
->add_join("LEFT JOIN {competency_usercomp} {$usercompetencyalias}
|
||||
ON {$usercompetencyalias}.competencyid = {$competencyalias}.id")
|
||||
);
|
||||
|
||||
// Join user entity.
|
||||
$userentity = new user();
|
||||
$useralias = $userentity->get_table_alias('user');
|
||||
$this->add_entity($userentity
|
||||
->add_joins($usercompetencyentity->get_joins())
|
||||
->add_join("LEFT JOIN {user} {$useralias} ON {$useralias}.id = {$usercompetencyalias}.userid")
|
||||
);
|
||||
|
||||
// Join cohort entity.
|
||||
$cohortentity = new cohort();
|
||||
$cohortalias = $cohortentity->get_table_alias('cohort');
|
||||
$cohortmemberalias = database::generate_alias();
|
||||
$this->add_entity($cohortentity
|
||||
->add_joins($userentity->get_joins())
|
||||
->add_joins([
|
||||
"LEFT JOIN {cohort_members} {$cohortmemberalias} ON {$cohortmemberalias}.userid = {$useralias}.id",
|
||||
"LEFT JOIN {cohort} {$cohortalias} ON {$cohortalias}.id = {$cohortmemberalias}.cohortid",
|
||||
])
|
||||
);
|
||||
|
||||
// Add report elements from each of the entities we added to the report.
|
||||
$this->add_all_from_entities([
|
||||
$contextentity->get_entity_name(),
|
||||
$frameworkentity->get_entity_name(),
|
||||
$competencyentity->get_entity_name(),
|
||||
$usercompetencyentity->get_entity_name(),
|
||||
$userentity->get_entity_name(),
|
||||
]);
|
||||
|
||||
$this->add_all_from_entity(
|
||||
$cohortentity->get_entity_name(),
|
||||
['name', 'idnumber', 'description', 'customfield*'],
|
||||
['cohortselect', 'name', 'idnumber', 'customfield*'],
|
||||
['cohortselect', 'name', 'idnumber', 'customfield*'],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the columns that will be added to the report upon creation
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_default_columns(): array {
|
||||
return [
|
||||
'framework:name',
|
||||
'competency:name',
|
||||
'user:fullname',
|
||||
'usercompetency:proficient',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the column sorting that will be added to the report upon creation
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function get_default_column_sorting(): array {
|
||||
return [
|
||||
'framework:name' => SORT_ASC,
|
||||
'competency:name' => SORT_ASC,
|
||||
'user:fullname' => SORT_ASC,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the filters that will be added to the report upon creation
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_default_filters(): array {
|
||||
return [
|
||||
'competency:name',
|
||||
'user:fullname',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the conditions that will be added to the report upon creation
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_default_conditions(): array {
|
||||
return [
|
||||
'framework:visible',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the condition values that will be added to the report upon creation
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_default_condition_values(): array {
|
||||
return [
|
||||
'framework:visible_operator' => boolean_select::CHECKED,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace core_competency\reportbuilder\local\entities;
|
||||
|
||||
use core\{context, context_helper};
|
||||
use core\lang_string;
|
||||
use core_reportbuilder\local\entities\base;
|
||||
use core_reportbuilder\local\filters\{date, text};
|
||||
use core_reportbuilder\local\helpers\{database, format};
|
||||
use core_reportbuilder\local\report\{column, filter};
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Competency entity
|
||||
*
|
||||
* @package core_competency
|
||||
* @copyright 2024 Paul Holden <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class competency extends base {
|
||||
|
||||
/**
|
||||
* Database tables that this entity uses
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function get_default_tables(): array {
|
||||
return [
|
||||
'competency',
|
||||
'context',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The default title for this entity
|
||||
*
|
||||
* @return lang_string
|
||||
*/
|
||||
protected function get_default_entity_title(): lang_string {
|
||||
return new lang_string('competency', 'core_competency');
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the entity
|
||||
*
|
||||
* @return base
|
||||
*/
|
||||
public function initialise(): base {
|
||||
$columns = $this->get_all_columns();
|
||||
foreach ($columns as $column) {
|
||||
$this->add_column($column);
|
||||
}
|
||||
|
||||
// All the filters defined by the entity can also be used as conditions.
|
||||
$filters = $this->get_all_filters();
|
||||
foreach ($filters as $filter) {
|
||||
$this
|
||||
->add_filter($filter)
|
||||
->add_condition($filter);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of all available columns
|
||||
*
|
||||
* @return column[]
|
||||
*/
|
||||
protected function get_all_columns(): array {
|
||||
global $DB;
|
||||
|
||||
$contextalias = $this->get_table_alias('context');
|
||||
$competencyalias = $this->get_table_alias('competency');
|
||||
|
||||
// Name.
|
||||
$columns[] = (new column(
|
||||
'name',
|
||||
new lang_string('name'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->add_field("{$competencyalias}.shortname")
|
||||
->set_is_sortable(true);
|
||||
|
||||
// Description.
|
||||
$descriptionfieldsql = "{$competencyalias}.description";
|
||||
if ($DB->get_dbfamily() === 'oracle') {
|
||||
$descriptionfieldsql = $DB->sql_order_by_text($descriptionfieldsql, 1024);
|
||||
}
|
||||
$columns[] = (new column(
|
||||
'description',
|
||||
new lang_string('description'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->add_joins($this->get_context_joins())
|
||||
->set_type(column::TYPE_LONGTEXT)
|
||||
->add_field($descriptionfieldsql, 'description')
|
||||
->add_field("{$competencyalias}.descriptionformat")
|
||||
->add_fields(context_helper::get_preload_record_columns_sql($contextalias))
|
||||
->add_callback(static function(?string $description, stdClass $competency): string {
|
||||
if ($description === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
context_helper::preload_from_record(clone $competency);
|
||||
$context = context::instance_by_id($competency->ctxid);
|
||||
|
||||
return format_text($description, $competency->descriptionformat, ['context' => $context->id]);
|
||||
});
|
||||
|
||||
// ID number.
|
||||
$columns[] = (new column(
|
||||
'idnumber',
|
||||
new lang_string('idnumber'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->add_field("{$competencyalias}.idnumber")
|
||||
->set_is_sortable(true);
|
||||
|
||||
// Time created.
|
||||
$columns[] = (new column(
|
||||
'timecreated',
|
||||
new lang_string('timecreated', 'core_reportbuilder'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->set_type(column::TYPE_TIMESTAMP)
|
||||
->add_field("{$competencyalias}.timecreated")
|
||||
->set_is_sortable(true)
|
||||
->add_callback([format::class, 'userdate']);
|
||||
|
||||
// Time modified.
|
||||
$columns[] = (new column(
|
||||
'timemodified',
|
||||
new lang_string('timemodified', 'core_reportbuilder'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->set_type(column::TYPE_TIMESTAMP)
|
||||
->add_field("{$competencyalias}.timemodified")
|
||||
->set_is_sortable(true)
|
||||
->add_callback([format::class, 'userdate']);
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of all available filters
|
||||
*
|
||||
* @return filter[]
|
||||
*/
|
||||
protected function get_all_filters(): array {
|
||||
$competencyalias = $this->get_table_alias('competency');
|
||||
|
||||
// Name.
|
||||
$filters[] = (new filter(
|
||||
text::class,
|
||||
'name',
|
||||
new lang_string('name'),
|
||||
$this->get_entity_name(),
|
||||
"{$competencyalias}.shortname",
|
||||
))
|
||||
->add_joins($this->get_joins());
|
||||
|
||||
// ID number.
|
||||
$filters[] = (new filter(
|
||||
text::class,
|
||||
'idnumber',
|
||||
new lang_string('idnumber'),
|
||||
$this->get_entity_name(),
|
||||
"{$competencyalias}.idnumber",
|
||||
))
|
||||
->add_joins($this->get_joins());
|
||||
|
||||
// Time created.
|
||||
$filters[] = (new filter(
|
||||
date::class,
|
||||
'timecreated',
|
||||
new lang_string('timecreated', 'core_reportbuilder'),
|
||||
$this->get_entity_name(),
|
||||
"{$competencyalias}.timecreated",
|
||||
))
|
||||
->add_joins($this->get_joins());
|
||||
|
||||
// Time modified.
|
||||
$filters[] = (new filter(
|
||||
date::class,
|
||||
'timemodified',
|
||||
new lang_string('timemodified', 'core_reportbuilder'),
|
||||
$this->get_entity_name(),
|
||||
"{$competencyalias}.timemodified",
|
||||
))
|
||||
->add_joins($this->get_joins());
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return context joins
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function get_context_joins(): array {
|
||||
|
||||
// If the context table is already joined, we don't need to do that again.
|
||||
if ($this->has_table_join_alias('context')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$frameworkalias = database::generate_alias();
|
||||
$competencyalias = $this->get_table_alias('competency');
|
||||
$contextalias = $this->get_table_alias('context');
|
||||
|
||||
return [
|
||||
"LEFT JOIN {competency_framework} {$frameworkalias} ON {$frameworkalias}.id = {$competencyalias}.competencyframeworkid",
|
||||
"LEFT JOIN {context} {$contextalias} ON {$contextalias}.id = {$frameworkalias}.contextid",
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace core_competency\reportbuilder\local\entities;
|
||||
|
||||
use core\{context, context_helper};
|
||||
use core\lang_string;
|
||||
use core_reportbuilder\local\entities\base;
|
||||
use core_reportbuilder\local\filters\{boolean_select, date, select, text};
|
||||
use core_reportbuilder\local\helpers\format;
|
||||
use core_reportbuilder\local\report\{column, filter};
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Competency framework entity
|
||||
*
|
||||
* @package core_competency
|
||||
* @copyright 2024 Paul Holden <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class framework extends base {
|
||||
|
||||
/**
|
||||
* Database tables that this entity uses
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function get_default_tables(): array {
|
||||
return [
|
||||
'competency_framework',
|
||||
'context',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The default title for this entity
|
||||
*
|
||||
* @return lang_string
|
||||
*/
|
||||
protected function get_default_entity_title(): lang_string {
|
||||
return new lang_string('competencyframework', 'core_competency');
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the entity
|
||||
*
|
||||
* @return base
|
||||
*/
|
||||
public function initialise(): base {
|
||||
$columns = $this->get_all_columns();
|
||||
foreach ($columns as $column) {
|
||||
$this->add_column($column);
|
||||
}
|
||||
|
||||
// All the filters defined by the entity can also be used as conditions.
|
||||
$filters = $this->get_all_filters();
|
||||
foreach ($filters as $filter) {
|
||||
$this
|
||||
->add_filter($filter)
|
||||
->add_condition($filter);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of all available columns
|
||||
*
|
||||
* @return column[]
|
||||
*/
|
||||
protected function get_all_columns(): array {
|
||||
global $DB;
|
||||
|
||||
$frameworkalias = $this->get_table_alias('competency_framework');
|
||||
$contextalias = $this->get_table_alias('context');
|
||||
|
||||
// Name.
|
||||
$columns[] = (new column(
|
||||
'name',
|
||||
new lang_string('name'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->add_field("{$frameworkalias}.shortname")
|
||||
->set_is_sortable(true);
|
||||
|
||||
// Description.
|
||||
$descriptionfieldsql = "{$frameworkalias}.description";
|
||||
if ($DB->get_dbfamily() === 'oracle') {
|
||||
$descriptionfieldsql = $DB->sql_order_by_text($descriptionfieldsql, 1024);
|
||||
}
|
||||
$columns[] = (new column(
|
||||
'description',
|
||||
new lang_string('description'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->add_join($this->get_context_join())
|
||||
->set_type(column::TYPE_LONGTEXT)
|
||||
->add_field($descriptionfieldsql, 'description')
|
||||
->add_field("{$frameworkalias}.descriptionformat")
|
||||
->add_fields(context_helper::get_preload_record_columns_sql($contextalias))
|
||||
->add_callback(static function(?string $description, stdClass $framework): string {
|
||||
if ($description === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
context_helper::preload_from_record(clone $framework);
|
||||
$context = context::instance_by_id($framework->ctxid);
|
||||
|
||||
return format_text($description, $framework->descriptionformat, ['context' => $context->id]);
|
||||
});
|
||||
|
||||
// ID number.
|
||||
$columns[] = (new column(
|
||||
'idnumber',
|
||||
new lang_string('idnumber'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->add_field("{$frameworkalias}.idnumber")
|
||||
->set_is_sortable(true);
|
||||
|
||||
// Scale.
|
||||
$columns[] = (new column(
|
||||
'scale',
|
||||
new lang_string('scale'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->add_field("{$frameworkalias}.scaleid")
|
||||
->add_callback(static function(?string $scaleid): string {
|
||||
$scales = get_scales_menu();
|
||||
return (string) ($scales[(int) $scaleid] ?? $scaleid);
|
||||
});
|
||||
|
||||
// Visible.
|
||||
$columns[] = (new column(
|
||||
'visible',
|
||||
new lang_string('visible'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->set_type(column::TYPE_BOOLEAN)
|
||||
->add_field("{$frameworkalias}.visible")
|
||||
->set_is_sortable(true)
|
||||
->add_callback([format::class, 'boolean_as_text']);
|
||||
|
||||
// Time created.
|
||||
$columns[] = (new column(
|
||||
'timecreated',
|
||||
new lang_string('timecreated', 'core_reportbuilder'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->set_type(column::TYPE_TIMESTAMP)
|
||||
->add_field("{$frameworkalias}.timecreated")
|
||||
->set_is_sortable(true)
|
||||
->add_callback([format::class, 'userdate']);
|
||||
|
||||
// Time modified.
|
||||
$columns[] = (new column(
|
||||
'timemodified',
|
||||
new lang_string('timemodified', 'core_reportbuilder'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->set_type(column::TYPE_TIMESTAMP)
|
||||
->add_field("{$frameworkalias}.timemodified")
|
||||
->set_is_sortable(true)
|
||||
->add_callback([format::class, 'userdate']);
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of all available filters
|
||||
*
|
||||
* @return filter[]
|
||||
*/
|
||||
protected function get_all_filters(): array {
|
||||
$frameworkalias = $this->get_table_alias('competency_framework');
|
||||
|
||||
// Name.
|
||||
$filters[] = (new filter(
|
||||
text::class,
|
||||
'name',
|
||||
new lang_string('name'),
|
||||
$this->get_entity_name(),
|
||||
"{$frameworkalias}.shortname",
|
||||
))
|
||||
->add_joins($this->get_joins());
|
||||
|
||||
// ID number.
|
||||
$filters[] = (new filter(
|
||||
text::class,
|
||||
'idnumber',
|
||||
new lang_string('idnumber'),
|
||||
$this->get_entity_name(),
|
||||
"{$frameworkalias}.idnumber",
|
||||
))
|
||||
->add_joins($this->get_joins());
|
||||
|
||||
// Scale.
|
||||
$filters[] = (new filter(
|
||||
select::class,
|
||||
'scale',
|
||||
new lang_string('scale'),
|
||||
$this->get_entity_name(),
|
||||
"{$frameworkalias}.scaleid",
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->set_options_callback('get_scales_menu');
|
||||
|
||||
// Visible.
|
||||
$filters[] = (new filter(
|
||||
boolean_select::class,
|
||||
'visible',
|
||||
new lang_string('visible'),
|
||||
$this->get_entity_name(),
|
||||
"{$frameworkalias}.visible",
|
||||
))
|
||||
->add_joins($this->get_joins());
|
||||
|
||||
// Time created.
|
||||
$filters[] = (new filter(
|
||||
date::class,
|
||||
'timecreated',
|
||||
new lang_string('timecreated', 'core_reportbuilder'),
|
||||
$this->get_entity_name(),
|
||||
"{$frameworkalias}.timecreated",
|
||||
))
|
||||
->add_joins($this->get_joins());
|
||||
|
||||
// Time modified.
|
||||
$filters[] = (new filter(
|
||||
date::class,
|
||||
'timemodified',
|
||||
new lang_string('timemodified', 'core_reportbuilder'),
|
||||
$this->get_entity_name(),
|
||||
"{$frameworkalias}.timemodified",
|
||||
))
|
||||
->add_joins($this->get_joins());
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return context join
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_context_join(): string {
|
||||
|
||||
// If the context table is already joined, we don't need to do that again.
|
||||
if ($this->has_table_join_alias('context')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$frameworkalias = $this->get_table_alias('competency_framework');
|
||||
$contextalias = $this->get_table_alias('context');
|
||||
|
||||
return "LEFT JOIN {context} {$contextalias} ON {$contextalias}.id = {$frameworkalias}.contextid";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace core_competency\reportbuilder\local\entities;
|
||||
|
||||
use core\lang_string;
|
||||
use core_competency\{competency, user_competency};
|
||||
use core_reportbuilder\local\entities\base;
|
||||
use core_reportbuilder\local\filters\{boolean_select, select};
|
||||
use core_reportbuilder\local\helpers\format;
|
||||
use core_reportbuilder\local\report\{column, filter};
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* User competency entity
|
||||
*
|
||||
* @package core_competency
|
||||
* @copyright 2024 Paul Holden <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class usercompetency extends base {
|
||||
|
||||
/**
|
||||
* Database tables that this entity uses
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function get_default_tables(): array {
|
||||
return [
|
||||
'competency_usercomp',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The default title for this entity
|
||||
*
|
||||
* @return lang_string
|
||||
*/
|
||||
protected function get_default_entity_title(): lang_string {
|
||||
return new lang_string('usercompetency', 'core_competency');
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the entity
|
||||
*
|
||||
* @return base
|
||||
*/
|
||||
public function initialise(): base {
|
||||
$columns = $this->get_all_columns();
|
||||
foreach ($columns as $column) {
|
||||
$this->add_column($column);
|
||||
}
|
||||
|
||||
// All the filters defined by the entity can also be used as conditions.
|
||||
$filters = $this->get_all_filters();
|
||||
foreach ($filters as $filter) {
|
||||
$this
|
||||
->add_filter($filter)
|
||||
->add_condition($filter);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of all available columns
|
||||
*
|
||||
* @return column[]
|
||||
*/
|
||||
protected function get_all_columns(): array {
|
||||
$usercompetencyalias = $this->get_table_alias('competency_usercomp');
|
||||
|
||||
// Status.
|
||||
$columns[] = (new column(
|
||||
'status',
|
||||
new lang_string('status'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->set_type(column::TYPE_TEXT)
|
||||
->add_field("{$usercompetencyalias}.status")
|
||||
->set_is_sortable(true)
|
||||
->add_callback(static function(?string $status): string {
|
||||
if ($status === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (string) user_competency::get_status_name((int) $status);
|
||||
});
|
||||
|
||||
// Proficient.
|
||||
$columns[] = (new column(
|
||||
'proficient',
|
||||
new lang_string('proficient', 'core_competency'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->set_type(column::TYPE_BOOLEAN)
|
||||
->add_field("{$usercompetencyalias}.proficiency")
|
||||
->set_is_sortable(true)
|
||||
->add_callback([format::class, 'boolean_as_text']);
|
||||
|
||||
// Rating.
|
||||
$columns[] = (new column(
|
||||
'rating',
|
||||
new lang_string('rating', 'core_competency'),
|
||||
$this->get_entity_name(),
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->add_fields("{$usercompetencyalias}.grade, {$usercompetencyalias}.competencyid")
|
||||
->add_callback(static function(?string $grade, stdClass $row): string {
|
||||
if ($grade === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$competency = new competency($row->competencyid);
|
||||
$scale = $competency->get_scale()->scale_items;
|
||||
|
||||
return (string) ($scale[(int) $grade - 1] ?? $grade);
|
||||
});
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of all available filters
|
||||
*
|
||||
* @return filter[]
|
||||
*/
|
||||
protected function get_all_filters(): array {
|
||||
$usercompetencyalias = $this->get_table_alias('competency_usercomp');
|
||||
|
||||
// Status.
|
||||
$filters[] = (new filter(
|
||||
select::class,
|
||||
'status',
|
||||
new lang_string('status'),
|
||||
$this->get_entity_name(),
|
||||
"{$usercompetencyalias}.status",
|
||||
))
|
||||
->add_joins($this->get_joins())
|
||||
->set_options_callback([user_competency::class, 'get_status_list']);
|
||||
|
||||
// Proficient.
|
||||
$filters[] = (new filter(
|
||||
boolean_select::class,
|
||||
'proficient',
|
||||
new lang_string('proficient', 'core_competency'),
|
||||
$this->get_entity_name(),
|
||||
"{$usercompetencyalias}.proficiency",
|
||||
))
|
||||
->add_joins($this->get_joins());
|
||||
|
||||
return $filters;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace core_competency\reportbuilder\datasource;
|
||||
|
||||
use core_competency_generator;
|
||||
use core_competency\user_competency;
|
||||
use core_reportbuilder_generator;
|
||||
use core_reportbuilder_testcase;
|
||||
use core_reportbuilder\local\filters\{boolean_select, date, select, text};
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php");
|
||||
|
||||
/**
|
||||
* Unit tests for comptencies datasource
|
||||
*
|
||||
* @package core_competency
|
||||
* @covers \core_competency\reportbuilder\datasource\competencies
|
||||
* @copyright 2024 Paul Holden <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
final class competencies_test extends core_reportbuilder_testcase {
|
||||
|
||||
/**
|
||||
* Test default datasource
|
||||
*/
|
||||
public function test_datasource_default(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
/** @var core_competency_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_competency');
|
||||
|
||||
// First framework has two competencies.
|
||||
$framework = $generator->create_framework(['shortname' => 'Zoology']);
|
||||
$generator->create_competency(['competencyframeworkid' => $framework->get('id'), 'shortname' => 'Zebras']);
|
||||
$competency = $generator->create_competency([
|
||||
'competencyframeworkid' => $framework->get('id'),
|
||||
'shortname' => 'Aardvarks',
|
||||
]);
|
||||
|
||||
// Framework two has no competencies.
|
||||
$generator->create_framework(['shortname' => 'Algebra']);
|
||||
|
||||
// Assign user to second competency.
|
||||
$generator->create_user_competency([
|
||||
'competencyid' => $competency->get('id'),
|
||||
'userid' => $user->id,
|
||||
'proficiency' => true,
|
||||
'grade' => 1,
|
||||
]);
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
$report = $generator->create_report(['name' => 'Competencies', 'source' => competencies::class, 'default' => 1]);
|
||||
|
||||
$content = $this->get_custom_report_content($report->get('id'));
|
||||
|
||||
// Default columns are framework name, competency name, user fullname, proficient. Sorted by first three.
|
||||
$this->assertEquals([
|
||||
['Algebra', '', '', ''],
|
||||
['Zoology', 'Aardvarks', fullname($user), 'Yes'],
|
||||
['Zoology', 'Zebras', '', ''],
|
||||
], array_map('array_values', $content));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test datasource columns that aren't added by default
|
||||
*/
|
||||
public function test_datasource_non_default_columns(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$cohort = $this->getDataGenerator()->create_cohort(['name' => 'My cohort']);
|
||||
cohort_add_member($cohort->id, $user->id);
|
||||
|
||||
$scale = $this->getDataGenerator()->create_scale(['name' => 'My scale', 'scale' => 'A,B,C,D']);
|
||||
|
||||
/** @var core_competency_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_competency');
|
||||
|
||||
$framework = $generator->create_framework(['description' => 'So cool', 'idnumber' => 'FRM101', 'scaleid' => $scale->id]);
|
||||
$competency = $generator->create_competency(['competencyframeworkid' => $framework->get('id'), 'idnumber' => 'COM101']);
|
||||
$generator->create_user_competency([
|
||||
'competencyid' => $competency->get('id'),
|
||||
'userid' => $user->id,
|
||||
'proficiency' => true,
|
||||
'grade' => 3,
|
||||
]);
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
$report = $generator->create_report(['name' => 'Competencies', 'source' => competencies::class, 'default' => 0]);
|
||||
|
||||
// Framework.
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'framework:description']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'framework:idnumber']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'framework:scale']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'framework:visible']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'framework:timecreated']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'framework:timemodified']);
|
||||
|
||||
// Competency.
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'competency:idnumber']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'competency:timecreated']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'competency:timemodified']);
|
||||
|
||||
// User competency.
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'usercompetency:status']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'usercompetency:rating']);
|
||||
|
||||
// Cohort.
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'cohort:name']);
|
||||
|
||||
$content = $this->get_custom_report_content($report->get('id'));
|
||||
$this->assertCount(1, $content);
|
||||
|
||||
[
|
||||
$frameworkdescription,
|
||||
$frameworkidnumber,
|
||||
$frameworkscale,
|
||||
$frameworkvisible,
|
||||
$frameworktimecreated,
|
||||
$frameworktimemodified,
|
||||
$competencyidnumber,
|
||||
$competencytimecreated,
|
||||
$competencytimemodified,
|
||||
$usercompetencystatus,
|
||||
$usercompetencyrating,
|
||||
$cohortname,
|
||||
] = array_values($content[0]);
|
||||
|
||||
$this->assertEquals('So cool', $frameworkdescription);
|
||||
$this->assertEquals('FRM101', $frameworkidnumber);
|
||||
$this->assertEquals('My scale', $frameworkscale);
|
||||
$this->assertEquals('Yes', $frameworkvisible);
|
||||
$this->assertNotEmpty($frameworktimecreated);
|
||||
$this->assertNotEmpty($frameworktimemodified);
|
||||
$this->assertEquals('COM101', $competencyidnumber);
|
||||
$this->assertNotEmpty($competencytimecreated);
|
||||
$this->assertNotEmpty($competencytimemodified);
|
||||
$this->assertEquals('Idle', $usercompetencystatus);
|
||||
$this->assertEquals('C', $usercompetencyrating);
|
||||
$this->assertEquals('My cohort', $cohortname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for {@see test_datasource_filters}
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public static function datasource_filters_provider(): array {
|
||||
return [
|
||||
// Framework.
|
||||
'Framework name' => ['framework:name', [
|
||||
'framework:name_operator' => text::IS_EQUAL_TO,
|
||||
'framework:name_value' => 'How much I care',
|
||||
], true],
|
||||
'Framework name (no match)' => ['framework:name', [
|
||||
'framework:name_operator' => text::IS_EQUAL_TO,
|
||||
'framework:name_value' => 'Something else',
|
||||
], false],
|
||||
'Framework idnumber' => ['framework:idnumber', [
|
||||
'framework:idnumber_operator' => text::IS_EQUAL_TO,
|
||||
'framework:idnumber_value' => 'FRM101',
|
||||
], true],
|
||||
'Framework idnumber (no match)' => ['framework:idnumber', [
|
||||
'framework:idnumber_operator' => text::IS_EQUAL_TO,
|
||||
'framework:idnumber_value' => 'FRM102',
|
||||
], false],
|
||||
'Framework scale' => ['framework:scale', [
|
||||
'framework:scale_operator' => select::EQUAL_TO,
|
||||
'framework:scale_value' => '<SCALEID>',
|
||||
], true],
|
||||
'Framework scale (no match)' => ['framework:scale', [
|
||||
'framework:scale_operator' => select::EQUAL_TO,
|
||||
'framework:scale_value' => -1,
|
||||
], false],
|
||||
'Framework visible' => ['framework:visible', [
|
||||
'framework:visible_operator' => boolean_select::CHECKED,
|
||||
], true],
|
||||
'Framework visible (no match)' => ['framework:visible', [
|
||||
'framework:visible_operator' => boolean_select::NOT_CHECKED,
|
||||
], false],
|
||||
'Framework time created' => ['framework:timecreated', [
|
||||
'framework:timecreated_operator' => date::DATE_RANGE,
|
||||
'framework:timecreated_from' => 1622502000,
|
||||
], true],
|
||||
'Framework time created (no match)' => ['framework:timecreated', [
|
||||
'framework:timecreated_operator' => date::DATE_RANGE,
|
||||
'framework:timecreated_to' => 1622502000,
|
||||
], false],
|
||||
'Framework time modified' => ['framework:timemodified', [
|
||||
'framework:timemodified_operator' => date::DATE_RANGE,
|
||||
'framework:timemodified_from' => 1622502000,
|
||||
], true],
|
||||
'Framework time modified (no match)' => ['framework:timemodified', [
|
||||
'framework:timemodified_operator' => date::DATE_RANGE,
|
||||
'framework:timemodified_to' => 1622502000,
|
||||
], false],
|
||||
|
||||
// Competency.
|
||||
'Competency name' => ['competency:name', [
|
||||
'competency:name_operator' => text::IS_EQUAL_TO,
|
||||
'competency:name_value' => 'My framework',
|
||||
], true],
|
||||
'Competency name (no match)' => ['competency:name', [
|
||||
'competency:name_operator' => text::IS_EQUAL_TO,
|
||||
'competency:name_value' => 'Something else',
|
||||
], false],
|
||||
'Competency idnumber' => ['competency:idnumber', [
|
||||
'competency:idnumber_operator' => text::IS_EQUAL_TO,
|
||||
'competency:idnumber_value' => 'COM101',
|
||||
], true],
|
||||
'Competency idnumber (no match)' => ['competency:idnumber', [
|
||||
'competency:idnumber_operator' => text::IS_EQUAL_TO,
|
||||
'competency:idnumber_value' => 'COM102',
|
||||
], false],
|
||||
'Competency time created' => ['competency:timecreated', [
|
||||
'competency:timecreated_operator' => date::DATE_RANGE,
|
||||
'competency:timecreated_from' => 1622502000,
|
||||
], true],
|
||||
'Competency time created (no match)' => ['competency:timecreated', [
|
||||
'competency:timecreated_operator' => date::DATE_RANGE,
|
||||
'competency:timecreated_to' => 1622502000,
|
||||
], false],
|
||||
'Competency time modified' => ['competency:timemodified', [
|
||||
'competency:timemodified_operator' => date::DATE_RANGE,
|
||||
'competency:timemodified_from' => 1622502000,
|
||||
], true],
|
||||
'Competency time modified (no match)' => ['competency:timemodified', [
|
||||
'competency:timemodified_operator' => date::DATE_RANGE,
|
||||
'competency:timemodified_to' => 1622502000,
|
||||
], false],
|
||||
|
||||
// User competency.
|
||||
'User competency status' => ['usercompetency:status', [
|
||||
'usercompetency:status_operator' => SELECT::EQUAL_TO,
|
||||
'usercompetency:status_value' => user_competency::STATUS_IDLE,
|
||||
], true],
|
||||
'User competency status (no match)' => ['usercompetency:status', [
|
||||
'usercompetency:status_operator' => SELECT::EQUAL_TO,
|
||||
'usercompetency:status_value' => user_competency::STATUS_WAITING_FOR_REVIEW,
|
||||
], false],
|
||||
'User competency proficient' => ['usercompetency:proficient', [
|
||||
'usercompetency:proficient_operator' => boolean_select::CHECKED,
|
||||
], true],
|
||||
'User competency proficient (no match)' => ['usercompetency:proficient', [
|
||||
'usercompetency:proficient_operator' => boolean_select::NOT_CHECKED,
|
||||
], false],
|
||||
|
||||
// User.
|
||||
'User username' => ['user:username', [
|
||||
'user:username_operator' => text::IS_EQUAL_TO,
|
||||
'user:username_value' => 'testuser',
|
||||
], true],
|
||||
'User username (no match)' => ['user:username', [
|
||||
'user:username_operator' => text::IS_NOT_EQUAL_TO,
|
||||
'user:username_value' => 'testuser',
|
||||
], false],
|
||||
|
||||
// Cohort.
|
||||
'Cohort name' => ['cohort:name', [
|
||||
'cohort:name_operator' => text::IS_EQUAL_TO,
|
||||
'cohort:name_value' => 'My cohort',
|
||||
], true],
|
||||
'Cohort name (no match)' => ['cohort:name', [
|
||||
'cohort:name_operator' => text::IS_EQUAL_TO,
|
||||
'cohort:name_value' => 'Another cohort',
|
||||
], false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test datasource filters
|
||||
*
|
||||
* @param string $filtername
|
||||
* @param array $filtervalues
|
||||
* @param bool $expectmatch
|
||||
*
|
||||
* @dataProvider datasource_filters_provider
|
||||
*/
|
||||
public function test_datasource_filters(
|
||||
string $filtername,
|
||||
array $filtervalues,
|
||||
bool $expectmatch
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user(['username' => 'testuser']);
|
||||
$cohort = $this->getDataGenerator()->create_cohort(['name' => 'My cohort']);
|
||||
cohort_add_member($cohort->id, $user->id);
|
||||
|
||||
$scale = $this->getDataGenerator()->create_scale([]);
|
||||
|
||||
/** @var core_competency_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_competency');
|
||||
|
||||
$framework = $generator->create_framework([
|
||||
'shortname' => 'How much I care',
|
||||
'description' => 'Sometimes I feel my heart will overflow',
|
||||
'idnumber' => 'FRM101',
|
||||
'scaleid' => $scale->id,
|
||||
]);
|
||||
$competency = $generator->create_competency([
|
||||
'competencyframeworkid' => $framework->get('id'),
|
||||
'shortname' => 'My framework',
|
||||
'idnumber' => 'COM101',
|
||||
]);
|
||||
$generator->create_user_competency([
|
||||
'competencyid' => $competency->get('id'),
|
||||
'userid' => $user->id,
|
||||
'proficiency' => true,
|
||||
'grade' => 3,
|
||||
]);
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
|
||||
// Create report containing single column, and given filter.
|
||||
$report = $generator->create_report(['name' => 'Competencies', 'source' => competencies::class, 'default' => 0]);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'framework:idnumber']);
|
||||
|
||||
// Add filter, set it's values.
|
||||
$generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]);
|
||||
$content = $this->get_custom_report_content(
|
||||
reportid: $report->get('id'),
|
||||
filtervalues: str_replace('<SCALEID>', $scale->id, $filtervalues),
|
||||
);
|
||||
|
||||
if ($expectmatch) {
|
||||
$this->assertCount(1, $content);
|
||||
$this->assertEquals('FRM101', reset($content[0]));
|
||||
} else {
|
||||
$this->assertEmpty($content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stress test datasource
|
||||
*
|
||||
* In order to execute this test PHPUNIT_LONGTEST should be defined as true in phpunit.xml or directly in config.php
|
||||
*/
|
||||
public function test_stress_datasource(): void {
|
||||
if (!PHPUNIT_LONGTEST) {
|
||||
$this->markTestSkipped('PHPUNIT_LONGTEST is not defined');
|
||||
}
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
/** @var core_competency_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_competency');
|
||||
|
||||
$framework = $generator->create_framework();
|
||||
$competency = $generator->create_competency(['competencyframeworkid' => $framework->get('id')]);
|
||||
$generator->create_user_competency(['competencyid' => $competency->get('id'), 'userid' => $user->id]);
|
||||
|
||||
$this->datasource_stress_test_columns(competencies::class);
|
||||
$this->datasource_stress_test_columns_aggregation(competencies::class);
|
||||
$this->datasource_stress_test_conditions(competencies::class, 'framework:idnumber');
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,8 @@ $string['allchildrenarecomplete'] = 'All children are complete';
|
||||
$string['competencies'] = 'Competencies';
|
||||
$string['competenciesarenotenabled'] = 'Competencies are not enabled.';
|
||||
$string['competenciessettings'] = 'Competencies settings';
|
||||
$string['competency'] = 'Competency';
|
||||
$string['competencyframework'] = 'Competency framework';
|
||||
$string['completeplanstask'] = 'Complete learning plans which are due';
|
||||
$string['coursecompetencyoutcome_complete'] = 'Complete the competency';
|
||||
$string['coursecompetencyoutcome_evidence'] = 'Attach evidence';
|
||||
@@ -162,8 +164,10 @@ $string['privacy:metadata:usermodified'] = 'The user who created or modified the
|
||||
$string['privacy:path:plans'] = 'Learning plans';
|
||||
$string['privacy:path:relatedtome'] = 'Related to me';
|
||||
$string['privacy:path:userevidence'] = 'Evidence of prior learning';
|
||||
$string['proficient'] = 'Proficient';
|
||||
$string['pushcourseratingstouserplans'] = 'Push course ratings to individual learning plans';
|
||||
$string['pushcourseratingstouserplans_desc'] = 'Default value for the course setting to update individual learning plans when course competencies are rated.';
|
||||
$string['rating'] = 'Rating';
|
||||
$string['syncplanscohorts'] = 'Sync plans from learning plan template cohorts';
|
||||
$string['taxonomy_behaviour'] = 'Behaviour';
|
||||
$string['taxonomy_competency'] = 'Competency';
|
||||
@@ -196,6 +200,7 @@ $string['usercommentedonaplanhtml'] = '<p>{$a->fullname} commented on the learni
|
||||
<p>See: <a href="{$a->url}">{$a->urlname}</a>.</p>';
|
||||
$string['usercommentedonaplansmall'] = '{$a->fullname} commented on the learning plan "{$a->plan}".';
|
||||
$string['usercommentedonaplansubject'] = '{$a} commented on a learning plan.';
|
||||
$string['usercompetency'] = 'User competency';
|
||||
$string['usercompetencystatus_idle'] = 'Idle';
|
||||
$string['usercompetencystatus_inreview'] = 'In review';
|
||||
$string['usercompetencystatus_waitingforreview'] = 'Waiting for review';
|
||||
|
||||
Reference in New Issue
Block a user