Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions classes/local/cms/campus_management.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

namespace local_lsf_unification\local\cms;

use moodle_url;

/**
* Interface to campus management systems (CMS).
*
* @package local_lsf_unification
* @copyright 2026 Daniel Meißner <daniel.meissner@uni-muenster.de>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
interface campus_management {
/**
* Query the CMS for a list of courses of a given teacher.
*
* @param object $teacher The user record of the teacher
* @return array A list of course objects
*/
public function get_courses_of_teacher(object $teacher): array;

/**
* Query the CMS for all users that should be enrolled in the course with their respective role
* @param object $course
* @return array
*/
public function get_users_of_course(object $course): array;

/**
* Add the link to the new existing moodle course to the course page in the cms.
* @param object $course
* @param moodle_url $url
* @return void
*/
public function set_moodle_link(object $course, moodle_url $url): void;

/**
* Get all single dates on which the course occurs. Can be used to import dates in the moodle calendar.
* @param object $course
* @return array
*/
public function get_course_dates(object $course): array;

/**
* Return all teachers registered in the cms that have courses in the configured timespan. Can be used to search for
* teachers when doing a course request.
* @return array
*/
public function get_teachers(): array;
}
139 changes: 139 additions & 0 deletions classes/local/cms/his_lsf.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

namespace local_lsf_unification\local\cms;

use DateTimeImmutable;
use DateTimeZone;
use Google\Service\Classroom\Teacher;
use local_lsf_unification\local\models\cms;
use local_lsf_unification\local\models\course;
use moodle_url;
use PDO;
use stdClass;

/**
* Connection to the LSF database.
*
* @package local_lsf_unification
* @copyright 2026 Daniel Meißner <daniel.meissner@uni-muenster.de>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class his_lsf implements campus_management {
/** @var PDO The database connection to LSF */
private PDO $db;

/**
* Constructor.
* @param stdClass $config The plugin configuration
*/
public function __construct(stdClass $config) {
$this->db = new PDO($this->connection_string_from($config));
}

/**
* Returns connection string.
* @param stdClass $config
* @return string
*/
private function connection_string_from(stdClass $config): string {
$options = ['host' => $config->dbhost, 'port' => $config->dbport, 'user' => $config->dbuser, 'dbname' => $config->dbname];

if (!empty($config->dbusessl)) {
$options['sslmode'] = 'verify-full';
$options['sslrootcert'] = $config->dbsslrootcert;
$options['sslcert'] = $config->dbsslcert;
$options['sslkey'] = $config->dbsslkey;
} else {
$options['password'] = $config->dbpass;
}

$parts = [];
foreach ($options as $key => $val) {
$escaped = addcslashes((string) $val, "\\'");
$parts[] = "$key='$escaped'";
}
return 'pgsql:' . implode(' ', $parts);
}

#[\Override]
public function get_courses_of_teacher(object $teacher): array {
$maxage = get_config('local_lsf_unification', 'max_import_age');
$rows = $this->db->query(
"SELECT lv.veranstid, lv.veranstnr, lv.titel, lv.semestertxt, lv.urlveranst, lv.veranstaltungsart, lv.zeitstempel,
COALESCE(lvk.description, '') AS description
FROM learnweb_veranstaltung lv
JOIN learnweb_personal_veranst lpv ON lpv.veranstid = lv.veranstid
JOIN learnweb_personal lp ON lp.pid = lpv.pid
LEFT JOIN LATERAL (
SELECT string_agg(k.kommentar, '<br>' ORDER BY k.sprache) AS description
FROM learnweb_veranst_kommentar k
WHERE k.veranstid = lv.veranstid
) lvk ON true
WHERE lp.login = '{$teacher->username}'
AND (CURRENT_DATE - CAST(lv.zeitstempel AS date)) < '{$maxage}'
ORDER BY semester, titel;",
PDO::FETCH_OBJ
);

return array_map(
fn($row) => new course(
cms: cms::LSF->value,
instance: (int) $row->veranstid,
title: $row->titel,
shorttitle: $row->veranstaltungsart,
description: $row->description,
teacher: $teacher->username,
semester: $row->semestertxt,
created: (new DateTimeImmutable($row->zeitstempel, new DateTimeZone('Europe/Berlin')))->getTimestamp(),
url: $row->urlveranst
),
$rows->fetchAll()
);
}

