first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,377 @@
<?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_badges\reportbuilder\local\entities;
use context_course;
use context_helper;
use context_system;
use html_writer;
use lang_string;
use moodle_url;
use stdClass;
use core_reportbuilder\local\entities\base;
use core_reportbuilder\local\filters\{date, select, text};
use core_reportbuilder\local\helpers\database;
use core_reportbuilder\local\report\{column, filter};
defined('MOODLE_INTERNAL') or die;
global $CFG;
require_once("{$CFG->libdir}/badgeslib.php");
/**
* Badge entity
*
* @package core_badges
* @copyright 2022 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class badge extends base {
/**
* Database tables that this entity uses
*
* @return string[]
*/
protected function get_default_tables(): array {
return [
'badge',
'context',
'tag_instance',
'tag',
];
}
/**
* The default title for this entity
*
* @return lang_string
*/
protected function get_default_entity_title(): lang_string {
return new lang_string('badgedetails', 'core_badges');
}
/**
* 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;
$badgealias = $this->get_table_alias('badge');
$contextalias = $this->get_table_alias('context');
// Name.
$columns[] = (new column(
'name',
new lang_string('name'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$badgealias}.name")
->set_is_sortable(true);
// Name with link.
$columns[] = (new column(
'namewithlink',
new lang_string('namewithlink', 'core_badges'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_fields("{$badgealias}.name, {$badgealias}.id")
->set_is_sortable(true)
->add_callback(static function(?string $value, stdClass $row): string {
if (!$row->id) {
return '';
}
$url = new moodle_url('/badges/overview.php', ['id' => $row->id]);
return html_writer::link($url, $row->name);
});
// Description (note, this column contains plaintext so requires no post-processing).
$descriptionfieldsql = "{$badgealias}.description";
if ($DB->get_dbfamily() === 'oracle') {
$descriptionfieldsql = $DB->sql_order_by_text($descriptionfieldsql, 1024);
}
$columns[] = (new column(
'description',
new lang_string('description', 'core_badges'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_LONGTEXT)
->add_field($descriptionfieldsql, 'description');
// Criteria.
$columns[] = (new column(
'criteria',
new lang_string('bcriteria', 'core_badges'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$badgealias}.id")
->set_disabled_aggregation_all()
->add_callback(static function($badgeid): string {
global $PAGE;
if (!$badgeid) {
return '';
}
$badge = new \core_badges\badge($badgeid);
$renderer = $PAGE->get_renderer('core_badges');
return $renderer->print_badge_criteria($badge, 'short');
});
// Image.
$columns[] = (new column(
'image',
new lang_string('badgeimage', 'core_badges'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->add_join("LEFT JOIN {context} {$contextalias}
ON {$contextalias}.contextlevel = " . CONTEXT_COURSE . "
AND {$contextalias}.instanceid = {$badgealias}.courseid")
->set_type(column::TYPE_INTEGER)
->add_fields("{$badgealias}.id, {$badgealias}.type, {$badgealias}.courseid")
->add_field($DB->sql_cast_to_char("{$badgealias}.imagecaption"), 'imagecaption')
->add_fields(context_helper::get_preload_record_columns_sql($contextalias))
->set_disabled_aggregation_all()
->add_callback(static function(?int $badgeid, stdClass $badge): string {
if (!$badgeid) {
return '';
}
if ($badge->type == BADGE_TYPE_SITE) {
$context = context_system::instance();
} else {
context_helper::preload_from_record($badge);
$context = context_course::instance($badge->courseid);
}
$badgeimage = moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $badgeid, '/', 'f2');
return html_writer::img($badgeimage, $badge->imagecaption);
});
// Language.
$columns[] = (new column(
'language',
new lang_string('language'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$badgealias}.language")
->set_is_sortable(true)
->add_callback(static function($language): string {
$languages = get_string_manager()->get_list_of_languages();
return $languages[$language] ?? $language ?? '';
});
// Version.
$columns[] = (new column(
'version',
new lang_string('version', 'core_badges'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$badgealias}.version")
->set_is_sortable(true);
// Status.
$columns[] = (new column(
'status',
new lang_string('status', 'core_badges'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$badgealias}.status")
->set_is_sortable(true)
->add_callback(static function($status): string {
if ($status === null) {
return '';
}
return get_string("badgestatus_{$status}", 'core_badges');
});
// Expiry date/period.
$columns[] = (new column(
'expiry',
new lang_string('expirydate', 'core_badges'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TIMESTAMP)
->add_fields("{$badgealias}.expiredate, {$badgealias}.expireperiod, {$badgealias}.id")
->set_is_sortable(true, ["{$badgealias}.expiredate", "{$badgealias}.expireperiod"])
->set_disabled_aggregation_all()
->add_callback(static function(?int $expiredate, stdClass $badge): string {
if (!$badge->id) {
return '';
} else if ($expiredate) {
return userdate($expiredate);
} else if ($badge->expireperiod) {
return format_time($badge->expireperiod);
} else {
return get_string('never', 'core_badges');
}
});
// Image author details.
foreach (['imageauthorname', 'imageauthoremail', 'imageauthorurl'] as $imageauthorfield) {
$columns[] = (new column(
$imageauthorfield,
new lang_string($imageauthorfield, 'core_badges'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$badgealias}.{$imageauthorfield}")
->set_is_sortable(true);
}
return $columns;
}
/**
* Return list of all available filters
*
* @return filter[]
*/
protected function get_all_filters(): array {
global $DB;
$badgealias = $this->get_table_alias('badge');
// Name.
$filters[] = (new filter(
text::class,
'name',
new lang_string('name'),
$this->get_entity_name(),
"{$badgealias}.name"
))
->add_joins($this->get_joins());
// Version.
$filters[] = (new filter(
text::class,
'version',
new lang_string('version', 'core_badges'),
$this->get_entity_name(),
"{$badgealias}.version"
))
->add_joins($this->get_joins());
// Status.
$filters[] = (new filter(
select::class,
'status',
new lang_string('status', 'core_badges'),
$this->get_entity_name(),
"{$badgealias}.status"
))
->add_joins($this->get_joins())
->set_options([
BADGE_STATUS_INACTIVE => new lang_string('badgestatus_0', 'core_badges'),
BADGE_STATUS_ACTIVE => new lang_string('badgestatus_1', 'core_badges'),
BADGE_STATUS_INACTIVE_LOCKED => new lang_string('badgestatus_2', 'core_badges'),
BADGE_STATUS_ACTIVE_LOCKED => new lang_string('badgestatus_3', 'core_badges'),
BADGE_STATUS_ARCHIVED => new lang_string('badgestatus_4', 'core_badges'),
]);
// Expiry date/period.
[$parammaxint, $paramtime] = database::generate_param_names(2);
$filters[] = (new filter(
date::class,
'expiry',
new lang_string('expirydate', 'core_badges'),
$this->get_entity_name(),
"CASE WHEN {$badgealias}.expiredate IS NULL AND {$badgealias}.expireperiod IS NULL
THEN " . $DB->sql_cast_char2int(":{$parammaxint}") . "
ELSE COALESCE({$badgealias}.expiredate, {$badgealias}.expireperiod + :{$paramtime})
END",
[$parammaxint => 2147483647, $paramtime => time()]
))
->add_joins($this->get_joins())
->set_limited_operators([
date::DATE_ANY,
date::DATE_RANGE,
date::DATE_LAST,
date::DATE_CURRENT,
date::DATE_NEXT,
date::DATE_PAST,
date::DATE_FUTURE,
]);
// Type.
$filters[] = (new filter(
select::class,
'type',
new lang_string('type', 'core_badges'),
$this->get_entity_name(),
"{$badgealias}.type"
))
->add_joins($this->get_joins())
->set_options([
BADGE_TYPE_SITE => new lang_string('site'),
BADGE_TYPE_COURSE => new lang_string('course'),
]);
return $filters;
}
/**
* Return joins necessary for retrieving tags
*
* @return string[]
*/
public function get_tag_joins(): array {
return $this->get_tag_joins_for_entity('core_badges', 'badge', $this->get_table_alias('badge') . '.id');
}
}
@@ -0,0 +1,164 @@
<?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_badges\reportbuilder\local\entities;
use lang_string;
use core_reportbuilder\local\entities\base;
use core_reportbuilder\local\filters\{boolean_select, date};
use core_reportbuilder\local\helpers\format;
use core_reportbuilder\local\report\{column, filter};
/**
* Badge issued entity
*
* @package core_badges
* @copyright 2022 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class badge_issued extends base {
/**
* Database tables that this entity uses
*
* @return string[]
*/
protected function get_default_tables(): array {
return [
'badge_issued',
];
}
/**
* The default title for this entity
*
* @return lang_string
*/
protected function get_default_entity_title(): lang_string {
return new lang_string('badgeissued', 'core_badges');
}
/**
* 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 {
$badgeissuedalias = $this->get_table_alias('badge_issued');
// Date issued.
$columns[] = (new column(
'issued',
new lang_string('dateawarded', 'core_badges'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TIMESTAMP)
->add_field("{$badgeissuedalias}.dateissued")
->set_is_sortable(true)
->add_callback([format::class, 'userdate']);
// Date expires.
$columns[] = (new column(
'expire',
new lang_string('expirydate', 'core_badges'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TIMESTAMP)
->add_field("{$badgeissuedalias}.dateexpire")
->set_is_sortable(true)
->add_callback([format::class, 'userdate']);
// Visible.
$columns[] = (new column(
'visible',
new lang_string('visible', 'core_badges'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_BOOLEAN)
->add_fields("{$badgeissuedalias}.visible")
->add_callback([format::class, 'boolean_as_text']);
return $columns;
}
/**
* Return list of all available filters
*
* @return filter[]
*/
protected function get_all_filters(): array {
$badgealias = $this->get_table_alias('badge_issued');
// Date issued.
$filters[] = (new filter(
date::class,
'issued',
new lang_string('dateawarded', 'core_badges'),
$this->get_entity_name(),
"{$badgealias}.dateissued"
))
->add_joins($this->get_joins());
// Date expires.
$filters[] = (new filter(
date::class,
'expires',
new lang_string('expirydate', 'core_badges'),
$this->get_entity_name(),
"{$badgealias}.dateexpire"
))
->add_joins($this->get_joins());
// Visible.
$filters[] = (new filter(
boolean_select::class,
'visible',
new lang_string('visible', 'core_badges'),
$this->get_entity_name(),
"{$badgealias}.visible"
))
->add_joins($this->get_joins());
return $filters;
}
}
@@ -0,0 +1,319 @@
<?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_badges\reportbuilder\local\systemreports;
use core\context\{course, system};
use core_badges\reportbuilder\local\entities\badge;
use core_reportbuilder\local\helpers\database;
use core_reportbuilder\local\report\{action, column};
use core_reportbuilder\system_report;
use html_writer;
use lang_string;
use moodle_url;
use pix_icon;
use stdClass;
defined('MOODLE_INTERNAL') || die;
global $CFG;
require_once("{$CFG->libdir}/badgeslib.php");
/**
* Badges system report class implementation
*
* @package core_badges
* @copyright 2023 David Carrillo <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class badges extends system_report {
/** @var int $badgeid The ID of the current badge row */
private int $badgeid;
/**
* Initialise report, we need to set the main table, load our entities and set columns/filters
*/
protected function initialise(): void {
// Our main entity, it contains all of the column definitions that we need.
$badgeentity = new badge();
$entityalias = $badgeentity->get_table_alias('badge');
$this->set_main_table('badge', $entityalias);
$this->add_entity($badgeentity);
$paramtype = database::generate_param_name();
$context = $this->get_context();
if ($context instanceof system) {
$type = BADGE_TYPE_SITE;
$this->add_base_condition_sql("{$entityalias}.type = :$paramtype", [$paramtype => $type]);
} else {
$type = BADGE_TYPE_COURSE;
$paramcourseid = database::generate_param_name();
$this->add_base_condition_sql("{$entityalias}.type = :$paramtype AND {$entityalias}.courseid = :$paramcourseid",
[$paramtype => $type, $paramcourseid => $context->instanceid]);
}
// Any columns required by actions should be defined here to ensure they're always available.
$this->add_base_fields("{$entityalias}.id, {$entityalias}.type, {$entityalias}.courseid, {$entityalias}.status");
// Now we can call our helper methods to add the content we want to include in the report.
$this->add_columns($badgeentity);
$this->add_filters();
$this->add_actions();
$this->set_initial_sort_column('badge:namewithlink', SORT_ASC);
$this->set_default_no_results_notice(new lang_string('nomatchingbadges', 'core_badges'));
// Set if report can be downloaded.
$this->set_downloadable(false);
}
/**
* Validates access to view this report
*
* @return bool
*/
protected function can_view(): bool {
return has_any_capability([
'moodle/badges:viewawarded',
'moodle/badges:createbadge',
'moodle/badges:awardbadge',
'moodle/badges:configurecriteria',
'moodle/badges:configuremessages',
'moodle/badges:configuredetails',
'moodle/badges:deletebadge'], $this->get_context());
}
/**
* Adds the columns we want to display in the report
*
* They are provided by the entities we previously added in the {@see initialise} method, referencing each by their
* unique identifier. If custom columns are needed just for this report, they can be defined here.
*
* @param badge $badgeentity
*/
public function add_columns(badge $badgeentity): void {
$columns = [
'badge:image',
'badge:namewithlink',
'badge:version',
'badge:status',
'badge:criteria',
];
$this->add_columns_from_entities($columns);
// Issued badges column.
$tempbadgealias = database::generate_alias();
$badgeentityalias = $badgeentity->get_table_alias('badge');
$this->add_column((new column(
'issued',
new lang_string('awards', 'core_badges'),
$badgeentity->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_INTEGER)
->add_field("(SELECT COUNT({$tempbadgealias}.userid)
FROM {badge_issued} {$tempbadgealias}
INNER JOIN {user} u
ON {$tempbadgealias}.userid = u.id
WHERE {$tempbadgealias}.badgeid = {$badgeentityalias}.id AND u.deleted = 0)", 'issued')
->set_is_sortable(true)
->set_callback(function(int $count): string {
if (!has_capability('moodle/badges:viewawarded', $this->get_context())) {
return (string) $count;
}
return html_writer::link(new moodle_url('/badges/recipients.php', ['id' => $this->badgeid]), $count);
}));
// Remove title from image column.
$this->get_column('badge:image')->set_title(null);
// Change title from namewithlink column.
$this->get_column('badge:namewithlink')->set_title(new lang_string('name'));
}
/**
* Adds the filters we want to display in the report
*
* They are all provided by the entities we previously added in the {@see initialise} method, referencing each by their
* unique identifier
*/
protected function add_filters(): void {
$this->add_filters_from_entities([
'badge:name',
'badge:version',
'badge:status',
'badge:expiry',
]);
}
/**
* Add the system report actions. An extra column will be appended to each row, containing all actions added here
*
* Note the use of ":id" placeholder which will be substituted according to actual values in the row
*/
protected function add_actions(): void {
// Activate badge.
$this->add_action((new action(
new moodle_url('/badges/action.php', [
'id' => ':id',
'activate' => true,
'return' => ':return',
]),
new pix_icon('t/show', '', 'core'),
[],
false,
new lang_string('activate', 'badges')
))->add_callback(static function(stdclass $row): bool {
$badge = new \core_badges\badge($row->id);
// Populate the return URL.
$row->return = (new moodle_url('/badges/index.php',
['type' => $badge->type, 'id' => (int) $badge->courseid]))->out_as_local_url(false);
return has_capability('moodle/badges:configuredetails', $badge->get_context()) &&
$badge->has_criteria() &&
($row->status == BADGE_STATUS_INACTIVE || $row->status == BADGE_STATUS_INACTIVE_LOCKED);
}));
// Deactivate badge.
$this->add_action((new action(
new moodle_url('/badges/index.php', [
'lock' => ':id',
'sesskey' => sesskey(),
'type' => ':type',
'id' => ':courseid',
]),
new pix_icon('t/hide', '', 'core'),
[],
false,
new lang_string('deactivate', 'badges')
))->add_callback(static function(stdclass $row): bool {
$badge = new \core_badges\badge($row->id);
return has_capability('moodle/badges:configuredetails', $badge->get_context()) &&
$badge->has_criteria() &&
$row->status != BADGE_STATUS_INACTIVE && $row->status != BADGE_STATUS_INACTIVE_LOCKED;
}));
// Award badge manually.
$this->add_action((new action(
new moodle_url('/badges/award.php', [
'id' => ':id',
]),
new pix_icon('t/award', '', 'core'),
[],
false,
new lang_string('award', 'badges')
))->add_callback(static function(stdclass $row): bool {
$badge = new \core_badges\badge($row->id);
return has_capability('moodle/badges:awardbadge', $badge->get_context()) &&
$badge->has_manual_award_criteria() &&
$badge->is_active();
}));
// Edit action.
$this->add_action((new action(
new moodle_url('/badges/edit.php', [
'id' => ':id',
'action' => 'badge',
]),
new pix_icon('t/edit', '', 'core'),
[],
false,
new lang_string('edit', 'core')
))->add_callback(static function(stdclass $row): bool {
$context = self::get_badge_context((int)$row->type, (int)$row->courseid);
return has_capability('moodle/badges:configuredetails', $context);
}));
// Duplicate action.
$this->add_action((new action(
new moodle_url('/badges/action.php', [
'id' => ':id',
'copy' => 1,
'sesskey' => sesskey(),
]),
new pix_icon('t/copy', '', 'core'),
[],
false,
new lang_string('copy', 'badges')
))->add_callback(static function(stdclass $row): bool {
$context = self::get_badge_context((int)$row->type, (int)$row->courseid);
return has_capability('moodle/badges:createbadge', $context);
}));
// Delete action.
$this->add_action((new action(
new moodle_url('/badges/index.php', [
'delete' => ':id',
'type' => ':type',
'id' => ':courseid',
]),
new pix_icon('t/delete', '', 'core'),
['class' => 'text-danger'],
false,
new lang_string('delete', 'core')
))->add_callback(static function(stdclass $row): bool {
$context = self::get_badge_context((int)$row->type, (int)$row->courseid);
return has_capability('moodle/badges:deletebadge', $context);
}));
}
/**
* Return badge context based on type and courseid
*
* @param int $type
* @param int $courseid
* @return \core\context
* @throws \coding_exception
*/
private static function get_badge_context(int $type, int $courseid): \core\context {
switch ($type) {
case BADGE_TYPE_SITE:
return system::instance();
case BADGE_TYPE_COURSE:
return course::instance($courseid);
default:
throw new \coding_exception('Wrong context');
}
}
/**
* Store the ID of the badge within each row
*
* @param stdClass $row
*/
public function row_callback(stdClass $row): void {
$this->badgeid = (int) $row->id;
}
/**
* CSS classes to add to the row
*
* @param stdClass $row
* @return string
*/
public function get_row_class(stdClass $row): string {
return ($row->status == BADGE_STATUS_INACTIVE_LOCKED || $row->status == BADGE_STATUS_INACTIVE) ? 'text-muted' : '';
}
}
@@ -0,0 +1,138 @@
<?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_badges\reportbuilder\local\systemreports;
use core_badges\reportbuilder\local\entities\badge;
use core_badges\reportbuilder\local\entities\badge_issued;
use core_reportbuilder\system_report;
use lang_string;
use moodle_url;
use pix_icon;
use stdClass;
defined('MOODLE_INTERNAL') || die;
global $CFG;
require_once("{$CFG->libdir}/badgeslib.php");
/**
* Course badges system report class implementation
*
* @package core_badges
* @copyright 2023 David Carrillo <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_badges extends system_report {
/**
* Initialise report, we need to set the main table, load our entities and set columns/filters
*/
protected function initialise(): void {
global $USER;
// Our main entity, it contains all of the column definitions that we need.
$badgeentity = new badge();
$entityalias = $badgeentity->get_table_alias('badge');
$this->set_main_table('badge', $entityalias);
$this->add_entity($badgeentity);
$type = $this->get_parameter('type', 0, PARAM_INT);
$courseid = $this->get_parameter('courseid', 0, PARAM_INT);
$this->add_base_condition_simple('type', $type);
$this->add_base_condition_simple('courseid', $courseid);
$this->add_base_condition_sql("({$entityalias}.status = " . BADGE_STATUS_ACTIVE .
" OR {$entityalias}.status = " . BADGE_STATUS_ACTIVE_LOCKED . ")");
$badgeissuedentity = new badge_issued();
$badgeissuedalias = $badgeissuedentity->get_table_alias('badge_issued');
$this->add_entity($badgeissuedentity
->add_join("LEFT JOIN {badge_issued} {$badgeissuedalias}
ON {$entityalias}.id = {$badgeissuedalias}.badgeid AND {$badgeissuedalias}.userid = ".$USER->id)
);
$this->add_base_fields("{$badgeissuedalias}.uniquehash");
// Now we can call our helper methods to add the content we want to include in the report.
$this->add_columns();
$this->add_filters();
$this->set_initial_sort_column('badge:name', SORT_ASC);
$this->set_default_no_results_notice(new lang_string('nomatchingbadges', 'core_badges'));
// Set if report can be downloaded.
$this->set_downloadable(false);
}
/**
* Validates access to view this report
*
* @return bool
*/
protected function can_view(): bool {
return has_capability('moodle/badges:viewbadges', $this->get_context());
}
/**
* Adds the columns we want to display in the report
*
* They are provided by the entities we previously added in the {@see initialise} method, referencing each by their
* unique identifier. If custom columns are needed just for this report, they can be defined here.
*/
protected function add_columns(): void {
$badgeissuedalias = $this->get_entity('badge_issued')->get_table_alias('badge_issued');
$this->add_columns_from_entities([
'badge:image',
'badge:name',
'badge:description',
'badge:criteria',
'badge_issued:issued',
]);
$this->get_column('badge_issued:issued')
->set_title(new lang_string('awardedtoyou', 'core_badges'))
->add_fields("{$badgeissuedalias}.uniquehash")
->set_callback(static function(?int $value, stdClass $row) {
global $OUTPUT;
if (!$value) {
return '';
}
$format = get_string('strftimedatefullshort', 'core_langconfig');
$date = $value ? userdate($value, $format) : '';
$badgeurl = new moodle_url('/badges/badge.php', ['hash' => $row->uniquehash]);
$icon = new pix_icon('i/valid', get_string('dateearned', 'badges', $date));
return $OUTPUT->action_icon($badgeurl, $icon, null, null, true);
});
}
/**
* Adds the filters we want to display in the report
*
* They are all provided by the entities we previously added in the {@see initialise} method, referencing each by their
* unique identifier
*/
protected function add_filters(): void {
$this->add_filters_from_entities([
'badge:name',
'badge_issued:issued',
]);
}
}
@@ -0,0 +1,123 @@
<?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_badges\reportbuilder\local\systemreports;
use core_badges\reportbuilder\local\entities\badge_issued;
use core_reportbuilder\local\report\action;
use core_reportbuilder\system_report;
use lang_string;
use moodle_url;
use pix_icon;
/**
* Badge recipients system report class implementation
*
* @package core_badges
* @copyright 2023 David Carrillo <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class recipients extends system_report {
/**
* Initialise report, we need to set the main table, load our entities and set columns/filters
*/
protected function initialise(): void {
// Our main entity, it contains all of the column definitions that we need.
$badgeissuedentity = new badge_issued();
$entityalias = $badgeissuedentity->get_table_alias('badge_issued');
$this->set_main_table('badge_issued', $entityalias);
$this->add_entity($badgeissuedentity);
$userentity = new \core_reportbuilder\local\entities\user();
$entityuseralias = $userentity->get_table_alias('user');
$this->add_entity($userentity
->add_joins($userentity->get_joins())
->add_join("JOIN {user} {$entityuseralias}
ON {$entityuseralias}.id = {$entityalias}.userid")
);
$this->add_base_condition_simple('badgeid', $this->get_parameter('badgeid', 0, PARAM_INT));
$this->add_base_fields("{$entityalias}.uniquehash");
// Now we can call our helper methods to add the content we want to include in the report.
$this->add_columns();
$this->add_filters();
$this->add_actions();
$this->set_initial_sort_column('badge_issued:issued', SORT_DESC);
$this->set_default_no_results_notice(new lang_string('nomatchingawards', 'core_badges'));
// Set if report can be downloaded.
$this->set_downloadable(false);
}
/**
* Validates access to view this report
*
* @return bool
*/
protected function can_view(): bool {
return has_capability('moodle/badges:viewawarded', $this->get_context());
}
/**
* Adds the columns we want to display in the report
*
* They are provided by the entities we previously added in the {@see initialise} method, referencing each by their
* unique identifier. If custom columns are needed just for this report, they can be defined here.
*/
protected function add_columns(): void {
$this->add_columns_from_entities([
'user:fullnamewithlink',
'badge_issued:issued',
]);
}
/**
* Adds the filters we want to display in the report
*
* They are all provided by the entities we previously added in the {@see initialise} method, referencing each by their
* unique identifier
*/
protected function add_filters(): void {
$this->add_filters_from_entities([
'user:fullname',
'badge_issued:issued',
]);
}
/**
* Add the system report actions. An extra column will be appended to each row, containing all actions added here
*
* Note the use of ":uniquehash" placeholder which will be substituted according to actual values in the row
*/
protected function add_actions(): void {
$this->add_action((new action(
new moodle_url('/badges/badge.php', [
'hash' => ':uniquehash',
]),
new pix_icon('i/search', '', 'core'),
[],
false,
new lang_string('viewbadge', 'badges')
)));
}
}