Skip to content

Commit

Permalink
MDL-78741 files: context report entity data for path and parent.
Browse files Browse the repository at this point in the history
Allows for better aggregation/grouping of file data by context tree.
  • Loading branch information
paulholden committed Aug 24, 2023
1 parent 5a44292 commit ce1db14
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 13 deletions.
45 changes: 33 additions & 12 deletions files/tests/reportbuilder/datasource/files_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@

namespace core_files\reportbuilder\datasource;

use context_course;
use context_user;
use core\context\{course, coursecat, user};
use core_reportbuilder_generator;
use core_reportbuilder_testcase;
use core_reportbuilder\local\filters\{boolean_select, date, number, select, text};
Expand All @@ -46,10 +45,10 @@ public function test_datasource_default(): void {
$this->resetAfterTest();

$course = $this->getDataGenerator()->create_course();
$coursecontext = context_course::instance($course->id);
$coursecontext = course::instance($course->id);

$user = $this->getDataGenerator()->create_user();
$usercontext = context_user::instance($user->id);
$usercontext = user::instance($user->id);

$this->setUser($user);

Expand Down Expand Up @@ -91,11 +90,14 @@ public function test_datasource_non_default_columns(): void {
$this->resetAfterTest();
$this->setAdminUser();

$course = $this->getDataGenerator()->create_course();
$coursecontext = context_course::instance($course->id);
$category = $this->getDataGenerator()->create_category();
$categorycontext = coursecat::instance($category->id);

$course = $this->getDataGenerator()->create_course(['category' => $category->id]);
$coursecontext = course::instance($course->id);

$user = $this->getDataGenerator()->create_user();
$usercontext = context_user::instance($user->id);
$usercontext = user::instance($user->id);

$this->setUser($user);

Expand All @@ -110,6 +112,9 @@ public function test_datasource_non_default_columns(): void {
'sortenabled' => 1, 'sortorder' => 1]);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'context:name']);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'context:level']);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'context:path']);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'context:parent']);

