2023-05-17 21:19:14 +02:00
< ? php
namespace local_treestudyplan ;
require_once ( $CFG -> libdir . '/externallib.php' );
class studyplan {
const TABLE = " local_treestudyplan " ;
private static $STUDYPLAN_CACHE = [];
private $r ; // Holds database record
private $id ;
private $aggregator ;
private $context = null ; // Hold context object once retrieved
2023-06-16 23:12:17 +02:00
private $linked_userids = null ; // cache lookup of linked users (saves queries)
2023-07-23 16:25:08 +02:00
private $page_cache = null ;
2023-05-17 21:19:14 +02:00
2023-07-23 16:25:08 +02:00
public function aggregator (){
2023-05-17 21:19:14 +02:00
return $this -> aggregator ;
}
// Cache constructors to avoid multiple creation events in one session.
public static function findById ( $id ) : self {
if ( ! array_key_exists ( $id , self :: $STUDYPLAN_CACHE )){
self :: $STUDYPLAN_CACHE [ $id ] = new self ( $id );
}
return self :: $STUDYPLAN_CACHE [ $id ];
}
private function __construct ( $id ) {
global $DB ;
$this -> id = $id ;
$this -> r = $DB -> get_record ( self :: TABLE ,[ 'id' => $id ]);
$this -> aggregator = aggregator :: createOrDefault ( $this -> r -> aggregation , $this -> r -> aggregation_config );
}
public function id (){
return $this -> id ;
}
2023-06-26 13:03:50 +02:00
public function shortname (){
return $this -> r -> shortname ;
}
2023-05-17 21:19:14 +02:00
public function name (){
return $this -> r -> name ;
}
2023-07-23 16:25:08 +02:00
public function pages (){
// cached version of find_studyplan_children.
// (may be premature optimization, since
// find_studyplan_children also does some caching)
if ( empty ( $this -> page_cache )){
$this -> page_cache = studyplanpage :: find_studyplan_children ( $this );
}
return $this -> page_cache ;
}
2023-05-17 21:19:14 +02:00
/**
* Return the context this studyplan is associated to
*/
public function context () : \context {
if ( ! isset ( $this -> context )){
try {
$this -> context = contextinfo :: by_id ( $this -> r -> context_id ) -> context ;
}
catch ( \dml_missing_record_exception $x ){
throw new \InvalidArgumentException ( " Context { $this -> r -> context_id } not available " ); // Just throw it up again. catch is included here to make sure we know it throws this exception
}
}
return $this -> context ;
}
public static function simple_structure ( $value = VALUE_REQUIRED ){
return new \external_single_structure ([
" id " => new \external_value ( PARAM_INT , 'id of studyplan' ),
" name " => new \external_value ( PARAM_TEXT , 'name of studyplan' ),
" shortname " => new \external_value ( PARAM_TEXT , 'shortname of studyplan' ),
2023-08-09 12:20:05 +02:00
" idnumber " => new \external_value ( PARAM_TEXT , 'idnumber of curriculum' ),
2023-05-17 21:19:14 +02:00
" context_id " => new \external_value ( PARAM_INT , 'context_id of studyplan' ),
" description " => new \external_value ( PARAM_TEXT , 'description of studyplan' ),
" aggregation " => new \external_value ( PARAM_TEXT , 'selected aggregator' ),
" aggregation_config " => new \external_value ( PARAM_TEXT , 'config string for aggregator' ),
" aggregation_info " => aggregator :: basic_structure (),
2023-07-27 12:28:04 +02:00
" pages " => new \external_multiple_structure ( studyplanpage :: simple_structure (), 'pages' ),
2023-05-17 21:19:14 +02:00
], 'Basic studyplan info' , $value );
}
public function simple_model (){
2023-07-27 12:28:04 +02:00
$pages = [];
foreach ( $this -> pages () as $p ){
$pages [] = $p -> simple_model ();
}
2023-05-17 21:19:14 +02:00
return [
'id' => $this -> r -> id ,
'name' => $this -> r -> name ,
'shortname' => $this -> r -> shortname ,
2023-08-09 12:20:05 +02:00
'idnumber' => $this -> r -> idnumber ,
2023-05-17 21:19:14 +02:00
'context_id' => $this -> context () -> id ,
'description' => $this -> r -> description ,
2023-07-27 12:28:04 +02:00
'aggregation' => $this -> r -> aggregation ,
'aggregation_config' => $this -> aggregator -> config_string (),
2023-05-17 21:19:14 +02:00
'aggregation_info' => $this -> aggregator -> basic_model (),
2023-07-27 12:28:04 +02:00
'pages' => $pages ,
2023-05-17 21:19:14 +02:00
];
}
public static function editor_structure ( $value = VALUE_REQUIRED ){
return new \external_single_structure ([
" id " => new \external_value ( PARAM_INT , 'id of studyplan' ),
" name " => new \external_value ( PARAM_TEXT , 'name of studyplan' ),
" shortname " => new \external_value ( PARAM_TEXT , 'shortname of studyplan' ),
2023-08-09 12:20:05 +02:00
" idnumber " => new \external_value ( PARAM_TEXT , 'idnumber of curriculum' ),
2023-05-17 21:19:14 +02:00
" description " => new \external_value ( PARAM_TEXT , 'description of studyplan' ),
" context_id " => new \external_value ( PARAM_INT , 'context_id of studyplan' ),
" aggregation " => new \external_value ( PARAM_TEXT , 'selected aggregator' ),
" aggregation_config " => new \external_value ( PARAM_TEXT , 'config string for aggregator' ),
" aggregation_info " => aggregator :: basic_structure (),
2023-07-23 16:25:08 +02:00
" pages " => new \external_multiple_structure ( studyplanpage :: editor_structure ()),
2023-05-17 21:19:14 +02:00
" advanced " => new \external_single_structure ([
" force_scales " => new \external_single_structure ([
" scales " => new \external_multiple_structure ( new \external_single_structure ([
" id " => new \external_value ( PARAM_INT , 'id of scale' ),
" name " => new \external_value ( PARAM_TEXT , 'name of scale' ),
])),
], " Scale forcing on stuff " , VALUE_OPTIONAL ),
], " Advanced features available " , VALUE_OPTIONAL ),
], 'Studyplan full structure' , $value );
}
public function editor_model (){
global $DB ;
$model = [
'id' => $this -> r -> id ,
'name' => $this -> r -> name ,
'shortname' => $this -> r -> shortname ,
2023-08-09 09:48:06 +02:00
'idnumber' => $this -> r -> idnumber ,
2023-08-09 12:20:05 +02:00
'description' => $this -> r -> description ,
2023-05-17 21:19:14 +02:00
'context_id' => $this -> context () -> id ,
" aggregation " => $this -> r -> aggregation ,
" aggregation_config " => $this -> aggregator -> config_string (),
2023-07-23 16:25:08 +02:00
'aggregation_info' => $this -> aggregator -> basic_model (),
'pages' => [],
2023-05-17 21:19:14 +02:00
];
2023-07-23 16:25:08 +02:00
foreach ( $this -> pages () as $p )
2023-05-17 21:19:14 +02:00
{
2023-07-23 16:25:08 +02:00
$model [ 'pages' ][] = $p -> editor_model ();
2023-05-17 21:19:14 +02:00
}
if ( has_capability ( 'local/treestudyplan:forcescales' , \context_system :: instance ())){
if ( ! array_key_exists ( 'advanced' , $model )){
// Create advanced node if it does not exist
$model [ 'advanced' ] = [];
}
// get a list of available scales
$scales = array_map ( function ( $scale ){
return [ " id " => $scale -> id , " name " => $scale -> name ,];
}, \grade_scale :: fetch_all ( array ( 'courseid' => 0 )) ) ;
$model [ 'advanced' ][ 'force_scales' ] = [
'scales' => $scales ,
];
}
return $model ;
}
2023-08-07 23:07:59 +02:00
public static function add ( $fields , $bare = false ){
2023-05-17 21:19:14 +02:00
global $CFG , $DB ;
2023-08-09 09:48:06 +02:00
$addable = [ 'name' , 'shortname' , 'description' , 'idnumber' , 'context_id' , 'aggregation' , 'aggregation_config' ];
2023-05-17 21:19:14 +02:00
$info = [ 'enddate' => null ];
foreach ( $addable as $f ){
if ( array_key_exists ( $f , $fields )){
$info [ $f ] = $fields [ $f ];
}
}
$id = $DB -> insert_record ( self :: TABLE , $info );
2023-07-23 16:47:02 +02:00
$plan = self :: findById ( $id ); // make sure the new studyplan is immediately cached
// Start temporary skräpp code
// Add a single page and copy the names.This keeps the data sane until the upgrade to
// real page management is done
2023-08-07 23:07:59 +02:00
// On import, adding an empty page messes things up for now, so we have an option to skip this....
2023-07-23 16:47:02 +02:00
// TODO: Remove this when proper page management is implemented
2023-08-07 23:07:59 +02:00
if ( ! $bare ){
$pageaddable = [ 'name' , 'shortname' , 'description' ,];
$pageinfo = [ 'studyplan_id' => $id ];
foreach ( $pageaddable as $f ){
if ( array_key_exists ( $f , $fields )){
if ( $f == " name " ){
$pageinfo [ " fullname " ] = $fields [ $f ];
} else {
$pageinfo [ $f ] = $fields [ $f ];
}
2023-07-23 16:47:02 +02:00
}
}
2023-08-07 23:07:59 +02:00
$page = studyplanpage :: add ( $pageinfo );
$plan -> page_cache = [ $page ];
2023-07-23 16:47:02 +02:00
}
// End temporary skräpp code
return $plan ;
2023-05-17 21:19:14 +02:00
}
public function edit ( $fields ){
global $DB ;
2023-08-09 09:48:06 +02:00
$editable = [ 'name' , 'shortname' , 'description' , 'idnumber' , 'context_id' , 'periods' , 'startdate' , 'enddate' , 'aggregation' , 'aggregation_config' ];
2023-05-17 21:19:14 +02:00
$info = [ 'id' => $this -> id ,];
foreach ( $editable as $f ){
if ( array_key_exists ( $f , $fields )){
$info [ $f ] = $fields [ $f ];
}
}
$DB -> update_record ( self :: TABLE , $info );
//reload record after edit
$this -> r = $DB -> get_record ( self :: TABLE ,[ 'id' => $this -> id ], " * " , MUST_EXIST );
//reload the context...
$this -> context = null ;
$this -> context ();
// reload aggregator
$this -> aggregator = aggregator :: createOrDefault ( $this -> r -> aggregation , $this -> r -> aggregation_config );
2023-07-23 16:47:02 +02:00
// Start temporary skräpp code
// TODO: Until proper page editing is implemented, copy data from studyplan to it's first page
// This keeps the data sane until the upgrade is done.
if ( count ( $this -> pages ()) == 1 ){
// update the info to the page as well
$page = $this -> pages ()[ 0 ];
2023-08-07 23:07:59 +02:00
$pageeditable = [ 'name' , 'shortname' , 'description' ];
2023-07-23 16:47:02 +02:00
$pageinfo = [];
foreach ( $pageeditable as $f ){
if ( array_key_exists ( $f , $fields )){
if ( $f == " name " ){
$pageinfo [ " fullname " ] = $fields [ $f ];
} else {
$pageinfo [ $f ] = $fields [ $f ];
}
}
}
$page -> edit ( $pageinfo );
}
// End temporary skräpp code
2023-05-17 21:19:14 +02:00
return $this ;
}
public function delete ( $force = false ){
global $DB ;
if ( $force ){
2023-07-23 16:25:08 +02:00
$children = studyplanpage :: find_studyplan_children ( $this );
2023-05-17 21:19:14 +02:00
foreach ( $children as $c ){
$c -> delete ( $force );
}
}
2023-07-23 16:25:08 +02:00
if ( $DB -> count_records ( 'local_treestudyplan_page' ,[ 'studyplan_id' => $this -> id ]) > 0 ){
return success :: fail ( 'cannot delete studyplan that still has pages' );
2023-05-17 21:19:14 +02:00
}
else
{
$DB -> delete_records ( 'local_treestudyplan' , [ 'id' => $this -> id ]);
return success :: success ();
}
}
2023-05-19 16:45:15 +02:00
public static function find_all ( $contextid =- 1 ){
2023-05-17 21:19:14 +02:00
global $DB , $USER ;
$list = [];
2023-05-19 16:45:15 +02:00
if ( $contextid <= 0 ){
$ids = $DB -> get_fieldset_select ( self :: TABLE , " id " , " " );
2023-05-17 21:19:14 +02:00
}
2023-05-19 16:45:15 +02:00
else {
if ( $contextid == 1 ){
$contextid = 1 ;
$where = " context_id <= :contextid OR context_id IS NULL " ;
} else {
$where = " context_id = :contextid " ;
}
$ids = $DB -> get_fieldset_select ( self :: TABLE , " id " , $where ,[ " contextid " => $contextid ]);
}
2023-05-17 21:19:14 +02:00
foreach ( $ids as $id )
{
$list [] = studyplan :: findById ( $id );
}
return $list ;
}
public static function find_by_shortname ( $shortname , $contextid = 0 ) : array {
global $DB ;
$list = [];
$where = " shortname = :shortname AND context_id = :contextid " ;
if ( $contextid == 0 ){
$where .= " OR context_id IS NULL " ;
}
$ids = $DB -> get_fieldset_select ( self :: TABLE , " id " , $where ,[ " shortname " => $shortname , " contextid " => $contextid ]);
foreach ( $ids as $id )
{
$list [] = studyplan :: findById ( $id );
}
return $list ;
}
public static function find_for_user ( $userid )
{
global $DB ;
$sql = " SELECT s.id FROM { local_treestudyplan} s
INNER JOIN { local_treestudyplan_cohort } j ON j . studyplan_id = s . id
INNER JOIN { cohort_members } cm ON j . cohort_id = cm . cohortid
WHERE cm . userid = : userid " ;
$cohort_plan_ids = $DB -> get_fieldset_sql ( $sql , [ 'userid' => $userid ]);
$sql = " SELECT s.id FROM { local_treestudyplan} s
INNER JOIN { local_treestudyplan_user } j ON j . studyplan_id = s . id
WHERE j . user_id = : userid " ;
$user_plan_ids = $DB -> get_fieldset_sql ( $sql , [ 'userid' => $userid ]);
$plans = [];
foreach ( $cohort_plan_ids as $id ) {
$plans [ $id ] = self :: findById ( $id );
}
foreach ( $user_plan_ids as $id ) {
if ( ! array_key_exists ( $id , $plans )){
$plans [ $id ] = self :: findById ( $id );
}
}
return $plans ;
}
static public function exist_for_user ( $userid )
{
global $DB ;
$count = 0 ;
$sql = " SELECT s.* FROM { local_treestudyplan} s
INNER JOIN { local_treestudyplan_cohort } j ON j . studyplan_id = s . id
INNER JOIN { cohort_members } cm ON j . cohort_id = cm . cohortid
WHERE cm . userid = : userid " ;
$count += $DB -> count_records_sql ( $sql , [ 'userid' => $userid ]);
$sql = " SELECT s.* FROM { local_treestudyplan} s
INNER JOIN { local_treestudyplan_user } j ON j . studyplan_id = s . id
WHERE j . user_id = : userid " ;
$count += $DB -> count_records_sql ( $sql , [ 'userid' => $userid ]);
return ( $count > 0 );
}
/**
* Retrieve the users linked to this studyplan .
* @ return array of User objects
*/
public function find_linked_users (){
global $DB ;
$users = [];
$uids = $this -> find_linked_userids ();
foreach ( $uids as $uid ){
$users [] = $DB -> get_record ( " user " ,[ " id " => $uid ]);
}
return $users ;
}
/**
* Retrieve the user id ' s of the users linked to this studyplan .
* @ return array of int ( User Id )
*/
2023-06-16 23:12:17 +02:00
public function find_linked_userids () : array {
2023-05-17 21:19:14 +02:00
global $DB ;
2023-06-16 23:12:17 +02:00
if ( $this -> linked_userids === null ){
$uids = [];
// First get directly linked userids
$sql = " SELECT j.user_id FROM { local_treestudyplan_user} j
WHERE j . studyplan_id = : planid " ;
$ulist = $DB -> get_fieldset_sql ( $sql , [ 'planid' => $this -> id ]);
2023-05-17 21:19:14 +02:00
2023-06-16 23:12:17 +02:00
$uids = array_merge ( $uids , $ulist );
foreach ( $ulist as $uid ){
$users [] = $DB -> get_record ( " user " ,[ " id " => $uid ]);
}
2023-05-17 21:19:14 +02:00
2023-06-16 23:12:17 +02:00
// Next het users linked though cohort
$sql = " SELECT cm.userid FROM { local_treestudyplan_cohort} j
INNER JOIN { cohort_members } cm ON j . cohort_id = cm . cohortid
WHERE j . studyplan_id = : planid " ;
$ulist = $DB -> get_fieldset_sql ( $sql , [ 'planid' => $this -> id ]);
2023-05-17 21:19:14 +02:00
2023-06-16 23:12:17 +02:00
$uids = array_merge ( $uids , $ulist );
2023-05-17 21:19:14 +02:00
2023-06-16 23:12:17 +02:00
$this -> linked_userids = array_unique ( $uids );
}
return $this -> linked_userids ;
2023-05-17 21:19:14 +02:00
}
/** Check if this studyplan is linked to a particular user
* @ param bool | stdClass $user The userid or user record of the user
*/
public function has_linked_user ( $user ){
if ( is_int ( $user )){
$userid = $user ;
} else {
$userid = $user -> id ;
}
$uids = $this -> find_linked_userids ();
if ( in_array ( $userid , $uids )){
return true ;
} else {
return false ;
}
}
public static function user_structure ( $value = VALUE_REQUIRED ){
return new \external_single_structure ([
" id " => new \external_value ( PARAM_INT , 'id of studyplan' ),
" name " => new \external_value ( PARAM_TEXT , 'name of studyplan' ),
" shortname " => new \external_value ( PARAM_TEXT , 'shortname of studyplan' ),
" description " => new \external_value ( PARAM_TEXT , 'description of studyplan' ),
2023-08-09 09:48:06 +02:00
" idnumber " => new \external_value ( PARAM_TEXT , 'idnumber of curriculum' ),
2023-07-23 16:25:08 +02:00
" pages " => new \external_multiple_structure ( studyplanpage :: user_structure ()),
2023-05-17 21:19:14 +02:00
" aggregation_info " => aggregator :: basic_structure (),
], 'Studyplan with user info' , $value );
}
public function user_model ( $userid ){
$model = [
'id' => $this -> r -> id ,
'name' => $this -> r -> name ,
'shortname' => $this -> r -> shortname ,
'description' => $this -> r -> description ,
2023-08-09 09:48:06 +02:00
'idnumber' => $this -> r -> idnumber ,
2023-07-23 16:25:08 +02:00
'pages' => [],
2023-05-17 21:19:14 +02:00
'aggregation_info' => $this -> aggregator -> basic_model (),
];
2023-07-23 16:25:08 +02:00
foreach ( $this -> pages () as $p )
2023-05-17 21:19:14 +02:00
{
2023-07-23 16:25:08 +02:00
$model [ 'pages' ][] = $p -> user_model ( $userid );
2023-05-17 21:19:14 +02:00
}
return $model ;
}
public static function duplicate_plan ( $plan_id , $name , $shortname )
{
$ori = self :: findById ( $plan_id );
$new = $ori -> duplicate ( $name , $shortname );
return $new -> simple_model ();
}
public function duplicate ( $name , $shortname )
{
// First duplicate the studyplan structure
2023-08-07 23:07:59 +02:00
$newplan = studyplan :: add ([
2023-05-17 21:19:14 +02:00
'name' => $name ,
'shortname' => $shortname ,
'description' => $this -> r -> description ,
]);
// next, copy the studylines
2023-07-23 16:25:08 +02:00
foreach ( $this -> pages () as $p ){
2023-08-07 23:07:59 +02:00
$newchild = $p -> duplicate ( $newplan );
2023-05-17 21:19:14 +02:00
}
2023-08-07 23:07:59 +02:00
return $newplan ;
2023-05-17 21:19:14 +02:00
}
public static function export_structure ()
{
return new \external_single_structure ([
" format " => new \external_value ( PARAM_TEXT , 'format of studyplan export' ),
" content " => new \external_value ( PARAM_TEXT , 'exported studyplan content' ),
], 'Exported studyplan' );
}
public function export_plan ()
{
$model = $this -> export_model ();
$json = json_encode ([
" type " => " studyplan " ,
2023-07-23 16:25:08 +02:00
" version " => 2.0 ,
2023-05-17 21:19:14 +02:00
" studyplan " => $model
], \JSON_PRETTY_PRINT );
return [ " format " => " application/json " , " content " => $json ];
}
public function export_model ()
{
$model = [
'name' => $this -> r -> name ,
'shortname' => $this -> r -> shortname ,
'description' => $this -> r -> description ,
" aggregation " => $this -> r -> aggregation ,
" aggregation_config " => json_decode ( $this -> aggregator -> config_string ()),
'aggregation_info' => $this -> aggregator -> basic_model (),
2023-07-23 16:25:08 +02:00
'pages' => $this -> export_pages_model (),
2023-05-17 21:19:14 +02:00
];
return $model ;
}
2023-07-23 16:25:08 +02:00
public function export_pages_model ()
2023-05-17 21:19:14 +02:00
{
2023-07-23 16:25:08 +02:00
$pages = [];
foreach ( $this -> pages () as $p )
2023-05-17 21:19:14 +02:00
{
2023-07-23 16:25:08 +02:00
$pages [] = $p -> export_model ();
2023-05-17 21:19:14 +02:00
}
2023-07-23 16:25:08 +02:00
return $pages ;
2023-05-17 21:19:14 +02:00
}
2023-05-19 16:45:15 +02:00
public static function import_studyplan ( $content , $format = " application/json " , $context_id = 1 )
2023-05-17 21:19:14 +02:00
{
if ( $format != " application/json " ) { return false ;}
$content = json_decode ( $content , true );
2023-07-23 16:25:08 +02:00
if ( $content [ " type " ] == " studyplan " && $content [ " version " ] >= 2.0 ){
2023-05-17 21:19:14 +02:00
// Make sure the aggregation_config is re-encoded as json text
$content [ " studyplan " ][ " aggregation_config " ] = json_encode ( $content [ " studyplan " ][ " aggregation_config " ]);
2023-07-23 16:25:08 +02:00
// And make sure the context_id is set to the provided context for import
2023-05-19 16:45:15 +02:00
$content [ " studyplan " ][ " context_id " ] = $context_id ;
2023-07-23 16:25:08 +02:00
// Create a new plan, based on the given parameters - this is the import studyplan part
2023-08-07 23:07:59 +02:00
$plan = self :: add ( $content [ " studyplan " ], true );
2023-07-23 16:25:08 +02:00
// Now import each page
return $plan -> import_pages_model ( $content [ " studyplan " ][ " pages " ]);
2023-05-17 21:19:14 +02:00
}
else {
error_log ( " Invalid format and type: { $content [ 'type' ] } version { $content [ 'version' ] } " );
return false ;
}
}
2023-07-23 16:25:08 +02:00
public function import_pages ( $content , $format = " application/json " )
2023-05-17 21:19:14 +02:00
{
if ( $format != " application/json " ) { return false ;}
$content = json_decode ( $content , true );
2023-07-23 16:25:08 +02:00
if ( $content [ " version " ] >= 2.0 ){
if ( $content [ " type " ] == " studyplanpage " ){
// import single page from a studyplanpage (wrapped in array of one page)
return $this -> import_pages_model ([ $content [ " page " ]]);
}
else if ( $content [ " type " ] == " studyplan " ){
// Import all pages from the studyplan
return $this -> import_pages_model ( $content [ " studyplan " ][ " pages " ]);
}
2023-05-17 21:19:14 +02:00
}
else {
return false ;
}
}
2023-07-23 16:25:08 +02:00
protected function import_pages_model ( $model )
2023-05-17 21:19:14 +02:00
{
2023-07-23 16:25:08 +02:00
$this -> pages (); // make sure the page cache is initialized, since we will be adding to it.
foreach ( $model as $p ){
$p [ " studyplan_id " ] = $this -> id ();
$page = studyplanpage :: add ( $p );
$this -> page_cache [] = $page ;
2023-07-27 16:58:23 +02:00
$page -> import_periods_model ( $p [ " perioddesc " ]);
2023-07-23 16:25:08 +02:00
$page -> import_studylines_model ( $p [ " studylines " ]);
2023-05-17 21:19:14 +02:00
}
return true ;
}
2023-06-27 07:33:27 +02:00
/**
* Mark the studyplan as changed regarding courses and associated cohorts
*/
public function mark_csync_changed (){
global $DB ;
$DB -> update_record ( self :: TABLE , [ 'id' => $this -> id , " csync_flag " => 1 ]);
$this -> r -> csync_flag = 1 ; //manually set it in the cache, if something unexpected happened, an exception has already been thrown anyway
}
/**
* Clear the csync mark
*/
public function clear_csync_changed (){
global $DB ;
$DB -> update_record ( self :: TABLE , [ 'id' => $this -> id , " csync_flag " => 0 ]);
$this -> r -> csync_flag = 0 ; //manually set it in the cache, if something unexpected happened, an exception has already been thrown anyway
}
public function has_csync_changed (){
return ( $this -> r -> csync_flag > 0 ) ? true : false ;
}
2023-06-16 13:49:47 +02:00
/**
* See if the specified course id is linked in this studyplan
*/
public function course_linked ( $courseid ){
global $DB ;
$sql = " SELECT COUNT(i.id)
FROM { local_treestudyplan }
INNER JOIN { local_treestudyplan_line } l ON p . id = l . studyplan_id
INNER JOIN { local_treestudyplan_item } i ON l . id = i . line_id
WHERE p . id = : planid
AND i . course_id = : courseid " ;
$count = $DB -> get_field_sql ( $sql ,[ " courseid " => $courseid , " planid " => $this -> id ]);
return ( $count > 0 ) ? true : false ;
}
2023-06-16 23:12:17 +02:00
/**
* List the course id is linked in this studyplan
* Used for cohort enrolment cascading
*/
public function get_linked_course_ids (){
global $DB ;
$sql = " SELECT i.course_id
2023-06-19 22:48:33 +02:00
FROM { local_treestudyplan } p
2023-08-07 22:20:45 +02:00
INNER JOIN { local_treestudyplan_page } pg ON p . id = pg . studyplan_id
INNER JOIN { local_treestudyplan_line } l ON pg . id = l . page_id
2023-06-16 23:12:17 +02:00
INNER JOIN { local_treestudyplan_item } i ON l . id = i . line_id
2023-06-19 22:48:33 +02:00
WHERE p . id = : studyplan_id AND i . type = : itemtype " ;
$fields = $DB -> get_fieldset_sql ( $sql ,[ " studyplan_id " => $this -> id , " itemtype " => studyitem :: COURSE ]);
return $fields ;
}
2023-06-16 23:12:17 +02:00
2023-06-19 22:48:33 +02:00
/**
* List the cohort id ' s associated with this studyplan
*/
public function get_linked_cohort_ids (){
global $CFG , $DB ;
$sql = " SELECT DISTINCT j.cohort_id FROM { local_treestudyplan_cohort} j
WHERE j . studyplan_id = : studyplan_id " ;
2023-06-26 21:44:31 +02:00
$fields = $DB -> get_fieldset_sql ( $sql , [ 'studyplan_id' => $this -> id ]);
2023-06-16 23:12:17 +02:00
return $fields ;
}
2023-06-30 12:14:11 +02:00
/**
* List the user id ' s explicitly associated with this studyplan
*/
public function get_linked_user_ids (){
global $CFG , $DB ;
2023-06-19 22:48:33 +02:00
2023-06-30 12:14:11 +02:00
$sql = " SELECT DISTINCT j.user_id FROM { local_treestudyplan_user} j
WHERE j . studyplan_id = : studyplan_id " ;
$fields = $DB -> get_fieldset_sql ( $sql , [ 'studyplan_id' => $this -> id ]);
return $fields ;
}
2023-06-16 13:49:47 +02:00
/**
* See if the specified course id is linked in this studyplan
*/
public function badge_linked ( $badgeid ){
global $DB ;
$sql = " SELECT COUNT(i.id)
FROM { local_treestudyplan }
INNER JOIN { local_treestudyplan_line } l ON p . id = l . studyplan_id
INNER JOIN { local_treestudyplan_item } i ON l . id = i . line_id
WHERE p . id = : planid
AND i . badge_id = : badgeid " ;
$count = $DB -> get_field_sql ( $sql ,[ " badgeid " => $badgeid , " planid " => $this -> id ]);
return ( $count > 0 ) ? true : false ;
}
2023-05-17 21:19:14 +02:00
}