Fixed badge search and some other things
This commit is contained in:
parent
9fe71f1800
commit
5a88761f22
17 changed files with 480 additions and 43 deletions
2
amd/build/page-edit-plan.min.js
vendored
2
amd/build/page-edit-plan.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
amd/build/primary-nav-tools.min.js
vendored
2
amd/build/primary-nav-tools.min.js
vendored
|
@ -1,3 +1,3 @@
|
||||||
define("local_treestudyplan/primary-nav-tools",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.hide_primary=function(hrefs){let element=document.createElement("style");document.head.appendChild(element);let sheet=element.sheet;("string"==typeof hrefs||hrefs instanceof String)&&(hrefs=[hrefs]);if("object"==typeof hrefs&&Array.isArray(hrefs))for(const ix in hrefs){const href=hrefs[ix];let style=`\n li > a[href*="${href}"] {\n display: none;\n }\n `;sheet.insertRule(style,sheet.cssRules.length),style=`\n #usernavigation a[href*="${href}"] {\n display: none;\n }\n `,sheet.insertRule(style,sheet.cssRules.length)}}}));
|
define("local_treestudyplan/primary-nav-tools",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.hide_primary=function(hrefs){("string"==typeof hrefs||hrefs instanceof String)&&(hrefs=[hrefs]);if("object"==typeof hrefs&&Array.isArray(hrefs)){let element=document.createElement("style");document.head.appendChild(element);let sheet=element.sheet;for(const ix in hrefs){const href=hrefs[ix];console.info(`Hiding ${href}`);let style=`\n li > a[href*="${href}"] {\n display: none;\n }\n `;sheet.insertRule(style,sheet.cssRules.length),style=`\n #usernavigation a[href*="${href}"] {\n display: none;\n }\n `,sheet.insertRule(style,sheet.cssRules.length)}console.info(element),console.info(sheet)}}}));
|
||||||
|
|
||||||
//# sourceMappingURL=primary-nav-tools.min.js.map
|
//# sourceMappingURL=primary-nav-tools.min.js.map
|
|
@ -1 +1 @@
|
||||||
{"version":3,"file":"primary-nav-tools.min.js","sources":["../src/primary-nav-tools.js"],"sourcesContent":["/*eslint-env es6*/\n\n/**\n * Hide a primary navigation item by href\n * @param {string|Array} hrefs The link that should be hidden\n */\nexport function hide_primary(hrefs) {\n let element = document.createElement('style');\n document.head.appendChild(element);\n let sheet = element.sheet;\n\n if(typeof hrefs === 'string' || hrefs instanceof String){\n hrefs = [hrefs];\n }\n\n if(typeof hrefs === 'object' && Array.isArray(hrefs)){\n for(const ix in hrefs){\n const href = hrefs[ix];\n let style = `\n li > a[href*=\"${href}\"] {\n display: none;\n }\n `;\n sheet.insertRule(style, sheet.cssRules.length);\n style = `\n #usernavigation a[href*=\"${href}\"] {\n display: none;\n }\n `;\n sheet.insertRule(style, sheet.cssRules.length);\n }\n }\n}\n"],"names":["hrefs","element","document","createElement","head","appendChild","sheet","String","Array","isArray","ix","href","style","insertRule","cssRules","length"],"mappings":"sKAM6BA,WACrBC,QAAUC,SAASC,cAAc,SACrCD,SAASE,KAAKC,YAAYJ,aACtBK,MAAQL,QAAQK,OAEA,iBAAVN,OAAsBA,iBAAiBO,UAC7CP,MAAQ,CAACA,WAGO,iBAAVA,OAAsBQ,MAAMC,QAAQT,WACtC,MAAMU,MAAMV,MAAM,OACZW,KAAOX,MAAMU,QACfE,MAAS,mCACOD,gFAIpBL,MAAMO,WAAWD,MAAON,MAAMQ,SAASC,QACvCH,MAAS,8CACsBD,gFAI/BL,MAAMO,WAAWD,MAAON,MAAMQ,SAASC"}
|
{"version":3,"file":"primary-nav-tools.min.js","sources":["../src/primary-nav-tools.js"],"sourcesContent":["/*eslint-env es6*/\n/*eslint no-console: \"off\"*/\n\n/**\n * Hide a primary navigation item by href\n * @param {string|Array} hrefs The link that should be hidden\n */\nexport function hide_primary(hrefs) {\n if(typeof hrefs === 'string' || hrefs instanceof String){\n hrefs = [hrefs];\n }\n\n if(typeof hrefs === 'object' && Array.isArray(hrefs)){\n let element = document.createElement('style');\n document.head.appendChild(element);\n let sheet = element.sheet;\n for(const ix in hrefs){\n const href = hrefs[ix];\n console.info(`Hiding ${href}`);\n let style = `\n li > a[href*=\"${href}\"] {\n display: none;\n }\n `;\n sheet.insertRule(style, sheet.cssRules.length);\n style = `\n #usernavigation a[href*=\"${href}\"] {\n display: none;\n }\n `;\n sheet.insertRule(style, sheet.cssRules.length);\n }\n console.info(element);\n console.info(sheet);\n }\n}\n"],"names":["hrefs","String","Array","isArray","element","document","createElement","head","appendChild","sheet","ix","href","console","info","style","insertRule","cssRules","length"],"mappings":"sKAO6BA,QACL,iBAAVA,OAAsBA,iBAAiBC,UAC7CD,MAAQ,CAACA,WAGO,iBAAVA,OAAsBE,MAAMC,QAAQH,OAAO,KAC7CI,QAAUC,SAASC,cAAc,SACrCD,SAASE,KAAKC,YAAYJ,aACtBK,MAAQL,QAAQK,UAChB,MAAMC,MAAMV,MAAM,OACZW,KAAOX,MAAMU,IACnBE,QAAQC,KAAM,UAASF,YACnBG,MAAS,mCACOH,gFAIpBF,MAAMM,WAAWD,MAAOL,MAAMO,SAASC,QACvCH,MAAS,8CACsBH,gFAI/BF,MAAMM,WAAWD,MAAOL,MAAMO,SAASC,QAE3CL,QAAQC,KAAKT,SACbQ,QAAQC,KAAKJ"}
|
|
@ -182,12 +182,8 @@ export function init(contextid,categoryid,options) {
|
||||||
// load studyplan from hash if applicable
|
// load studyplan from hash if applicable
|
||||||
const hash = location.hash.replace('#','');
|
const hash = location.hash.replace('#','');
|
||||||
if(hash){
|
if(hash){
|
||||||
for(let idx in app.studyplans){
|
const id = hash;
|
||||||
if(app.studyplans[idx].id == hash){
|
app.selectStudyplan(id);
|
||||||
app.selectStudyplan(app.studyplans[idx]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}).catch(notification.exception);
|
}).catch(notification.exception);
|
||||||
call([{
|
call([{
|
||||||
|
@ -242,13 +238,13 @@ export function init(contextid,categoryid,options) {
|
||||||
window.location.href = window.location.pathname + "?" + params.toString();
|
window.location.href = window.location.pathname + "?" + params.toString();
|
||||||
},50);
|
},50);
|
||||||
},
|
},
|
||||||
selectStudyplan(studyplan){
|
selectStudyplan(studyplanid){
|
||||||
// fetch studyplan
|
// fetch studyplan
|
||||||
app.loadingstudyplan = true;
|
app.loadingstudyplan = true;
|
||||||
app.activestudyplan = null;
|
app.activestudyplan = null;
|
||||||
call([{
|
call([{
|
||||||
methodname: 'local_treestudyplan_get_studyplan_map',
|
methodname: 'local_treestudyplan_get_studyplan_map',
|
||||||
args: { id: studyplan.id}
|
args: { id: studyplanid}
|
||||||
}])[0].then(function(response){
|
}])[0].then(function(response){
|
||||||
app.activestudyplan = ProcessStudyplan(response);
|
app.activestudyplan = ProcessStudyplan(response);
|
||||||
debug.info('studyplan processed');
|
debug.info('studyplan processed');
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
/*eslint-env es6*/
|
/*eslint-env es6*/
|
||||||
|
/*eslint no-console: "off"*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hide a primary navigation item by href
|
* Hide a primary navigation item by href
|
||||||
* @param {string|Array} hrefs The link that should be hidden
|
* @param {string|Array} hrefs The link that should be hidden
|
||||||
*/
|
*/
|
||||||
export function hide_primary(hrefs) {
|
export function hide_primary(hrefs) {
|
||||||
let element = document.createElement('style');
|
|
||||||
document.head.appendChild(element);
|
|
||||||
let sheet = element.sheet;
|
|
||||||
|
|
||||||
if(typeof hrefs === 'string' || hrefs instanceof String){
|
if(typeof hrefs === 'string' || hrefs instanceof String){
|
||||||
hrefs = [hrefs];
|
hrefs = [hrefs];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(typeof hrefs === 'object' && Array.isArray(hrefs)){
|
if(typeof hrefs === 'object' && Array.isArray(hrefs)){
|
||||||
|
let element = document.createElement('style');
|
||||||
|
document.head.appendChild(element);
|
||||||
|
let sheet = element.sheet;
|
||||||
for(const ix in hrefs){
|
for(const ix in hrefs){
|
||||||
const href = hrefs[ix];
|
const href = hrefs[ix];
|
||||||
|
console.info(`Hiding ${href}`);
|
||||||
let style = `
|
let style = `
|
||||||
li > a[href*="${href}"] {
|
li > a[href*="${href}"] {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -29,5 +30,7 @@ export function hide_primary(hrefs) {
|
||||||
`;
|
`;
|
||||||
sheet.insertRule(style, sheet.cssRules.length);
|
sheet.insertRule(style, sheet.cssRules.length);
|
||||||
}
|
}
|
||||||
|
console.info(element);
|
||||||
|
console.info(sheet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,14 +107,14 @@ class badgeinfo {
|
||||||
public static function editor_structure($value = VALUE_REQUIRED) : \external_description {
|
public static function editor_structure($value = VALUE_REQUIRED) : \external_description {
|
||||||
return new \external_single_structure([
|
return new \external_single_structure([
|
||||||
"id" => new \external_value(PARAM_INT, 'id of badge'),
|
"id" => new \external_value(PARAM_INT, 'id of badge'),
|
||||||
"infolink" => new \external_value(PARAM_TEXT, 'badge issue information link', VALUE_OPTIONAL),
|
"infolink" => new \external_value(PARAM_RAW, 'badge issue information link', VALUE_OPTIONAL),
|
||||||
"name" => new \external_value(PARAM_TEXT, 'badge name'),
|
"name" => new \external_value(PARAM_RAW, 'badge name'),
|
||||||
"status" => new \external_value(PARAM_TEXT, 'badge status'),
|
"status" => new \external_value(PARAM_TEXT, 'badge status'),
|
||||||
"locked" => new \external_value(PARAM_TEXT, 'badge lock status'),
|
"locked" => new \external_value(PARAM_TEXT, 'badge lock status'),
|
||||||
"criteria" => new \external_multiple_structure(
|
"criteria" => new \external_multiple_structure(
|
||||||
new \external_value(PARAM_RAW, 'criteria text'), 'badge criteria', VALUE_OPTIONAL),
|
new \external_value(PARAM_RAW, 'criteria text'), 'badge criteria', VALUE_OPTIONAL),
|
||||||
"description" => new \external_value(PARAM_TEXT, 'badge description'),
|
"description" => new \external_value(PARAM_RAW, 'badge description'),
|
||||||
"imageurl" => new \external_value(PARAM_TEXT, 'url of badge image'),
|
"imageurl" => new \external_value(PARAM_RAW, 'url of badge image'),
|
||||||
"studentcount" => new \external_value(PARAM_INT,
|
"studentcount" => new \external_value(PARAM_INT,
|
||||||
'number of studyplan students that can get this badge', VALUE_OPTIONAL),
|
'number of studyplan students that can get this badge', VALUE_OPTIONAL),
|
||||||
"issuedcount" => new \external_value(PARAM_INT,
|
"issuedcount" => new \external_value(PARAM_INT,
|
||||||
|
@ -823,17 +823,16 @@ class badgeinfo {
|
||||||
[$insql, $inparams] = $DB->get_in_or_equal([BADGE_STATUS_ACTIVE, BADGE_STATUS_ACTIVE_LOCKED]);
|
[$insql, $inparams] = $DB->get_in_or_equal([BADGE_STATUS_ACTIVE, BADGE_STATUS_ACTIVE_LOCKED]);
|
||||||
$conditions .= " AND b.status $insql";
|
$conditions .= " AND b.status $insql";
|
||||||
$basesqlparams = array_merge($basesqlparams,$inparams);
|
$basesqlparams = array_merge($basesqlparams,$inparams);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all course badges for this course
|
// Get all course badges for this course
|
||||||
$coursebadges = [];
|
$badgesids = [];
|
||||||
$sql = "SELECT DISTINCT b.id from {badge} b
|
$sql = "SELECT DISTINCT b.id from {badge} b
|
||||||
WHERE b.courseid = :courseid AND $conditions";
|
WHERE b.courseid = :courseid AND $conditions";
|
||||||
|
|
||||||
$coursebadgesids = $DB->get_fieldset_sql($sql,$basesqlparams);
|
$badgesids = $DB->get_fieldset_sql($sql,$basesqlparams);
|
||||||
|
|
||||||
return $coursebadgesids;
|
return $badgesids;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -879,4 +878,46 @@ class badgeinfo {
|
||||||
return $badges;
|
return $badges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search site badges
|
||||||
|
* @param string $search An optional search string to filter by
|
||||||
|
* @param bool $active Only list active badges
|
||||||
|
* @return array of badge
|
||||||
|
*/
|
||||||
|
public static function search_site_badges($search='', $active=false) {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
$search = trim($search);
|
||||||
|
$conditions = "TRUE";
|
||||||
|
$basesqlparams = ['type' => \BADGE_TYPE_SITE];
|
||||||
|
|
||||||
|
if (strlen($search) > 0) {
|
||||||
|
$conditions .= " AND ".$DB->sql_like('b.name',':search');
|
||||||
|
$basesqlparams["search"] = "%$search%";
|
||||||
|
}
|
||||||
|
if ($active) {
|
||||||
|
[$insql, $inparams] = $DB->get_in_or_equal([BADGE_STATUS_ACTIVE, BADGE_STATUS_ACTIVE_LOCKED]);
|
||||||
|
$conditions .= " AND b.status $insql";
|
||||||
|
$basesqlparams = array_merge($basesqlparams,$inparams);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all course badges for this course
|
||||||
|
$sql = "SELECT DISTINCT b.id from {badge} b
|
||||||
|
WHERE $conditions";
|
||||||
|
|
||||||
|
$badgeids = $DB->get_fieldset_sql($sql,$basesqlparams);
|
||||||
|
|
||||||
|
$badges = [];
|
||||||
|
foreach (array_unique($badgeids) as $id) {
|
||||||
|
$badges[] = new self(new badge($id));
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($badges,function($a,$b) {
|
||||||
|
return $a->name() <=> $b->name();
|
||||||
|
});
|
||||||
|
|
||||||
|
return $badges;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
174
classes/local/randomimage.php
Normal file
174
classes/local/randomimage.php
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
* Generate random grades and feedback to initialize development environment
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers - Chris Zuber
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace local_treestudyplan\local;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
/**
|
||||||
|
* Generate random grades and feedback to initialize development environment
|
||||||
|
*/
|
||||||
|
class randomimage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Image width
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $width;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Image height
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $height ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of shapes to draw
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $shapes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Image name
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Image temporary file
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $tempfile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Various available styles for arcs
|
||||||
|
* @var Arary
|
||||||
|
*/
|
||||||
|
const ARC_STYLES = [
|
||||||
|
IMG_ARC_PIE,
|
||||||
|
IMG_ARC_CHORD,
|
||||||
|
IMG_ARC_EDGED,
|
||||||
|
IMG_ARC_NOFILL
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a random polygon with number of points between 0 & $max_pts
|
||||||
|
* @param \GdImage $im The image reource
|
||||||
|
* @param integer $max_pts Max number of point to use
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function random_polygon($im, Int $max_pts = 20)
|
||||||
|
{
|
||||||
|
$color = imagecolorallocatealpha($im, ...$this->random_color_alpha());
|
||||||
|
$pts = $this->random_pts(\random_int(3, $max_pts));
|
||||||
|
imagefilledpolygon($im, $pts, $color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a random arc of a random color
|
||||||
|
* @param \GdImage $im The image resource
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function random_arc($im)
|
||||||
|
{
|
||||||
|
$cx = \random_int(0, $this->width);
|
||||||
|
$cy = \random_int(0, $this->height);
|
||||||
|
$w = \random_int(0, $this->width);
|
||||||
|
$h = \random_int(0, $this->height);
|
||||||
|
$s = \random_int(0, 360);
|
||||||
|
$e = \random_int(0, 360);
|
||||||
|
$col = imagecolorallocatealpha($im, ...$this->random_color_alpha());
|
||||||
|
$style = self::ARC_STYLES[\random_int(0, 3)];
|
||||||
|
imagefilledarc($im, $cx, $cy, $w, $h, $s, $e, $col, $style);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an array of random alpha color values.
|
||||||
|
* @return Array [r, g, b, a]
|
||||||
|
*/
|
||||||
|
private function random_color_alpha(): Array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
\random_int(0, 255),
|
||||||
|
\random_int(0, 255),
|
||||||
|
\random_int(0, 255),
|
||||||
|
\random_int(0, 127)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a set of random points for a polygon [x1,y1, x2,y2,...]
|
||||||
|
* @param integer $length Number of sets of points to generate
|
||||||
|
* @return Array The resulting array of points
|
||||||
|
*/
|
||||||
|
private function random_pts($length): Array
|
||||||
|
{
|
||||||
|
$pts = [];
|
||||||
|
for($n = 0; $n < $length; $n++) {
|
||||||
|
$pts[] = \random_int(0, $this->width);
|
||||||
|
$pts[] = \random_int(0, $this->height);
|
||||||
|
}
|
||||||
|
return $pts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct($shapes=3,$width=256,$height=256) {
|
||||||
|
$this->shapes = $shapes;
|
||||||
|
$this->width = $width;
|
||||||
|
$this->height = $height;
|
||||||
|
|
||||||
|
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
$string = '';
|
||||||
|
|
||||||
|
for ($i = 0; $i < 20; $i++) {
|
||||||
|
$string .= $characters[\mt_rand(0, strlen($characters) - 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->name = $string.".png";
|
||||||
|
|
||||||
|
$im = imagecreatetruecolor($this->width, $this->height);
|
||||||
|
for ($i = 0; $i < $this->shapes; $i++) {
|
||||||
|
switch(\random_int(1, 2)) {
|
||||||
|
case 1:
|
||||||
|
$this->random_arc($im);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$this->random_polygon($im);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->tempfile = \tempnam("/tmp","tsp");
|
||||||
|
imagepng($im,$this->tempfile);
|
||||||
|
imagedestroy($im);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function content() {
|
||||||
|
return $this->content = \file_get_contents($this->tempfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
|
if (isset($this->tempfile) && file_exists($this->tempfile)) {
|
||||||
|
unlink($this->tempfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -875,20 +875,15 @@ class studyplanservice extends \external_api {
|
||||||
*/
|
*/
|
||||||
public static function search_badges($search,$active=false) {
|
public static function search_badges($search,$active=false) {
|
||||||
$systemcontext = webservicehelper::system_context();
|
$systemcontext = webservicehelper::system_context();
|
||||||
$search = trim($search);
|
// Check system permission to
|
||||||
|
webservicehelper::require_capabilities("moodle/badges:viewbadges",$systemcontext);
|
||||||
|
|
||||||
$result = [];
|
$results = [];
|
||||||
$badges = badges_get_badges(BADGE_TYPE_SITE, "timemodified");
|
$badges = badgeinfo::search_site_badges($search,$active);
|
||||||
|
foreach ($badges as $badgeinfo) {
|
||||||
foreach ($badges as $badge) {
|
$results[] = $badgeinfo->editor_model();
|
||||||
if (!$active || $badge->is_active()) {
|
|
||||||
|
|
||||||
if (strlen($search) == 0 || mb_stristr($badge->name,$search) ) {
|
|
||||||
$result[] = (new badgeinfo($badge))->editor_model();
|
|
||||||
}
|
}
|
||||||
}
|
return $results;
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
146
cli/generate_badges.php
Normal file
146
cli/generate_badges.php
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
* Developer CLI tool. Primes grade generator with random student properties
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace local_treestudyplan;
|
||||||
|
|
||||||
|
define('CLI_SCRIPT', true);
|
||||||
|
require(__DIR__ . '/../../../config.php');
|
||||||
|
require_once($CFG->libdir . '/clilib.php');
|
||||||
|
use \core_badges\badge;
|
||||||
|
use local_treestudyplan\local\randomimage;
|
||||||
|
require_once($CFG->libdir.'/badgeslib.php');
|
||||||
|
|
||||||
|
$usage = "Generate a number of random badges
|
||||||
|
Usage:
|
||||||
|
# php generate_badges.php [--amount|-a=<amount>]
|
||||||
|
# php generate_badges.php --help|-h
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h --help Print this help.
|
||||||
|
-a --amount=<amount> The amount of badges to generate.
|
||||||
|
";
|
||||||
|
|
||||||
|
list($options, $unrecognised) = cli_get_params([
|
||||||
|
'help' => false,
|
||||||
|
'amount' => null
|
||||||
|
], [
|
||||||
|
'h' => 'help',
|
||||||
|
'a' => 'amount',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($unrecognised) {
|
||||||
|
$unrecognised = implode(PHP_EOL . ' ', $unrecognised);
|
||||||
|
cli_error(get_string('cliunknowoption', 'core_admin', $unrecognised));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($options['help']) {
|
||||||
|
cli_writeln($usage);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
print_r($options);
|
||||||
|
if (empty($options['amount']) || !is_numeric($options['amount'])) {
|
||||||
|
cli_error('Missing mandatory integer argument "amount"', 2);
|
||||||
|
}
|
||||||
|
$amount = intval($options['amount']);
|
||||||
|
cli_writeln("Creating {$amount} new badges");
|
||||||
|
|
||||||
|
$fortunepath = "/usr/games/fortune";
|
||||||
|
if (!is_executable($fortunepath)) {
|
||||||
|
// Get a fortune if it is available.
|
||||||
|
cli_error('/usr/bin/fortune not found, which is needed for this script. Please install fortune',2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get administrator role and log in as.
|
||||||
|
$user = get_admin();
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
cli_error("Unable to find admin user in DB.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$auth = empty($user->auth) ? 'manual' : $user->auth;
|
||||||
|
if ($auth == 'nologin' || !is_enabled_auth($auth)) {
|
||||||
|
cli_error(sprintf("User authentication is either 'nologin' or disabled. Check Moodle authentication method for '%s'",
|
||||||
|
$user->username));
|
||||||
|
}
|
||||||
|
|
||||||
|
$authplugin = get_auth_plugin($auth);
|
||||||
|
$authplugin->sync_roles($user);
|
||||||
|
login_attempt_valid($user);
|
||||||
|
complete_user_login($user);
|
||||||
|
|
||||||
|
|
||||||
|
for ($i=0; $i<$amount; $i++) {
|
||||||
|
$fortune = shell_exec("{$fortunepath} -n 160 ");
|
||||||
|
$pieces = explode(" ", $fortune);
|
||||||
|
$name = implode(" ", array_splice($pieces, 0, 4));
|
||||||
|
|
||||||
|
$fordb = new \stdClass();
|
||||||
|
$fordb->id = null;
|
||||||
|
|
||||||
|
$now = time();
|
||||||
|
|
||||||
|
$randomicon = new randomimage(10,256,256);
|
||||||
|
|
||||||
|
|
||||||
|
$fordb->name = $name;
|
||||||
|
$fordb->version = 1;
|
||||||
|
$fordb->language = "en";
|
||||||
|
$fordb->description = $fortune;
|
||||||
|
$fordb->imageauthorname = "Generator";
|
||||||
|
$fordb->imageauthoremail = "generator@null.null";
|
||||||
|
$fordb->imageauthorurl = "";
|
||||||
|
$fordb->imagecaption = $name;
|
||||||
|
$fordb->timecreated = $now;
|
||||||
|
$fordb->timemodified = $now;
|
||||||
|
$fordb->usercreated = $USER->id;
|
||||||
|
$fordb->usermodified = $USER->id;
|
||||||
|
|
||||||
|
$url = parse_url($CFG->wwwroot);
|
||||||
|
$fordb->issuerurl = $url['scheme'] . '://' . $url['host'];
|
||||||
|
$fordb->issuername = $CFG->badges_defaultissuername;
|
||||||
|
$fordb->issuercontact = $CFG->badges_defaultissuercontact;
|
||||||
|
|
||||||
|
$fordb->expiredate = null;
|
||||||
|
$fordb->expireperiod = null;
|
||||||
|
$fordb->type = \BADGE_TYPE_SITE; // Site badge.
|
||||||
|
$fordb->courseid = null;
|
||||||
|
$fordb->messagesubject = get_string('messagesubject', 'badges');
|
||||||
|
$fordb->message = get_string('messagebody', 'badges',
|
||||||
|
\html_writer::link($CFG->wwwroot . '/badges/mybadges.php', get_string('managebadges', 'badges')));
|
||||||
|
$fordb->attachment = 1;
|
||||||
|
$fordb->notification = \BADGE_MESSAGE_NEVER;
|
||||||
|
|
||||||
|
$fordb->status = \BADGE_STATUS_INACTIVE;
|
||||||
|
|
||||||
|
$newid = $DB->insert_record('badge', $fordb, true);
|
||||||
|
|
||||||
|
// Trigger event, badge created.
|
||||||
|
$eventparams = array('objectid' => $newid, 'context' => $PAGE->context);
|
||||||
|
$event = \core\event\badge_created::create($eventparams);
|
||||||
|
$event->trigger();
|
||||||
|
|
||||||
|
$newbadge = new badge($newid);
|
||||||
|
badges_process_badge_image($newbadge, $randomicon->tempfile);
|
||||||
|
cli_writeln("Created new badge '{$name}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -665,6 +665,7 @@
|
||||||
top: -5px;
|
top: -5px;
|
||||||
right: -5px;
|
right: -5px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
.path-local-treestudyplan a.t-item-course-config,
|
.path-local-treestudyplan a.t-item-course-config,
|
||||||
.features-treestudyplan a.t-item-course-config {
|
.features-treestudyplan a.t-item-course-config {
|
||||||
|
@ -1537,3 +1538,16 @@
|
||||||
.features-treestudyplan .b-modal-justify-footer-between .modal-footer {
|
.features-treestudyplan .b-modal-justify-footer-between .modal-footer {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
.path-local-treestudyplan .collapse.show,
|
||||||
|
.features-treestudyplan .collapse.show {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.path-local-treestudyplan.bootstrap-polyfill,
|
||||||
|
.features-treestudyplan.bootstrap-polyfill {
|
||||||
|
/* Contains a number of CSS tweaks only needed if the current theme is nog based on boost with bootstrap */
|
||||||
|
}
|
||||||
|
body.path-local-treestudyplan.bootstrap-polyfill .collapse.show,
|
||||||
|
.features-treestudyplan.bootstrap-polyfill .collapse.show {
|
||||||
|
height: auto;
|
||||||
|
}
|
|
@ -106,7 +106,7 @@ print $OUTPUT->header();
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-cloak>
|
<div v-cloak>
|
||||||
<div v-if='!activestudyplan && usedcontexts' class='ml-3 mb-3 s-context-selector'>
|
<div v-if='!activestudyplan && usedcontexts && !loadingstudyplan' class='ml-3 mb-3 s-context-selector'>
|
||||||
<b-form-select text='<?php print($contextname);?>' :value="contextid" @change='switchContext'
|
<b-form-select text='<?php print($contextname);?>' :value="contextid" @change='switchContext'
|
||||||
:class="(!(usedcontexts.length))?'text-primary':''">
|
:class="(!(usedcontexts.length))?'text-primary':''">
|
||||||
<b-form-select-option v-if='!(usedcontexts.length)' :value="contextid"
|
<b-form-select-option v-if='!(usedcontexts.length)' :value="contextid"
|
||||||
|
@ -127,12 +127,12 @@ print $OUTPUT->header();
|
||||||
<a href='#' v-if='activestudyplan' @click.prevent='closeStudyplan'
|
<a href='#' v-if='activestudyplan' @click.prevent='closeStudyplan'
|
||||||
><i style='font-size: 150%;' class='fa fa-chevron-left'></i> <?php t('back');?></a>
|
><i style='font-size: 150%;' class='fa fa-chevron-left'></i> <?php t('back');?></a>
|
||||||
<span v-if='activestudyplan'><?php t("studyplan_select"); ?></span>
|
<span v-if='activestudyplan'><?php t("studyplan_select"); ?></span>
|
||||||
<b-form-select v-if='activestudyplan' lazy :text='dropdown_title' v-model='activestudyplan.id'>
|
<b-form-select v-if='activestudyplan' lazy :text='dropdown_title' :value='activestudyplan.id' @change="selectStudyplan">
|
||||||
<b-form-select-option
|
<b-form-select-option
|
||||||
v-for='(studyplan, planindex) in studyplans'
|
v-for='(studyplan, planindex) in studyplans'
|
||||||
:value="studyplan.id"
|
:value="studyplan.id"
|
||||||
:key='studyplan.id'
|
:key='studyplan.id'
|
||||||
@click='selectStudyplan(studyplan)'>{{ studyplan.name }}</b-form-select-option>
|
>{{ studyplan.name }}</b-form-select-option>
|
||||||
</b-form-select>
|
</b-form-select>
|
||||||
<t-studyplan-edit
|
<t-studyplan-edit
|
||||||
@created="onStudyPlanCreated"
|
@created="onStudyPlanCreated"
|
||||||
|
@ -169,7 +169,7 @@ print $OUTPUT->header();
|
||||||
:key='studyplan.id'
|
:key='studyplan.id'
|
||||||
v-model='studyplans[planindex]'
|
v-model='studyplans[planindex]'
|
||||||
open
|
open
|
||||||
@open='selectStudyplan(studyplan)'
|
@open='selectStudyplan(studyplan.id)'
|
||||||
>
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
<span class='s-studyplan-card-title-buttons'>
|
<span class='s-studyplan-card-title-buttons'>
|
||||||
|
|
43
lib.php
43
lib.php
|
@ -511,6 +511,49 @@ function local_treestudyplan_pluginfile(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Things to do on the start of every instance.
|
||||||
|
*
|
||||||
|
* Beware: do not access theme in this function, find another hook!!
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
function local_treestudyplan_after_config() {
|
||||||
|
global $PAGE;
|
||||||
|
|
||||||
|
/* WARNINGS from the documentation about this callback:
|
||||||
|
This callback is very "raw" and so there are a number of edge cases that you should think about and possibly protect against. If this callback throws an exception that means you can very easily brick your moodle site
|
||||||
|
|
||||||
|
- running while in unit tests
|
||||||
|
- during install
|
||||||
|
- during upgrade
|
||||||
|
- generic exceptions of any type
|
||||||
|
|
||||||
|
Also depending on the defines set before config.php is required, you may not have a $USER object, or other apis, eg if ABORT_AFTER_CONFIG or NO_MOODLE_COOKIES is defined. */
|
||||||
|
/*
|
||||||
|
// So, catch all exceptions to avoid page breaking. We should never break the page in this function.
|
||||||
|
try {
|
||||||
|
// Check if $PAGE is available and valid for use.
|
||||||
|
if (!empty($PAGE) && is_object($PAGE) && method_exists($PAGE,"add_body_class")) {
|
||||||
|
// Check to see if the theme is based on classic or boost to see if we need to add a polyfill...
|
||||||
|
$bootstrapbased = false;
|
||||||
|
foreach ($PAGE->theme->parents as $p) {
|
||||||
|
if ($p->name == 'boost' || $p->name == 'classic') {
|
||||||
|
$bootstrapbased = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$bootstrapbased) {
|
||||||
|
//$PAGE->add_body_class("bootstrap-polyfill"); // Enable the polyfill for boost styling.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (\Exception $x) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
12
scss/bootstraptweaking.scss
vendored
12
scss/bootstraptweaking.scss
vendored
|
@ -3,6 +3,16 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.collapse.show {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
body.path-local-treestudyplan.bootstrap-polyfill, .features-treestudyplan.bootstrap-polyfill {
|
||||||
|
/* Contains a number of CSS tweaks only needed if the current theme is nog based on boost with bootstrap */
|
||||||
|
.collapse.show {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -561,6 +561,7 @@
|
||||||
top: -5px;
|
top: -5px;
|
||||||
right: -5px;
|
right: -5px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
14
styles.css
14
styles.css
|
@ -665,6 +665,7 @@
|
||||||
top: -5px;
|
top: -5px;
|
||||||
right: -5px;
|
right: -5px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
.path-local-treestudyplan a.t-item-course-config,
|
.path-local-treestudyplan a.t-item-course-config,
|
||||||
.features-treestudyplan a.t-item-course-config {
|
.features-treestudyplan a.t-item-course-config {
|
||||||
|
@ -1537,3 +1538,16 @@
|
||||||
.features-treestudyplan .b-modal-justify-footer-between .modal-footer {
|
.features-treestudyplan .b-modal-justify-footer-between .modal-footer {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
.path-local-treestudyplan .collapse.show,
|
||||||
|
.features-treestudyplan .collapse.show {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.path-local-treestudyplan.bootstrap-polyfill,
|
||||||
|
.features-treestudyplan.bootstrap-polyfill {
|
||||||
|
/* Contains a number of CSS tweaks only needed if the current theme is nog based on boost with bootstrap */
|
||||||
|
}
|
||||||
|
body.path-local-treestudyplan.bootstrap-polyfill .collapse.show,
|
||||||
|
.features-treestudyplan.bootstrap-polyfill .collapse.show {
|
||||||
|
height: auto;
|
||||||
|
}
|
|
@ -22,7 +22,7 @@
|
||||||
defined('MOODLE_INTERNAL') || die();
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494).
|
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494).
|
||||||
$plugin->version = 2024012800; // YYYYMMDDHH (year, month, day, iteration).
|
$plugin->version = 2024020204; // YYYYMMDDHH (year, month, day, iteration).
|
||||||
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11).
|
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11).
|
||||||
|
|
||||||
$plugin->release = "1.1.0";
|
$plugin->release = "1.1.0";
|
||||||
|
|
Loading…
Reference in a new issue