$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'file:path']);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'file:author']);
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'file:license']);
Expand All @@ -130,6 +135,8 @@ public function test_datasource_non_default_columns(): void {
"<a href=\"{$coursecontext->get_url()}\">{$coursecontext->get_context_name()}</a>",
$coursecontext->get_context_name(),
'Course',
$coursecontext->path,
$categorycontext->get_context_name(),
'/',
null,
'',
Expand All @@ -142,6 +149,8 @@ public function test_datasource_non_default_columns(): void {
"<a href=\"{$coursecontext->get_url()}\">{$coursecontext->get_context_name()}</a>",
$coursecontext->get_context_name(),
'Course',
$coursecontext->path,
$categorycontext->get_context_name(),
'/',
null,
'',
Expand All @@ -154,6 +163,8 @@ public function test_datasource_non_default_columns(): void {
"<a href=\"{$usercontext->get_url()}\">{$usercontext->get_context_name()}</a>",
$usercontext->get_context_name(),
'User',
$usercontext->path,
'System',
'/',
null,
'',
Expand All @@ -166,6 +177,8 @@ public function test_datasource_non_default_columns(): void {
"<a href=\"{$usercontext->get_url()}\">{$usercontext->get_context_name()}</a>",
$usercontext->get_context_name(),
'User',
$usercontext->path,
'System',
'/',
null,
'',
Expand Down Expand Up @@ -233,6 +246,14 @@ public function datasource_filters_provider(): array {
'context:level_operator' => select::EQUAL_TO,
'context:level_value' => CONTEXT_BLOCK,
], 0],
'Context path' => ['context:path', [
'context:path_operator' => text::STARTS_WITH,
'context:path_value' => '/1/',
], 4],
'Context path (no match)' => ['context:path', [
'context:path_operator' => text::STARTS_WITH,
'context:path_value' => '/1/2/3/',
], 0],

// User.
'Filter user' => ['user:username', [
Expand Down Expand Up @@ -267,7 +288,7 @@ public function test_datasource_filters(
$this->setUser($user);

$course = $this->getDataGenerator()->create_course();
$coursecontext = context_course::instance($course->id);
$coursecontext = course::instance($course->id);

$this->generate_test_files($coursecontext);

Expand Down Expand Up @@ -302,7 +323,7 @@ public function test_stress_datasource(): void {
$this->setAdminUser();

$course = $this->getDataGenerator()->create_course();
$coursecontext = context_course::instance($course->id);
$coursecontext = course::instance($course->id);

$this->generate_test_files($coursecontext);

Expand All @@ -326,17 +347,17 @@ protected function filter_custom_report_content(array $content, callable $callba
/**
* Helper method to generate some test files (a user draft and course summary file) for reporting on
*
* @param context_course $context
* @param course $context
* @return int Draft item ID
*/
protected function generate_test_files(context_course $context): int {
protected function generate_test_files(course $context): int {
global $USER;

$draftitemid = file_get_unused_draft_itemid();

// Populate user draft.
get_file_storage()->create_file_from_string([
'contextid' => context_user::instance($USER->id)->id,
'contextid' => user::instance($USER->id)->id,
'userid' => $USER->id,
'component' => 'user',
'filearea' => 'draft',
Expand Down
1 change: 1 addition & 0 deletions lang/en/moodle.php
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@
$string['context'] = 'Context';
$string['contextlevel'] = 'Context level';
$string['contextname'] = 'Context name';
$string['contextparent'] = 'Parent';
$string['contexturl'] = 'Context URL';
$string['continue'] = 'Continue';
$string['continuetocourse'] = 'Click here to enter your course';
Expand Down
57 changes: 56 additions & 1 deletion lib/classes/reportbuilder/local/entities/context.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

use core\context_helper;
use core_reportbuilder\local\entities\base;
use core_reportbuilder\local\filters\select;
use core_reportbuilder\local\filters\{select, text};
use core_reportbuilder\local\report\{column, filter};
use html_writer;
use lang_string;
Expand Down Expand Up @@ -81,6 +81,8 @@ public function initialise(): base {
* @return column[]
*/
protected function get_all_columns(): array {
global $DB;

$contextalias = $this->get_table_alias('context');

// Name.
Expand Down Expand Up @@ -145,6 +147,49 @@ protected function get_all_columns(): array {
return context_helper::get_level_name($level);
});

// Path.
$columns[] = (new column(
'path',
new lang_string('path'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$contextalias}.path")
->set_is_sortable(true);

// Parent (note we select the parent path in SQL, so that aggregation/grouping is on the parent data itself).
$columns[] = (new column(
'parent',
new lang_string('contextparent'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
// The "path" column looks like "/1/2/3", for context ID 3. In order to select/group by the parent context, we
// concatenate a trailing slash (to prevent partial matches, e.g. "/1/2/31"), then replace "/3/" with empty string.
->add_field("
REPLACE(
" . $DB->sql_concat("{$contextalias}.path", "'/'") . ",
" . $DB->sql_concat("'/'", $DB->sql_cast_to_char("{$contextalias}.id"), "'/'") . ",
''
)", 'parent'
)
// Sorting may not order alphabetically, but will at least group contexts together.
->set_is_sortable(true)
->add_callback(static function (?string $parent): string {

// System level (no parent) or null.
if ($parent === '' || $parent === null) {
return '';
}

$contextids = explode('/', $parent);
$contextid = (int) array_pop($contextids);

return context_helper::instance_by_id($contextid)->get_context_name();
});

return $columns;
}

Expand Down Expand Up @@ -173,6 +218,16 @@ protected function get_all_filters(): array {
}, $levels);
});

// Path.
$filters[] = (new filter(
text::class,
'path',
new lang_string('path'),
$this->get_entity_name(),
"{$contextalias}.path"
))
->add_joins($this->get_joins());

return $filters;
}
}

0 comments on commit ce1db14

Please sign in to comment.