Skip to content

Commit

Permalink
add cli script to assign a user to a role on a given course category …
Browse files Browse the repository at this point in the history
…(or create a new course cat), code and documentation improvements.
  • Loading branch information
Glutamat42 committed Apr 3, 2024
1 parent b9140bf commit a4cacd5
Show file tree
Hide file tree
Showing 8 changed files with 320 additions and 20 deletions.
19 changes: 17 additions & 2 deletions classes/local/course_category_manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@

namespace local_adler\local;

use coding_exception;
use dml_exception;
use invalid_parameter_exception;
use local_adler\local\db\moodle_core_repository;
use local_adler\moodle_core;
use moodle_exception;

class course_category_manager {
/**
* @param string $username The username of the existing user.
* @param string $role shortname of the role to assign to the user.
* @param string|null $category_path The path of the category. If null or an empty string is passed, it initializes to "adler/{$username}".
* @throws dml_exception
* @throws moodle_exception
* @throws invalid_parameter_exception
*/
public static function create_category_user_can_create_courses_in(string $username, string $role, string|null $category_path = Null) {
$moodle_core_repository = new moodle_core_repository();

Expand Down Expand Up @@ -36,11 +47,15 @@ public static function create_category_user_can_create_courses_in(string $userna
return $category_id;
}

private static function assign_user_to_role_in_category(string $username, string $role, int $category_id) {
/**
* @throws coding_exception
* @throws dml_exception
*/
private static function assign_user_to_role_in_category(string $username, string $role_shortname, int $category_id): void {
$moodle_core_repository = new moodle_core_repository();

$user_id = $moodle_core_repository->get_user_id_by_username($username);
$role_id = $moodle_core_repository->get_role_id_by_shortname($role);
$role_id = $moodle_core_repository->get_role_id_by_shortname($role_shortname);
$context = moodle_core::context_coursecat_instance($category_id);
moodle_core::role_assign($role_id, $user_id, $context->id);
}
Expand Down
38 changes: 22 additions & 16 deletions classes/local/course_category_path.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class course_category_path implements Countable {
private array $path;

/**
* @param string|null $path the path in moodle (with spaces around the /) or UNIX format (without spaces), can be empty string or null
* @param string|null $path the path in moodle (with spaces around the /) or UNIX format (without spaces),
* can be empty string or null to initialize an empty path
*/
public function __construct(string|null $path) {
if ($path === null || strlen($path) === 0) {
Expand All @@ -28,6 +29,9 @@ public function __toString(): string {
return implode(' / ', $this->path);
}

/**
* @return array Returns the path as an array of strings.
*/
public function get_path(): array {
return $this->path;
}
Expand All @@ -36,25 +40,28 @@ public function count(): int {
return count($this->path);
}

/**
* @return bool Returns true if the category path exists in moodle, false otherwise.
*/
public function exists(): bool {
try {
$this->get_category_id();
return true;
} catch (moodle_exception $e) {
if ($this->get_category_id() === false) {
return false;
} else {
return true;
}
}

/**
* @throws moodle_exception if the category already exists
* @return int Returns the ID of the created category (the last category in the path).
* @throws invalid_parameter_exception if the path is empty
* @throws moodle_exception if the category already exists
*/
public function create(): int {
if(count($this) === 0) {
if (count($this) === 0) {
throw new invalid_parameter_exception('path must not be empty');
}

if($this->exists()) {
if ($this->exists()) {
throw new moodle_exception('category_already_exists', 'local_adler');
}

Expand Down Expand Up @@ -82,15 +89,11 @@ public function create(): int {


/**
* @throws moodle_exception if the category does not exist
* @return int|bool Returns the ID of the category, or false if the category does not exist.
*/
public function get_category_id(): int {
public function get_category_id(): int|bool {
$categories = core_course_category::make_categories_list();
$key = array_search((string)$this, $categories);
if ($key === false) {
throw new moodle_exception('category_not_found', 'local_adler');
}
return $key;
return array_search((string)$this, $categories);
}

/**
Expand All @@ -104,12 +107,15 @@ public function append_to_path(string $path_part): void {
$this->path = array_merge($this->path, $this->split_and_trim_path($path_part));
}

/**
* @param string $path The path to split and trim.
* @return array Returns the path as an array of strings after splitting by '/' and trimming whitespace.
*/
private function split_and_trim_path(string $path): array {
// remove preceding and trailing /
$path = trim($path, ' /');

$path_parts = explode('/', $path);
return array_map('trim', $path_parts);
}

}
8 changes: 8 additions & 0 deletions classes/local/db/moodle_core_repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@
namespace local_adler\local\db;


use dml_exception;

class moodle_core_repository extends base_repository {
/**
* @throws dml_exception
*/
public function get_role_id_by_shortname(string $shortname): int {
global $DB;
return (int)$DB->get_field('role', 'id', array('shortname' => $shortname));
}

/**
* @throws dml_exception
*/
public function get_user_id_by_username(string $username): int {
global $DB;
return (int)$DB->get_field('user', 'id', array('username' => $username));
Expand Down
16 changes: 16 additions & 0 deletions classes/local/exceptions/exit_exception.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace local_adler\local\exceptions;

use Exception;
use Throwable;

class exit_exception extends Exception {
public function __construct($code = 0, Throwable $previous = null) {
parent::__construct(
"Exiting script",
$code,
$previous
);
}
}
4 changes: 4 additions & 0 deletions classes/moodle_core.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

namespace local_adler;

use coding_exception;
use context_coursecat;

/**
* This class contains aliases for moodle core functions to allow mocking them.
*/
class moodle_core {
/**
* @throws coding_exception
*/
public static function role_assign(...$args): int {
return role_assign(...$args);
}
Expand Down
73 changes: 73 additions & 0 deletions cli/create_course_cat_and_assign_user_role.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

use local_adler\local\course_category_manager;
use local_adler\local\exceptions\exit_exception;

if (!defined('CLI_SCRIPT')) {
define('CLI_SCRIPT', true);
}

require_once(__DIR__ . '/../../../config.php');
global $CFG;
require_once("{$CFG->libdir}/clilib.php");

$help =
"Create a new course category and grant the user permission to create adler courses in it.
Options:
--username=STRING User name
--role=STRING Role name
--category_path=STRING Category path (optional)
-h, --help Print out this help
";

// Parse command line arguments
list($options, $unrecognized) = cli_get_params(
array(
'username' => false,
'role' => false,
'category_path' => false,
'help' => false
),
array(
'h' => 'help'
)
);

if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_write(get_string('cliunknowoption', 'admin', $unrecognized) . "\n");
echo $help;
throw new exit_exception(1);
}

if (!empty($options['help'])) {
echo $help;
} else {
if (empty(trim($options['username']))) {
cli_writeln('--username is required');
throw new exit_exception(1);
}

if (empty(trim($options['role']))) {
cli_writeln('--role is required');
throw new exit_exception(1);
}

$username = trim($options['username']);
$role = trim($options['role']);
$category_path = trim($options['category_path']);


try {
$category_id = course_category_manager::create_category_user_can_create_courses_in($username, $role, $category_path);
} catch (moodle_exception $e) {
cli_writeln($e->getMessage());
throw new exit_exception(1);
}

cli_writeln("Created category with ID $category_id and assigned user $username the role $role in it.");
}


Loading

0 comments on commit a4cacd5

Please sign in to comment.