PHPDoc documentation

This commit is contained in:
PMKuipers 2023-08-27 23:27:07 +02:00
parent 92536683f0
commit 96f311a30b
14 changed files with 508 additions and 48 deletions

View file

@ -194,7 +194,7 @@ abstract class aggregator {
/** /**
* Webservice structure for basic aggregator info * Webservice structure for basic aggregator info
* @param int $value Webservice requirement constant * @param int $value Webservice requirement constant
* @return external_single_structure Webservice output structure * @return \external_description Webservice output structure
*/ */
public static function basic_structure($value = VALUE_REQUIRED) { public static function basic_structure($value = VALUE_REQUIRED) {
return new \external_single_structure([ return new \external_single_structure([

View file

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>. // along with Moodle. If not, see <https://www.gnu.org/licenses/>.
/** /**
* * Handle badge information
* @package local_treestudyplan * @package local_treestudyplan
* @copyright 2023 P.M. Kuipers * @copyright 2023 P.M. Kuipers
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -24,10 +24,22 @@ namespace local_treestudyplan;
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/externallib.php'); require_once($CFG->libdir.'/externallib.php');
use \core_badges\badge;
/**
* Handle badge information in the same style as the other classes
*/
class badgeinfo { class badgeinfo {
private $badge; // Holds database record. /**
* Holds database record
* @var \core_badges\badge
*/
private $badge;
/**
* Maps badge status to strings
* @var array
*/
private const STATUSINFO = [ private const STATUSINFO = [
BADGE_STATUS_INACTIVE => 'inactive', BADGE_STATUS_INACTIVE => 'inactive',
BADGE_STATUS_ACTIVE => 'active', BADGE_STATUS_ACTIVE => 'active',
@ -35,6 +47,11 @@ class badgeinfo {
BADGE_STATUS_ACTIVE_LOCKED => 'active', BADGE_STATUS_ACTIVE_LOCKED => 'active',
BADGE_STATUS_ARCHIVED => 'archived', BADGE_STATUS_ARCHIVED => 'archived',
]; ];
/**
* Maps badge status to locked or not
* @var array
*/
private const LOCKEDINFO = [ private const LOCKEDINFO = [
BADGE_STATUS_INACTIVE => 0, BADGE_STATUS_INACTIVE => 0,
BADGE_STATUS_ACTIVE => 0, BADGE_STATUS_ACTIVE => 0,
@ -43,8 +60,11 @@ class badgeinfo {
BADGE_STATUS_ARCHIVED => 1, // We don't want to edit archived badges anyway.... . BADGE_STATUS_ARCHIVED => 1, // We don't want to edit archived badges anyway.... .
]; ];
public function __construct(\core_badges\badge $badge) { /**
global $DB; * Construct new badgeinfo object
* @param badge $badge Badge object to use
*/
public function __construct(badge $badge) {
$this->badge = $badge; $this->badge = $badge;
} }
@ -56,12 +76,22 @@ class badgeinfo {
return $this->badge->name; return $this->badge->name;
} }
/**
* Get the badge id from the badge name
* @param string $name Badge name
* @return int Badge id
*/
public static function id_from_name($name) { public static function id_from_name($name) {
global $DB; global $DB;
return $DB->get_field("badge", "id", ['name' => $name]); return $DB->get_field("badge", "id", ['name' => $name]);
} }
/**
* Check if a given badge exists
* @param int $id Badge id
* @return bool
*/
public static function exists($id) { public static function exists($id) {
global $DB; global $DB;
return is_numeric($id) && $DB->record_exists('badge', array('id' => $id)); return is_numeric($id) && $DB->record_exists('badge', array('id' => $id));
@ -92,6 +122,7 @@ class badgeinfo {
/** /**
* Webservice model for editor info * Webservice model for editor info
* @param int[] $studentlist List of user id's to use for checking issueing progress within a study plan
* @return array Webservice data model * @return array Webservice data model
*/ */
public function editor_model(array $studentlist = null) { public function editor_model(array $studentlist = null) {
@ -197,6 +228,11 @@ class badgeinfo {
return $badge; return $badge;
} }
/**
* Count how many of the students in the array have this badge issued
* @param int[] $studentids List of user id's to check
* @return int
*/
public function count_issued(array $studentids) { public function count_issued(array $studentids) {
$issuecount = 0; $issuecount = 0;

View file

@ -41,7 +41,7 @@ class contextinfo {
/** /**
* Describe the result for the webservice model * Describe the result for the webservice model
* @param int $value Webservice requirement constant * @param int $value Webservice requirement constant
* @return external_single_structure Webservice output structure * @return \external_description Webservice output structure
*/ */
public static function structure($value = VALUE_REQUIRED) { public static function structure($value = VALUE_REQUIRED) {
return new \external_single_structure([ return new \external_single_structure([

View file

@ -236,7 +236,7 @@ class courseinfo {
/** /**
* Webservice structure for basic info * Webservice structure for basic info
* @param int $value Webservice requirement constant * @param int $value Webservice requirement constant
* @return external_single_structure Webservice output structure * @return \external_description Webservice output structure
*/ */
public static function simple_structure($value = VALUE_REQUIRED) { public static function simple_structure($value = VALUE_REQUIRED) {
return new \external_single_structure([ return new \external_single_structure([

View file

@ -145,7 +145,7 @@ class gradeinfo {
/** /**
* Get a specific course context from grade item id * Get a specific course context from grade item id
* @param int $id Grade item id * @param int $id Grade item id
* @return context_course * @return \context_course
* @throws InvalidArgumentException if grade id is not found * @throws InvalidArgumentException if grade id is not found
*/ */
public static function get_coursecontext_by_id($id) : \context_course { public static function get_coursecontext_by_id($id) : \context_course {
@ -251,7 +251,7 @@ class gradeinfo {
/** /**
* Webservice structure for editor info * Webservice structure for editor info
* @param int $value Webservice requirement constant * @param int $value Webservice requirement constant
* @return external_single_structure Webservice output structure * @return \external_description Webservice output structure
*/ */
/** /**
* Webservice structure for editor info * Webservice structure for editor info
@ -305,7 +305,7 @@ class gradeinfo {
/** /**
* Webservice structure for user info * Webservice structure for user info
* @param int $value Webservice requirement constant * @param int $value Webservice requirement constant
* @return external_single_structure Webservice output structure * @return \external_description Webservice output structure
*/ */
/** /**
* Webservice structure for userinfo * Webservice structure for userinfo

View file

@ -35,7 +35,7 @@ class period {
* Holds database record * Holds database record
* @var stdClass * @var stdClass
*/ */
private $r; // Holds database record. private $r;
/** @var int */ /** @var int */
private $id; private $id;
/** @var studyplanpage */ /** @var studyplanpage */
@ -46,6 +46,11 @@ class period {
} }
// Cache constructors to avoid multiple creation events in one session. // Cache constructors to avoid multiple creation events in one session.
/**
* Find record in database and return management object
* @param int $id Id of database record
* @return self
*/
public static function find_by_id($id): self { public static function find_by_id($id): self {
if (!array_key_exists($id, self::$cache)) { if (!array_key_exists($id, self::$cache)) {
self::$cache[$id] = new self($id); self::$cache[$id] = new self($id);
@ -123,6 +128,10 @@ class period {
return self::$pagecache[$page->id()]; return self::$pagecache[$page->id()];
} }
/**
* Construct new instance from DB record
* @param int $id Id of database record
*/
private function __construct($id) { private function __construct($id) {
global $DB; global $DB;
$this->id = $id; $this->id = $id;
@ -166,10 +175,18 @@ class period {
return $this->r->period; return $this->r->period;
} }
/**
* Start date
* @return \DateTime
*/
public function startdate() { public function startdate() {
return new \DateTime($this->r->startdate); return new \DateTime($this->r->startdate);
} }
/**
* End date
* @return \DateTime
*/
public function enddate() { public function enddate() {
if ($this->r->enddate && strlen($this->r->enddate) > 0) { if ($this->r->enddate && strlen($this->r->enddate) > 0) {
return new \DateTime($this->r->enddate); return new \DateTime($this->r->enddate);

View file

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>. // along with Moodle. If not, see <https://www.gnu.org/licenses/>.
/** /**
* * Webservice class for retrieving student studyplans
* @package local_treestudyplan * @package local_treestudyplan
* @copyright 2023 P.M. Kuipers * @copyright 2023 P.M. Kuipers
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -28,8 +28,14 @@ require_once($CFG->libdir.'/externallib.php');
use \local_treestudyplan\local\helpers\webservicehelper; use \local_treestudyplan\local\helpers\webservicehelper;
require_once($CFG->libdir.'/badgeslib.php'); require_once($CFG->libdir.'/badgeslib.php');
/**
* Webservice class for retrieving student studyplans
*/
class studentstudyplanservice extends \external_api { class studentstudyplanservice extends \external_api {
/**
* Capability required to view studyplans of other users
* @var string
*/
const CAP_VIEWOTHER = "local/treestudyplan:viewuserreports"; const CAP_VIEWOTHER = "local/treestudyplan:viewuserreports";
/************************ /************************
* * * *
@ -57,7 +63,12 @@ class studentstudyplanservice extends \external_api {
); );
} }
private static function list_user_studyplans($userid) { /**
* Return overview of the studyplans for a specific user
* @param int $userid ID of user to check specific info for
* @return array
*/
public static function list_user_studyplans($userid) {
global $CFG, $DB; global $CFG, $DB;
$list = []; $list = [];
@ -96,6 +107,12 @@ class studentstudyplanservice extends \external_api {
studyplan::user_structure() studyplan::user_structure()
); );
} }
/**
* Get the full studyplans for a specific user
* @param int $userid ID of user to check specific info for
* @return array
*/
public static function get_user_studyplans($userid) { public static function get_user_studyplans($userid) {
global $CFG, $DB; global $CFG, $DB;
@ -136,6 +153,13 @@ class studentstudyplanservice extends \external_api {
public static function get_user_studyplan_returns() { public static function get_user_studyplan_returns() {
return studyplan::user_structure(); return studyplan::user_structure();
} }
/**
* Get a specific studyplan for a given user
* @param int $userid ID of user to check specific info for
* @param int $studyplanid ID of studyplan to view
* @return array
*/
public static function get_user_studyplan($userid, $studyplanid) { public static function get_user_studyplan($userid, $studyplanid) {
global $CFG, $DB; global $CFG, $DB;
@ -174,6 +198,12 @@ class studentstudyplanservice extends \external_api {
studyplan::user_structure() studyplan::user_structure()
); );
} }
/**
* Get studyplan based on invite key
* @param int $invitekey Invitation key
* @return array
*/
public static function get_invited_studyplan($invitekey) { public static function get_invited_studyplan($invitekey) {
global $CFG, $DB; global $CFG, $DB;
@ -224,7 +254,11 @@ class studentstudyplanservice extends \external_api {
); );
} }
private static function list_own_studyplans() { /**
* Return overview of the studyplans the current user is linked to
* @return array
*/
public static function list_own_studyplans() {
global $CFG, $DB, $USER; global $CFG, $DB, $USER;
$userid = $USER->id; $userid = $USER->id;
@ -262,6 +296,11 @@ class studentstudyplanservice extends \external_api {
); );
} }
/**
* Get all studyplans for current user or a specific one
* @param int $id Optional id of specific studyplan
* @return array
*/
public static function get_own_studyplan($id = null) { public static function get_own_studyplan($id = null) {
global $USER; global $USER;
@ -314,6 +353,11 @@ class studentstudyplanservice extends \external_api {
); );
} }
/**
* Get all or one studyplan the current user is teaching in
* @param int $id Optional specific id of studyplan
* @return array
*/
public static function get_teaching_studyplans($id = null) { public static function get_teaching_studyplans($id = null) {
global $CFG, $DB, $USER; global $CFG, $DB, $USER;
$userid = $USER->id; $userid = $USER->id;

View file

@ -42,14 +42,14 @@ class studyitem {
* Holds database record * Holds database record
* @var stdClass * @var stdClass
*/ */
private $r; // Holds database record. private $r;
/** @var int */ /** @var int */
private $id; private $id;
private $courseinfo = null; private $courseinfo = null;
private $studyline; private $studyline;
/** @var aggragator[] */ /** @var aggregator[] */
/** @var aggragator */ /** @var aggregator */
private $aggregator; private $aggregator;
@ -69,6 +69,11 @@ class studyitem {
return $this->r->conditions; return $this->r->conditions;
} }
/**
* Find record in database and return management object
* @param int $id Id of database record
* @return self
*/
public static function find_by_id($id): self { public static function find_by_id($id): self {
if (!array_key_exists($id, self::$studyitemcache)) { if (!array_key_exists($id, self::$studyitemcache)) {
self::$studyitemcache[$id] = new self($id); self::$studyitemcache[$id] = new self($id);
@ -315,6 +320,9 @@ class studyitem {
global $DB; global $DB;
foreach ($resequence as $sq) { foreach ($resequence as $sq) {
// Only change line_id if new line is within the same studyplan page
if ( studyitem::find_by_id($sq['id'])->studyline()->page()->id() ==
studyline::find_by_id($sq['line_id'])->page()->id() ) {
$DB->update_record(self::TABLE, [ $DB->update_record(self::TABLE, [
'id' => $sq['id'], 'id' => $sq['id'],
'line_id' => $sq['line_id'], 'line_id' => $sq['line_id'],
@ -322,6 +330,7 @@ class studyitem {
'layer' => $sq['layer'], 'layer' => $sq['layer'],
]); ]);
} }
}
return success::success(); return success::success();
} }

View file

@ -55,7 +55,7 @@ class studyitemconnection {
/** /**
* Webservice structure for basic info * Webservice structure for basic info
* @param int $value Webservice requirement constant * @param int $value Webservice requirement constant
* @return external_single_structure Webservice output structure * @return \external_description Webservice output structure
*/ */
public static function structure($value = VALUE_REQUIRED) { public static function structure($value = VALUE_REQUIRED) {
return new \external_single_structure([ return new \external_single_structure([

View file

@ -51,7 +51,7 @@ class studyline {
* Holds database record * Holds database record
* @var stdClass * @var stdClass
*/ */
private $r; // Holds database record. private $r;
/** @var int */ /** @var int */
private $id; private $id;
/** @var studyplanpage */ /** @var studyplanpage */
@ -76,6 +76,11 @@ class studyline {
return $this->page; return $this->page;
} }
/**
* Find record in database and return management object
* @param int $id Id of database record
* @return self
*/
public static function find_by_id($id): self { public static function find_by_id($id): self {
if (!array_key_exists($id, self::$studylinecache)) { if (!array_key_exists($id, self::$studylinecache)) {
self::$studylinecache[$id] = new self($id); self::$studylinecache[$id] = new self($id);
@ -83,6 +88,10 @@ class studyline {
return self::$studylinecache[$id]; return self::$studylinecache[$id];
} }
/**
* Construct new instance from DB record
* @param int $id Id of database record
*/
private function __construct($id) { private function __construct($id) {
global $DB; global $DB;
$this->id = $id; $this->id = $id;

View file

@ -35,10 +35,10 @@ class studyplan {
* Holds database record * Holds database record
* @var stdClass * @var stdClass
*/ */
private $r; // Holds database record. private $r;
/** @var int */ /** @var int */
private $id; private $id;
/** @var aggragator */ /** @var aggregator */
private $aggregator; private $aggregator;
private $context = null; // Hold context object once retrieved. private $context = null; // Hold context object once retrieved.
private $linkeduserids = null; // Cache lookup of linked users (saves queries). private $linkeduserids = null; // Cache lookup of linked users (saves queries).
@ -50,6 +50,11 @@ class studyplan {
} }
// Cache constructors to avoid multiple creation events in one session. // Cache constructors to avoid multiple creation events in one session.
/**
* Find record in database and return management object
* @param int $id Id of database record
* @return self
*/
public static function find_by_id($id): self { public static function find_by_id($id): self {
if (!array_key_exists($id, self::$studyplancache)) { if (!array_key_exists($id, self::$studyplancache)) {
self::$studyplancache[$id] = new self($id); self::$studyplancache[$id] = new self($id);
@ -57,6 +62,10 @@ class studyplan {
return self::$studyplancache[$id]; return self::$studyplancache[$id];
} }
/**
* Construct new instance from DB record
* @param int $id Id of database record
*/
private function __construct($id) { private function __construct($id) {
global $DB; global $DB;
$this->id = $id; $this->id = $id;
@ -119,7 +128,7 @@ class studyplan {
/** /**
* Webservice structure for basic info * Webservice structure for basic info
* @param int $value Webservice requirement constant * @param int $value Webservice requirement constant
* @return external_single_structure Webservice output structure * @return \external_description Webservice output structure
*/ */
public static function simple_structure($value = VALUE_REQUIRED) { public static function simple_structure($value = VALUE_REQUIRED) {
return new \external_single_structure([ return new \external_single_structure([
@ -546,6 +555,10 @@ class studyplan {
return $newplan; return $newplan;
} }
/**
* Description of export structure for webservices
* @return \external_description
*/
public static function export_structure() { public static function export_structure() {
return new \external_single_structure([ return new \external_single_structure([
"format" => new \external_value(PARAM_TEXT, 'format of studyplan export'), "format" => new \external_value(PARAM_TEXT, 'format of studyplan export'),

View file

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>. // along with Moodle. If not, see <https://www.gnu.org/licenses/>.
/** /**
* * Studyplan page management class
* @package local_treestudyplan * @package local_treestudyplan
* @copyright 2023 P.M. Kuipers * @copyright 2023 P.M. Kuipers
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -24,11 +24,18 @@ namespace local_treestudyplan;
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/externallib.php'); require_once($CFG->libdir.'/externallib.php');
/**
* Studyplan page management class
*/
class studyplanpage { class studyplanpage {
/** @var string */ /**
* Database table this class models for
* @var string */
const TABLE = "local_treestudyplan_page"; const TABLE = "local_treestudyplan_page";
/**
* Cache for finding previously loaded pages
* @var array */
private static $cache = []; private static $cache = [];
/** /**
@ -41,11 +48,19 @@ class studyplanpage {
/** @var studyplan*/ /** @var studyplan*/
private $studyplan; private $studyplan;
public function aggregator() { /**
* Get aggregator for the studyplan (page)
* @return aggregator
*/
public function aggregator() : aggregator {
return $this->studyplan->aggregator(); return $this->studyplan->aggregator();
} }
// Cache constructors to avoid multiple creation events in one session. /**
* Find record in database and return management object
* @param int $id Id of database record
* @return self
*/
public static function find_by_id($id): self { public static function find_by_id($id): self {
if (!array_key_exists($id, self::$cache)) { if (!array_key_exists($id, self::$cache)) {
self::$cache[$id] = new self($id); self::$cache[$id] = new self($id);
@ -53,6 +68,10 @@ class studyplanpage {
return self::$cache[$id]; return self::$cache[$id];
} }
/**
* Construct new instance from DB record
* @param int $id Id of database record
*/
private function __construct($id) { private function __construct($id) {
global $DB; global $DB;
$this->id = $id; $this->id = $id;
@ -68,6 +87,9 @@ class studyplanpage {
return $this->id; return $this->id;
} }
/**
* Find studyplan for this page
*/
public function studyplan() : studyplan { public function studyplan() : studyplan {
return $this->studyplan; return $this->studyplan;
} }
@ -80,6 +102,9 @@ class studyplanpage {
return $this->r->shortname; return $this->r->shortname;
} }
/**
* Numer of periods for this page
*/
public function periods() { public function periods() {
return $this->r->periods; return $this->r->periods;
} }
@ -92,10 +117,18 @@ class studyplanpage {
return $this->r->fullname; return $this->r->fullname;
} }
/**
* Start date
* @return \DateTime
*/
public function startdate() { public function startdate() {
return new \DateTime($this->r->startdate); return new \DateTime($this->r->startdate);
} }
/**
* End date
* @return \DateTime
*/
public function enddate() { public function enddate() {
if ($this->r->enddate && strlen($this->r->enddate) > 0) { if ($this->r->enddate && strlen($this->r->enddate) > 0) {
return new \DateTime($this->r->enddate); return new \DateTime($this->r->enddate);
@ -109,7 +142,7 @@ class studyplanpage {
/** /**
* Webservice structure for basic info * Webservice structure for basic info
* @param int $value Webservice requirement constant * @param int $value Webservice requirement constant
* @return external_single_structure Webservice output structure * @return \external_description Webservice output structure
*/ */
public static function simple_structure($value = VALUE_REQUIRED) { public static function simple_structure($value = VALUE_REQUIRED) {
return new \external_single_structure([ return new \external_single_structure([
@ -186,6 +219,11 @@ class studyplanpage {
return $model; return $model;
} }
/**
* Add new study plan page
* @param mixed $fields Parameter for new study plan page
* @return self
*/
public static function add($fields) { public static function add($fields) {
global $CFG, $DB; global $CFG, $DB;
@ -210,6 +248,11 @@ class studyplanpage {
return self::find_by_id($id); // Make sure the new page is immediately cached. return self::find_by_id($id); // Make sure the new page is immediately cached.
} }
/**
* Edit studyplan page
* @param mixed $fields Parameters to change
* @return self
*/
public function edit($fields) { public function edit($fields) {
global $DB; global $DB;
$editable = ['fullname', 'shortname', 'description', 'periods', 'startdate', 'enddate']; $editable = ['fullname', 'shortname', 'description', 'periods', 'startdate', 'enddate'];
@ -230,6 +273,11 @@ class studyplanpage {
return $this; return $this;
} }
/**
* Delete study plan page
* @param bool $force Force deletion even if not empty
* @return success
*/
public function delete($force = false) { public function delete($force = false) {
global $DB; global $DB;
@ -293,6 +341,11 @@ class studyplanpage {
return $model; return $model;
} }
/**
* Find list of pages belonging to a specified study plan
* @param studyplan $plan Studyplan to search pages for
* @return self[]
*/
public static function find_studyplan_children(studyplan $plan) { public static function find_studyplan_children(studyplan $plan) {
global $DB; global $DB;
$list = []; $list = [];
@ -304,13 +357,24 @@ class studyplanpage {
return $list; return $list;
} }
public static function duplicate_page($pageid, $name, $shortname) { /**
* Duplicate a studyplan page
* @param int $pageid Id of the page to copy
* @param studyplan $newstudyplan Studyplan to copy the page into
* @return self
*/
public static function duplicate_page(int $pageid, studyplan $newstudyplan) {
$ori = self::find_by_id($pageid); $ori = self::find_by_id($pageid);
$new = $ori->duplicate($name, $shortname); $new = $ori->duplicate($newstudyplan);
return $new->simple_model(); return $new;
} }
public function duplicate($newstudyplan) { /**
* Duplicate this studyplan page
* @param studyplan $newstudyplan Studyplan to copy the page into
* @return self
*/
public function duplicate(studyplan $newstudyplan) {
// First duplicate the studyplan structure. // First duplicate the studyplan structure.
$new = self::add([ $new = self::add([
'studyplan_id' => $newstudyplan->id(), 'studyplan_id' => $newstudyplan->id(),
@ -345,6 +409,10 @@ class studyplanpage {
return $new; return $new;
} }
/**
* Description of export structure for webservices
* @return \external_description
*/
public static function export_structure() { public static function export_structure() {
return new \external_single_structure([ return new \external_single_structure([
"format" => new \external_value(PARAM_TEXT, 'format of studyplan export'), "format" => new \external_value(PARAM_TEXT, 'format of studyplan export'),
@ -352,6 +420,10 @@ class studyplanpage {
], 'Exported studyplan'); ], 'Exported studyplan');
} }
/**
* Export this page into a json model
* @return array
*/
public function export_page() { public function export_page() {
$model = $this->export_model(); $model = $this->export_model();
$json = json_encode([ $json = json_encode([
@ -362,6 +434,10 @@ class studyplanpage {
return [ "format" => "application/json", "content" => $json]; return [ "format" => "application/json", "content" => $json];
} }
/**
* Export this page into a csv model
* @return array
*/
public function export_page_csv() { public function export_page_csv() {
$plist = period::find_for_page($this); $plist = period::find_for_page($this);
@ -436,6 +512,10 @@ class studyplanpage {
return [ "format" => "text/csv", "content" => $csv]; return [ "format" => "text/csv", "content" => $csv];
} }
/**
* Export this page's studylines into a json model
* @return array
*/
public function export_studylines() { public function export_studylines() {
$model = $this->export_studylines_model(); $model = $this->export_studylines_model();
$json = json_encode([ $json = json_encode([
@ -446,6 +526,10 @@ class studyplanpage {
return [ "format" => "application/json", "content" => $json]; return [ "format" => "application/json", "content" => $json];
} }
/**
* Export this pages periods into a json model
* @return array
*/
public function export_periods() { public function export_periods() {
$model = period::page_model($this); $model = period::page_model($this);
$json = json_encode([ $json = json_encode([
@ -474,6 +558,10 @@ class studyplanpage {
return $model; return $model;
} }
/**
* Export this pages periods into an array before serialization
* @return array
*/
public function export_studylines_model() { public function export_studylines_model() {
$children = studyline::find_page_children($this); $children = studyline::find_page_children($this);
$lines = []; $lines = [];
@ -483,6 +571,11 @@ class studyplanpage {
return $lines; return $lines;
} }
/**
* Import periods from file contents
* @param string $content String
* @param string $format Format description
*/
public function import_periods($content, $format = "application/json") { public function import_periods($content, $format = "application/json") {
if ($format != "application/json") { if ($format != "application/json") {
return false; return false;
@ -497,6 +590,11 @@ class studyplanpage {
} }
} }
/**
* Import studylines from file contents
* @param string $content String
* @param string $format Format description
*/
public function import_studylines($content, $format = "application/json") { public function import_studylines($content, $format = "application/json") {
if ($format != "application/json") { if ($format != "application/json") {
return false; return false;
@ -513,6 +611,11 @@ class studyplanpage {
} }
} }
/**
* Find a studyline in this page by its shortname
* @param string $shortname
* @return studyline|null
*/
protected function find_studyline_by_shortname($shortname) { protected function find_studyline_by_shortname($shortname) {
$children = studyline::find_page_children($this); $children = studyline::find_page_children($this);
foreach ($children as $l) { foreach ($children as $l) {
@ -523,6 +626,10 @@ class studyplanpage {
return null; return null;
} }
/**
* Import periods from decoded array model
* @param array $model Decoded array
*/
public function import_periods_model($model) { public function import_periods_model($model) {
$periods = period::find_for_page($this); $periods = period::find_for_page($this);
foreach ($model as $pmodel) { foreach ($model as $pmodel) {
@ -533,6 +640,10 @@ class studyplanpage {
} }
} }
/**
* Import studylines from decoded array model
* @param array $model Decoded array
*/
public function import_studylines_model($model) { public function import_studylines_model($model) {
// First attempt to map each studyline model to an existing or new line. // First attempt to map each studyline model to an existing or new line.
$linemap = []; $linemap = [];

View file

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>. // along with Moodle. If not, see <https://www.gnu.org/licenses/>.
/** /**
* * Webservice class for managing studyplans
* @package local_treestudyplan * @package local_treestudyplan
* @copyright 2023 P.M. Kuipers * @copyright 2023 P.M. Kuipers
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -30,9 +30,19 @@ require_once($CFG->libdir.'/badgeslib.php');
require_once($CFG->libdir.'/gradelib.php'); require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->dirroot.'/course/modlib.php'); require_once($CFG->dirroot.'/course/modlib.php');
/**
* Webservice class for managing studyplans
*/
class studyplanservice extends \external_api { class studyplanservice extends \external_api {
/**
* Capability required to edit study plans
* @var string
*/
const CAP_EDIT = "local/treestudyplan:editstudyplan"; const CAP_EDIT = "local/treestudyplan:editstudyplan";
/**
* Capability required to view studyplans (for other users)
* @var string
*/
const CAP_VIEW = "local/treestudyplan:viewuserreports"; const CAP_VIEW = "local/treestudyplan:viewuserreports";
/************************ /************************
@ -59,6 +69,11 @@ class studyplanservice extends \external_api {
return new \external_multiple_structure( studyplan::simple_structure() ); return new \external_multiple_structure( studyplan::simple_structure() );
} }
/**
* Get overview of all studyplans in a given context
* @param int $contextid Id of context to view (defaults to systemcontext)
* @return array
*/
public static function list_studyplans($contextid = 0) { public static function list_studyplans($contextid = 0) {
global $CFG, $DB; global $CFG, $DB;
@ -100,6 +115,11 @@ class studyplanservice extends \external_api {
return studyplan::editor_structure(); return studyplan::editor_structure();
} }
/**
* Get editor model for specific studyplan
* @param int $id Id of studyplan
* @return array
*/
public static function get_studyplan_map($id) { public static function get_studyplan_map($id) {
if (isset($id) && $id > 0) { if (isset($id) && $id > 0) {
$studyplan = studyplan::find_by_id($id); $studyplan = studyplan::find_by_id($id);
@ -134,6 +154,11 @@ class studyplanservice extends \external_api {
return new \external_multiple_structure( studyline::editor_structure() ); return new \external_multiple_structure( studyline::editor_structure() );
} }
/**
* Get editor model for specific study line
* @param int $id ID of study line
* @return array
*/
public static function get_studyline_map($id) { public static function get_studyline_map($id) {
$o = studyline::find_by_id($id); $o = studyline::find_by_id($id);
@ -174,6 +199,20 @@ class studyplanservice extends \external_api {
return studyplan::simple_structure(); return studyplan::simple_structure();
} }
/**
* Add a new studyplan in a given context
* @param mixed $name
* @param mixed $shortname
* @param mixed $idnumber
* @param mixed $description
* @param mixed $periods
* @param mixed $startdate
* @param mixed $enddate
* @param string $aggregation
* @param string $aggregationconfig
* @param int $contextid
* @return array
*/
public static function add_studyplan($name, $shortname, $idnumber, $description, $periods, public static function add_studyplan($name, $shortname, $idnumber, $description, $periods,
$startdate, $enddate, $aggregation = "bistate", $aggregationconfig = '', $contextid = 0) { $startdate, $enddate, $aggregation = "bistate", $aggregationconfig = '', $contextid = 0) {
// Check if we have the proper rights for the requested context. // Check if we have the proper rights for the requested context.
@ -229,6 +268,21 @@ class studyplanservice extends \external_api {
return studyplan::simple_structure(); return studyplan::simple_structure();
} }
/**
* Edit studyplan parameters
* @param mixed $id
* @param mixed $name
* @param mixed $shortname
* @param mixed $idnumber
* @param mixed $description
* @param mixed $periods
* @param mixed $startdate
* @param mixed $enddate
* @param string $aggregation
* @param string $aggregationconfig
* @param int $contextid
* @return array
*/
public static function edit_studyplan($id, $name, $shortname, $idnumber, $description, $periods, $startdate, public static function edit_studyplan($id, $name, $shortname, $idnumber, $description, $periods, $startdate,
$enddate, $aggregation = "bistate", $aggregationconfig = '', $contextid = 0) { $enddate, $aggregation = "bistate", $aggregationconfig = '', $contextid = 0) {
// Validate access in the intended context. // Validate access in the intended context.
@ -279,6 +333,12 @@ class studyplanservice extends \external_api {
return success::structure(); return success::structure();
} }
/**
* Delete a studyplan
* @param mixed $id Id of the studyplan
* @param bool $force Force deletion, even though studyplan is not empty
* @return array Succes/fail model
*/
public static function delete_studyplan($id, $force = false) { public static function delete_studyplan($id, $force = false) {
$o = studyplan::find_by_id($id); $o = studyplan::find_by_id($id);
// Validate if the requesting user has the right to edit the plan in it's current context. // Validate if the requesting user has the right to edit the plan in it's current context.
@ -314,6 +374,15 @@ class studyplanservice extends \external_api {
return studyline::editor_structure(); return studyline::editor_structure();
} }
/**
* Add a new study line
* @param mixed $pageid
* @param mixed $name
* @param mixed $shortname
* @param mixed $color
* @param mixed $sequence
* @return array
*/
public static function add_studyline($pageid, $name, $shortname, $color, $sequence) { public static function add_studyline($pageid, $name, $shortname, $color, $sequence) {
// Validate if the requesting user has the right to edit the plan in it's current context. // Validate if the requesting user has the right to edit the plan in it's current context.
$page = studyplanpage::find_by_id($pageid); $page = studyplanpage::find_by_id($pageid);
@ -356,6 +425,14 @@ class studyplanservice extends \external_api {
return studyline::editor_structure(); return studyline::editor_structure();
} }
/**
* Edit studyline parameters
* @param mixed $id
* @param mixed $name
* @param mixed $shortname
* @param mixed $color
* @return [type]
*/
public static function edit_studyline($id, $name, $shortname, $color) { public static function edit_studyline($id, $name, $shortname, $color) {
$o = studyline::find_by_id($id); $o = studyline::find_by_id($id);
// Validate if the requesting user has the right to edit the plan in it's current context. // Validate if the requesting user has the right to edit the plan in it's current context.
@ -393,12 +470,17 @@ class studyplanservice extends \external_api {
return success::structure(); return success::structure();
} }
/**
* Delete a study line
* @param mixed $id Id of the studyline
* @return array Success/fail model
*
*/
public static function delete_studyline($id) { public static function delete_studyline($id) {
$o = studyline::find_by_id($id); $o = studyline::find_by_id($id);
// Validate if the requesting user has the right to edit the plan in it's current context. // Validate if the requesting user has the right to edit the plan in it's current context.
webservicehelper::require_capabilities(self::CAP_EDIT, $o->context()); webservicehelper::require_capabilities(self::CAP_EDIT, $o->context());
return $o->delete()->model(); return $o->delete()->model();
} }
/************************ /************************
@ -430,6 +512,11 @@ class studyplanservice extends \external_api {
return success::structure(); return success::structure();
} }
/**
* Reorder study lines
* @param int[] $resequence New order of study lines by id
* @return [type]
*/
public static function reorder_studylines($resequence) { public static function reorder_studylines($resequence) {
// Validate if the requesting user has the right to edit the lines in it's current context. // Validate if the requesting user has the right to edit the lines in it's current context.
foreach ($resequence as $sq) { foreach ($resequence as $sq) {
@ -468,6 +555,11 @@ class studyplanservice extends \external_api {
return studyitem::editor_structure(); return studyitem::editor_structure();
} }
/**
* Get editor model for study item
* @param mixed $id ID of study item
* @return array
*/
public static function get_studyitem($id) { public static function get_studyitem($id) {
$o = studyitem::find_by_id($id); $o = studyitem::find_by_id($id);
webservicehelper::require_capabilities([self::CAP_EDIT, self::CAP_VIEW], $o->context()); webservicehelper::require_capabilities([self::CAP_EDIT, self::CAP_VIEW], $o->context());
@ -509,6 +601,15 @@ class studyplanservice extends \external_api {
return studyitem::editor_structure(); return studyitem::editor_structure();
} }
/**
* Add a new study item
* @param int $lineid
* @param string $type
* @param array $details
* @param int $slot
* @param int $layer
* @return array
*/
public static function add_studyitem($lineid, $type, $details, $slot = -1, $layer = 0) { public static function add_studyitem($lineid, $type, $details, $slot = -1, $layer = 0) {
webservicehelper::require_capabilities(self::CAP_EDIT, studyline::find_by_id($lineid)->context()); webservicehelper::require_capabilities(self::CAP_EDIT, studyline::find_by_id($lineid)->context());
@ -551,6 +652,13 @@ class studyplanservice extends \external_api {
return studyitem::editor_structure(); return studyitem::editor_structure();
} }
/**
* Edit study item paremeters
* @param mixed $id Id of studt item
* @param mixed $conditions Conditions related to item (filters only)
* @param bool $continuationid Link to previous filter item to copy result from (not used)
* @return array
*/
public static function edit_studyitem($id, $conditions, $continuationid = false) { public static function edit_studyitem($id, $conditions, $continuationid = false) {
$o = studyitem::find_by_id($id); $o = studyitem::find_by_id($id);
@ -599,6 +707,11 @@ class studyplanservice extends \external_api {
return success::structure(); return success::structure();
} }
/**
* Reposition study items in line, layer and/or slot
* @param mixed $resequence Array of item info [id, line_id, slot, layer]
* @return array Success/fail model
*/
public static function reorder_studyitems($resequence) { public static function reorder_studyitems($resequence) {
// Check for permissions to modify the studyplan. // Check for permissions to modify the studyplan.
foreach ($resequence as $sq) { foreach ($resequence as $sq) {
@ -632,6 +745,11 @@ class studyplanservice extends \external_api {
return success::structure(); return success::structure();
} }
/**
* Delete a studyitem
* @param mixed $id Id of study item to delete
* @return array Success/fail model
*/
public static function delete_studyitem($id) { public static function delete_studyitem($id) {
$o = studyitem::find_by_id($id); $o = studyitem::find_by_id($id);
webservicehelper::require_capabilities(self::CAP_EDIT, $o->context()); webservicehelper::require_capabilities(self::CAP_EDIT, $o->context());
@ -664,6 +782,12 @@ class studyplanservice extends \external_api {
return studyitemconnection::structure(); return studyitemconnection::structure();
} }
/**
* Connect two studylines
* @param mixed $fromid Originating item
* @param mixed $toid Target item
* @return array Success/fail model
*/
public static function connect_studyitems($fromid, $toid) { public static function connect_studyitems($fromid, $toid) {
// Validate permissions. // Validate permissions.
webservicehelper::require_capabilities(self::CAP_EDIT, studyitem::find_by_id($fromid)->context()); webservicehelper::require_capabilities(self::CAP_EDIT, studyitem::find_by_id($fromid)->context());
@ -698,6 +822,12 @@ class studyplanservice extends \external_api {
return success::structure(); return success::structure();
} }
/**
* Disconnect two studylines
* @param mixed $fromid Originating item
* @param mixed $toid Target item
* @return array Success/fail model
*/
public static function disconnect_studyitems($fromid, $toid) { public static function disconnect_studyitems($fromid, $toid) {
// Validate permissions. // Validate permissions.
webservicehelper::require_capabilities(self::CAP_EDIT, studyitem::find_by_id($fromid)->context()); webservicehelper::require_capabilities(self::CAP_EDIT, studyitem::find_by_id($fromid)->context());
@ -727,6 +857,10 @@ class studyplanservice extends \external_api {
return new \external_multiple_structure(badgeinfo::editor_structure()); return new \external_multiple_structure(badgeinfo::editor_structure());
} }
/**
* List all available badges to drag into a studyplan page
* @return array
*/
public static function list_badges() { public static function list_badges() {
$systemcontext = webservicehelper::system_context(); $systemcontext = webservicehelper::system_context();
@ -770,6 +904,16 @@ class studyplanservice extends \external_api {
return success::structure(); return success::structure();
} }
/**
* Mark a gradable item for inclusion in the studyplan
* @param mixed $gradeid Id of gradable
* @param mixed $itemid Id of study item
* @param bool $include Include grade or not
* @param bool $required Mark grade as required or not
* @return array Success/Fail model
*
*/
public static function include_grade($gradeid, $itemid, $include, $required = false) { public static function include_grade($gradeid, $itemid, $include, $required = false) {
global $USER; global $USER;
@ -810,6 +954,10 @@ class studyplanservice extends \external_api {
return aggregator::list_structure(); return aggregator::list_structure();
} }
/**
* List available aggregators
* @return array
*/
public static function list_aggregators() { public static function list_aggregators() {
return aggregator::list_model(); return aggregator::list_model();
@ -847,6 +995,12 @@ class studyplanservice extends \external_api {
])); ]));
} }
/**
* Force all gradables in the studyplan to the same scale item
* @param int $studyplanid Id of studyplan
* @param int $scaleid Id of scale to use
* @return array
*/
public static function force_studyplan_scale($studyplanid, $scaleid) { public static function force_studyplan_scale($studyplanid, $scaleid) {
global $DB; global $DB;
$dbman = $DB->get_manager(); $dbman = $DB->get_manager();
@ -967,6 +1121,10 @@ class studyplanservice extends \external_api {
])); ]));
} }
/**
* List available scales
* @return array
*/
public static function list_scales() { public static function list_scales() {
global $DB; global $DB;
$list = []; $list = [];
@ -1007,6 +1165,11 @@ class studyplanservice extends \external_api {
return success::structure(); return success::structure();
} }
/**
* Disable automatic end date for all courses in a study plan
* @param int $studyplanid Id of the studyplan
* @return array Success/fail model
*/
public static function disable_autoenddate($studyplanid) { public static function disable_autoenddate($studyplanid) {
global $DB; global $DB;
@ -1060,6 +1223,13 @@ class studyplanservice extends \external_api {
return studyplan::simple_structure(); return studyplan::simple_structure();
} }
/**
* Duplicate a studyplan into a new one
* @param mixed $studyplanid Id of the plan to duplicate
* @param mixed $name New fullname
* @param mixed $shortname New shortname
* @return array
*/
public static function duplicate_plan($studyplanid, $name, $shortname) { public static function duplicate_plan($studyplanid, $name, $shortname) {
// Validate permissions. // Validate permissions.
webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::find_by_id($studyplanid)->context()); webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::find_by_id($studyplanid)->context());
@ -1092,6 +1262,13 @@ class studyplanservice extends \external_api {
return studyplan::export_structure(); return studyplan::export_structure();
} }
/**
* Export studyplan
* @param mixed $studyplanid Id of studyplan to export
* @param string $format Export format [csv, json (default)]
* @return array
*/
public static function export_plan($studyplanid, $format = "json") { public static function export_plan($studyplanid, $format = "json") {
try { try {
// Validate permissions. // Validate permissions.
@ -1127,9 +1304,12 @@ class studyplanservice extends \external_api {
return studyplan::export_structure(); return studyplan::export_structure();
} }
/**
* Export studylines for a studyplan
* @param mixed $studyplanid Id of the studyplan to export the studylines for
* @return array
*/
public static function export_studylines($studyplanid) { public static function export_studylines($studyplanid) {
$systemcontext = webservicehelper::system_context();
try { try {
webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::find_by_id($studyplanid)->context()); webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::find_by_id($studyplanid)->context());
$plan = studyplan::find_by_id($studyplanid); $plan = studyplan::find_by_id($studyplanid);
@ -1165,6 +1345,13 @@ class studyplanservice extends \external_api {
return success::structure(); return success::structure();
} }
/**
* Import studyplan from file
* @param string $content Content of file
* @param string $format Format of file
* @param int $contextid ID of context to import to
* @return array Success/fail model
*/
public static function import_plan($content, $format = "application/json", $contextid = 1) { public static function import_plan($content, $format = "application/json", $contextid = 1) {
try { try {
@ -1199,8 +1386,14 @@ class studyplanservice extends \external_api {
return success::structure(); return success::structure();
} }
/**
* Import studylines into existing studtplan
* @param int $studyplanid ID of studyplan to import to
* @param string $content Content of file
* @param string $format Format of file
* @return array Success/fail model
*/
public static function import_studylines($studyplanid, $content, $format = "application/json") { public static function import_studylines($studyplanid, $content, $format = "application/json") {
try { try {
$plan = studyplan::find_by_id($studyplanid); $plan = studyplan::find_by_id($studyplanid);
// Validate import context. // Validate import context.
@ -1241,7 +1434,13 @@ class studyplanservice extends \external_api {
return success::structure(); return success::structure();
} }
/** DEPRECATED, will remove hacked edit form in the future */ /**
* Submit hacked course activity edit form to edit just name and description
* @deprecated will remove hacked edit form in the future
* @param mixed $cmid
* @param mixed $formdata
* @return array Success/fail structure
*/
public static function submit_cm_editform($cmid, $formdata) { public static function submit_cm_editform($cmid, $formdata) {
global $CFG; global $CFG;
global $DB; global $DB;
@ -1329,6 +1528,15 @@ class studyplanservice extends \external_api {
return period::structure(); return period::structure();
} }
/**
* Edit period information
* @param mixed $id
* @param mixed $fullname
* @param mixed $shortname
* @param mixed $startdate
* @param mixed $enddate
* @return array
*/
public static function edit_period($id, $fullname, $shortname, $startdate, $enddate) { public static function edit_period($id, $fullname, $shortname, $startdate, $enddate) {
$p = period::find_by_id($id); $p = period::find_by_id($id);
@ -1370,6 +1578,13 @@ class studyplanservice extends \external_api {
return courseinfo::editor_structure(); return courseinfo::editor_structure();
} }
/**
* Match course start/end to period start/end times
* @param mixed $periodid
* @param mixed $courseid
* @param int $span
* @return array
*/
public static function course_period_timing($periodid, $courseid, $span = 1) { public static function course_period_timing($periodid, $courseid, $span = 1) {
global $DB; global $DB;
$period = period::find_by_id($periodid); $period = period::find_by_id($periodid);
@ -1442,6 +1657,12 @@ class studyplanservice extends \external_api {
return studyitem::editor_structure(); return studyitem::editor_structure();
} }
/**
* Set studyitem span to one or more periods
* @param mixed $id
* @param null $span
* @return array
*/
public static function set_studyitem_span($id, $span = null) { public static function set_studyitem_span($id, $span = null) {
$o = studyitem::find_by_id($id); $o = studyitem::find_by_id($id);
webservicehelper::require_capabilities(self::CAP_EDIT, $o->context()); webservicehelper::require_capabilities(self::CAP_EDIT, $o->context());

View file

@ -68,7 +68,7 @@ class success {
/** /**
* Describe the result for the webservice model * Describe the result for the webservice model
* @return external_single_structure * @return \external_description
*/ */
public static function structure() { public static function structure() {
return new \external_single_structure([ return new \external_single_structure([