#[\Override]
public function get_users_of_course(object $course): array {
return [];
}

#[\Override]
public function set_moodle_link(object $course, moodle_url $url): void {
return;
}

#[\Override]
public function get_course_dates(object $course): array {
return [];
}

#[\Override]
public function get_teachers(): array {
$maxage = get_config('local_lsf_unification', 'max_import_age');
$rows = $this->db->query(
"SELECT DISTINCT lp.zivk, lp.vorname, lp.nachname
FROM learnweb_personal lp
JOIN learnweb_personal_veranst lpv ON lpv.pid = lp.pid
JOIN learnweb_veranstaltung lv ON lv.veranstid = lpv.veranstid
WHERE (CURRENT_DATE - CAST(lv.zeitstempel AS date)) < '{$maxage}';",
PDO::FETCH_OBJ
);
return array_map(
fn($row) => (object) ['username' => $row->zivk, 'firstname' => $row->vorname, 'lastname' => $row->nachname],
$rows->fetchAll()
);
}
}
53 changes: 53 additions & 0 deletions classes/local/cms/sap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

namespace local_lsf_unification\local\cms;

use moodle_url;

/**
* Connection to the SAP database.
*
* @package local_lsf_unification
* @copyright 2026 Tamaro Walter <daniel.meissner@uni-muenster.de>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class sap implements campus_management {
#[\Override]
public function get_courses_of_teacher(object $teacher): array {
return [];
}

#[\Override]
public function get_users_of_course(object $course): array {
return [];
}

#[\Override]
public function set_moodle_link(object $course, moodle_url $url): void {
return;
}

#[\Override]
public function get_course_dates(object $course): array {
return [];
}

#[\Override]
public function get_teachers(): array {
return [];
}
}
113 changes: 113 additions & 0 deletions classes/local/dto/course_dto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

namespace local_lsf_unification\local\dto;

use local_lsf_unification\local\models\course;
use moodle_url;

/**
* DTO for a course that gets shown in the user dashboard.
*
* @package local_lsf_unification
* @copyright 2026 Tamaro Walter
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_dto {
/**
* Constructor.
*/
public function __construct(
/** @var int unique id of the abstracted course */
public readonly int $id,
/** @var string cms the course originates from */
public readonly string $cms,
/** @var int id of the course in the cms */
public readonly int $cmsinstance,
/** @var string url to the course in the cms */
public readonly string $cmsurl,
/** @var string title of the course */
public readonly string $title,
/** @var string short title of the course */
public readonly string $shorttitle,
/** @var string description of the course */
public readonly string $description,
/** @var string user name of the main responsible teacher */
public readonly string $teacher,
/** @var string semester the course belongs to */
public readonly string $semester,
/** @var int timestamp of when the course was created in the cms */
public readonly int $created,
/** @var int abstract course id */
public readonly int $courseid,
/** @var int moodle course id, 0 when not yet created */
public readonly int $moodleid = 0,
/** @var int request state of the user, if there is no request then the state is 0 */
public readonly int $requeststate = 0,
/** @var string url to the course in moodle */
public readonly string $moodleurl = '',
) {
}

/**
* Builds a course dto from a course entity.
*
* @param course $course
* @return self
*/
public static function from_course(course $course, int $moodleid = 0, int $requeststate = 0): self {
return new self(
$course->id,
$course->cms,
$course->instance,
$course->url,
$course->title,
$course->shorttitle,
$course->description,
$course->teacher,
$course->semester,
$course->created,
$course->id,
$moodleid,
$requeststate,
$moodleid != 0 ? (new moodle_url('/course/view.php', ['id' => $moodleid]))->out() : '',
);
}

/**
* Returns the wire format (JSON shape) of this dashboard course.
*
* @return array
*/
public function to_array(): array {
return [
'id' => $this->id,
'cms' => $this->cms,
'cmsinstance' => $this->cmsinstance,
'cmsurl' => $this->cmsurl,
'title' => $this->title,
'shorttitle' => $this->shorttitle,
'description' => $this->description,
'teacher' => $this->teacher,
'semester' => $this->semester,
'created' => $this->created,
'courseid' => $this->courseid,
'moodleid' => $this->moodleid,
'requeststate' => $this->requeststate,
'moodleurl' => $this->moodleurl,
];
}
}
Loading