Improved category listing and link hiding
This commit is contained in:
parent
29f11982ff
commit
8aed72af70
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/page-view-plan.min.js
vendored
2
amd/build/page-view-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){("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)}}}));
|
||||
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 css="";for(const ix in hrefs){const href=hrefs[ix];console.info(`Hiding ${href}`),css+=`\n li > a[href*="${href}"] {\n display: none !important; \n }\n `,css+=`\n #usernavigation a[href*="${href}"] {\n display: none !important;\n }\n `}const element=document.createElement("style");element.setAttribute("type","text/css"),"textContent"in element?element.textContent=css:element.styleSheet.cssText=css,document.head.appendChild(element),console.info(element)}}}));
|
||||
|
||||
//# 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/*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"}
|
||||
{"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 css = '' ;\n for(const ix in hrefs){\n const href = hrefs[ix];\n console.info(`Hiding ${href}`);\n css += `\n li > a[href*=\"${href}\"] {\n display: none !important; \n }\n `;\n css += `\n #usernavigation a[href*=\"${href}\"] {\n display: none !important;\n }\n `;\n }\n\n\n const element = document.createElement('style');\n element.setAttribute('type', 'text/css');\n\n if ('textContent' in element) {\n element.textContent = css;\n } else {\n element.styleSheet.cssText = css;\n }\n\n document.head.appendChild(element);\n\n console.info(element);\n }\n}\n"],"names":["hrefs","String","Array","isArray","css","ix","href","console","info","element","document","createElement","setAttribute","textContent","styleSheet","cssText","head","appendChild"],"mappings":"sKAO6BA,QACL,iBAAVA,OAAsBA,iBAAiBC,UAC7CD,MAAQ,CAACA,WAGO,iBAAVA,OAAsBE,MAAMC,QAAQH,OAAO,KAC7CI,IAAM,OACN,MAAMC,MAAML,MAAM,OACZM,KAAON,MAAMK,IACnBE,QAAQC,KAAM,UAASF,QACvBF,KAAQ,mCACYE,4FAIpBF,KAAQ,8CACuBE,iGAO7BG,QAAUC,SAASC,cAAc,SACvCF,QAAQG,aAAa,OAAQ,YAEzB,gBAAiBH,QACjBA,QAAQI,YAAcT,IAEtBK,QAAQK,WAAWC,QAAUX,IAGjCM,SAASM,KAAKC,YAAYR,SAE1BF,QAAQC,KAAKC"}
|
|
@ -193,7 +193,7 @@ export function init(contextid,categoryid,options) {
|
|||
app.courses = response;
|
||||
}).catch(notification.exception);
|
||||
call([{
|
||||
methodname: 'local_treestudyplan_list_used_categories',
|
||||
methodname: 'local_treestudyplan_list_available_categories',
|
||||
args: { operation: 'edit', refcontext_id: contextid}
|
||||
}])[0].then(function(response){
|
||||
app.usedcontexts = response;
|
||||
|
|
|
@ -100,13 +100,14 @@ export function init(contextid,categoryid) {
|
|||
}
|
||||
}).catch(notification.exception);
|
||||
call([{
|
||||
methodname: 'local_treestudyplan_list_used_categories',
|
||||
methodname: 'local_treestudyplan_list_available_categories',
|
||||
args: { operation: 'view', refcontext_id: contextid}
|
||||
}])[0].then(function(response){
|
||||
const contexts = [];
|
||||
for(const ix in response){
|
||||
if(response[ix].studyplancount >0){
|
||||
contexts.push(response[ix]);
|
||||
const cat = response[ix];
|
||||
if(cat.studyplancount > 0 || cat.context_id == contextid){
|
||||
contexts.push(cat);
|
||||
}
|
||||
}
|
||||
app.usedcontexts = contexts;
|
||||
|
|
|
@ -11,26 +11,34 @@ export function hide_primary(hrefs) {
|
|||
}
|
||||
|
||||
if(typeof hrefs === 'object' && Array.isArray(hrefs)){
|
||||
let element = document.createElement('style');
|
||||
document.head.appendChild(element);
|
||||
let sheet = element.sheet;
|
||||
let css = '' ;
|
||||
for(const ix in hrefs){
|
||||
const href = hrefs[ix];
|
||||
console.info(`Hiding ${href}`);
|
||||
let style = `
|
||||
css += `
|
||||
li > a[href*="${href}"] {
|
||||
display: none;
|
||||
display: none !important;
|
||||
}
|
||||
`;
|
||||
sheet.insertRule(style, sheet.cssRules.length);
|
||||
style = `
|
||||
css += `
|
||||
#usernavigation a[href*="${href}"] {
|
||||
display: none;
|
||||
display: none !important;
|
||||
}
|
||||
`;
|
||||
sheet.insertRule(style, sheet.cssRules.length);
|
||||
}
|
||||
|
||||
|
||||
const element = document.createElement('style');
|
||||
element.setAttribute('type', 'text/css');
|
||||
|
||||
if ('textContent' in element) {
|
||||
element.textContent = css;
|
||||
} else {
|
||||
element.styleSheet.cssText = css;
|
||||
}
|
||||
|
||||
document.head.appendChild(element);
|
||||
|
||||
console.info(element);
|
||||
console.info(sheet);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,8 +54,11 @@ class courseservice extends \external_api {
|
|||
* @param int $userid Id of the user
|
||||
* @return array of core_course_category
|
||||
*/
|
||||
public static function user_tops($userid) {
|
||||
global $DB;
|
||||
public static function user_tops($userid=null,$capability='moodle/category:viewcourselist') {
|
||||
global $DB, $USER;
|
||||
if ($userid == null) {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
$tops = [];
|
||||
|
||||
/*
|
||||
|
@ -300,35 +303,22 @@ class courseservice extends \external_api {
|
|||
}
|
||||
|
||||
/**
|
||||
* [Description for categories_by_capability]
|
||||
* List all user visible categories the current user has a given capability for.
|
||||
* @param mixed $capability
|
||||
* @param core_course_category|null $parent
|
||||
* @return array
|
||||
*/
|
||||
public static function categories_by_capability($capability, core_course_category $parent = null) {
|
||||
public static function categories_by_capability($capability) {
|
||||
global $USER;
|
||||
// List the categories in which the user has a specific capability.
|
||||
$list = [];
|
||||
// Initialize parent if needed.
|
||||
if ($parent == null) {
|
||||
$parent = \core_course_category::user_top();
|
||||
if (has_capability($capability, $parent->get_context())) {
|
||||
$list[] = $parent;
|
||||
}
|
||||
}
|
||||
$parents = self::user_tops($USER->id,$capability);
|
||||
array_merge($list,$parents);
|
||||
|
||||
$children = $parent->get_children();
|
||||
foreach ($children as $child) {
|
||||
// Check if we should add this category.
|
||||
if (has_capability($capability, $child->get_context())) {
|
||||
$list[] = $child;
|
||||
foreach ($parents as $parent) {
|
||||
// For optimization purposes, we include all its children now, since they will have inherited the permission.
|
||||
// #PREMATURE_OPTIMIZATION ???.
|
||||
$list = array_merge($list, self::recursive_child_categories($child));
|
||||
} else {
|
||||
if ($child->get_children_count() > 0) {
|
||||
$list = array_merge($list, self::categories_by_capability($capability, $child));
|
||||
}
|
||||
}
|
||||
$list = array_merge($list, self::recursive_child_categories($parent));
|
||||
}
|
||||
|
||||
return $list;
|
||||
|
@ -352,9 +342,9 @@ class courseservice extends \external_api {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return value description for list_used_categories function
|
||||
* Return value description for list_available_categories function
|
||||
*/
|
||||
public static function list_used_categories_parameters() : \external_function_parameters {
|
||||
public static function list_available_categories_parameters() : \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"operation" => new \external_value(PARAM_TEXT, 'type of operation ["view"|"edit"]', VALUE_DEFAULT),
|
||||
"refcontext_id" => new \external_value(PARAM_INT, 'id of reference context', VALUE_DEFAULT),
|
||||
|
@ -362,9 +352,9 @@ class courseservice extends \external_api {
|
|||
}
|
||||
|
||||
/**
|
||||
* Parameter description for list_used_categories function
|
||||
* Parameter description for list_available_categories function
|
||||
*/
|
||||
public static function list_used_categories_returns() : \external_description {
|
||||
public static function list_available_categories_returns() : \external_description {
|
||||
return new \external_multiple_structure(static::map_category_structure(true));
|
||||
}
|
||||
|
||||
|
@ -374,43 +364,66 @@ class courseservice extends \external_api {
|
|||
* @param int $refctxid Reference context id
|
||||
* @return array
|
||||
*/
|
||||
public static function list_used_categories($operation = 'edit', $refctxid = 0) {
|
||||
public static function list_available_categories($operation = 'edit', $refctxid = 0) {
|
||||
global $DB;
|
||||
if ($operation == "edit") {
|
||||
$capability = self::CAP_EDIT;
|
||||
} else { // Operation == "view" || default.
|
||||
$capability = self::CAP_VIEW;
|
||||
}
|
||||
$contextcounts = [];
|
||||
|
||||
// Get the context ids of all categories the user has access to view and wich have the given permission.
|
||||
$contextids = [];
|
||||
$tops = self::user_tops(null,$capability);
|
||||
foreach ($tops as $cat) {
|
||||
$ctx = \context_coursecat::instance($cat->id);
|
||||
$contextids[] = $ctx->id;
|
||||
}
|
||||
|
||||
// Now get an overview of the number of study plans in a given context.
|
||||
$contextcounts = [];
|
||||
$insertctxs = [];
|
||||
$rs = $DB->get_recordset_sql("SELECT DISTINCT context_id, COUNT(*) as num FROM {local_treestudyplan}
|
||||
GROUP BY context_id");
|
||||
foreach ($rs as $r) {
|
||||
// Build the counts.
|
||||
$contextcounts[$r->context_id] = $r->num;
|
||||
$contextids[] = $r->context_id;
|
||||
// Add any of the categories containing studyplans to the list.
|
||||
$ctx = \context::instance_by_id($r->context_id);
|
||||
if (has_capability($capability,$ctx) && !in_array($r->context_id,$contextids)) {
|
||||
$insertctxs[] = $ctx;
|
||||
}
|
||||
|
||||
// Add system context to list if needed.
|
||||
if (!in_array(1,$contextids)) {
|
||||
array_unshift($contextids,1);
|
||||
}
|
||||
|
||||
$rs->close();
|
||||
|
||||
$cats = [];
|
||||
// If the reference context id is not in the list, push it there
|
||||
|
||||
// If the reference context id is not in the list, push it there if the user has proper permissions in that context
|
||||
if ($refctxid > 1 && !in_array($refctxid, $contextids)) {
|
||||
try {
|
||||
// Get the context.
|
||||
$refctx = \context::instance_by_id($refctxid);
|
||||
$refpath = $refctx->get_parent_context_ids(true);
|
||||
// Double check permissions.
|
||||
if (has_capability($capability,$refctx)) {
|
||||
$insertctxs[] = $refctx;
|
||||
}
|
||||
} catch(\dml_missing_record_exception $x) {
|
||||
// ignore context
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($insertctxs as $ictx) {
|
||||
// Place this context and all relevant direct parents in the correct spots.
|
||||
$ipath = $ictx->get_parent_context_ids(true);
|
||||
$found = false;
|
||||
foreach ($refpath as $i => $pid) {
|
||||
foreach ($ipath as $i => $pid) {
|
||||
$idx = array_search($pid,$contextids);
|
||||
if($idx !== false) {
|
||||
|
||||
$contextids = array_merge(
|
||||
array_slice($contextids, 0, $idx+1),
|
||||
array_reverse(array_slice($refpath,0,$i)),
|
||||
array_reverse(array_slice($ipath,0,$i)),
|
||||
array_slice($contextids, $idx+1, count($contextids) - 1)
|
||||
) ;
|
||||
|
||||
|
@ -419,25 +432,24 @@ class courseservice extends \external_api {
|
|||
}
|
||||
}
|
||||
if(!$found) {
|
||||
array_unshift($contextids,$refctxid);
|
||||
}
|
||||
} catch(\dml_missing_record_exception $x) {
|
||||
// ignore context
|
||||
array_unshift($contextids,$ictx->id);
|
||||
}
|
||||
}
|
||||
// we only have to check the contexts having a study plan for access permissions
|
||||
|
||||
|
||||
// Now translate this to the list of categories.
|
||||
foreach ($contextids as $ctxid ) {
|
||||
try {
|
||||
$ctx = \context::instance_by_id($ctxid);
|
||||
if (has_capability($capability, $ctx)) {
|
||||
if ($ctx->contextlevel == CONTEXT_SYSTEM) {
|
||||
$cat = \core_course_category::top();
|
||||
} else if ($ctx->contextlevel == CONTEXT_COURSECAT) {
|
||||
$cat = \core_course_category::get($ctx->instanceid,\MUST_EXIST,true);
|
||||
$cat = \core_course_category::get($ctx->instanceid,\MUST_EXIST,false);
|
||||
}
|
||||
$cats[] = $cat;
|
||||
// In edit mode, also include direct children of the currently selected context.
|
||||
if ($operation == "edit" && $ctxid == $refctxid) {
|
||||
// Include direct children for navigation purposes
|
||||
// Include direct children for navigation purposes.
|
||||
foreach ($cat->get_children() as $ccat) {
|
||||
$ccatctx = \context_coursecat::instance($ccat->id);
|
||||
if (!in_array($ccatctx->id,$contextids)) {
|
||||
|
@ -445,12 +457,12 @@ class courseservice extends \external_api {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\dml_missing_record_exception $x) {
|
||||
// ignore context
|
||||
}
|
||||
}
|
||||
|
||||
// And finally build the proper models, including studyplan count in the category context.
|
||||
$list = [];
|
||||
foreach ($cats as $cat) {
|
||||
$count = 0;
|
||||
|
|
|
@ -484,9 +484,9 @@ $functions = [
|
|||
'ajax' => true,
|
||||
'loginrequired' => true,
|
||||
],
|
||||
'local_treestudyplan_list_used_categories' => [ // Web service function name.
|
||||
'local_treestudyplan_list_available_categories' => [ // Web service function name.
|
||||
'classname' => '\local_treestudyplan\courseservice', // Class containing the external function.
|
||||
'methodname' => 'list_used_categories', // External function name.
|
||||
'methodname' => 'list_available_categories', // External function name.
|
||||
'description' => 'Get categories hosting a studyplan',
|
||||
'type' => 'read', // Database rights of the web service function (read, write).
|
||||
'capabilities' => 'local/treestudyplan:editstudyplan',
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494).
|
||||
$plugin->version = 2024020204; // YYYYMMDDHH (year, month, day, iteration).
|
||||
$plugin->version = 2024020400; // YYYYMMDDHH (year, month, day, iteration).
|
||||
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11).
|
||||
|
||||
$plugin->release = "1.1.0";
|
||||
|
|
Loading…
Reference in New Issue
Block a user