Compare commits

..
Author SHA1 Message Date
adisposkofh e6db3bfa8a merged master into 2026-09-09 14:13:20 +02:00
adisposkofh 254ea1a2b5 removed redundant variable previously used for debugging 2026-09-09 14:09:30 +02:00
adisposkofh e8e9bc73ad reworked old-to-new coodle redirect to not rely on old coodle tables 2026-09-09 14:07:05 +02:00
adisposkofh 883fbaee76 removed use of retval from freebusy controller 2026-08-11 15:10:37 +02:00
adisposkofh e871e30a09 removed direct use of retval in all coodle-related models 2026-08-11 15:00:18 +02:00
adisposkofh 6f25a2b955 removed direct use of retval from all CoodleSurvey_model methods 2026-08-11 14:06:28 +02:00
adisposkofh f79c1dc090 removed direct use of retval from CoodleSurvey_model->getSurvey 2026-08-11 13:56:28 +02:00
adisposkofh ec23bffcbc minor coodle fix 2026-08-11 13:50:32 +02:00
adisposkofh 803afde542 reworked coodle-related email sending to avoid delays on user's end 2026-08-11 13:34:27 +02:00
adisposkofh efa04c0b68 Merge branch 'master' into feature/77174-nu-coodle 2026-08-06 13:40:39 +02:00
adisposkofh 6ae3fcd462 fixed 'new tab' links in coodle 2026-08-06 13:31:35 +02:00
adisposkofh 9be6708acc coodle data migration script 2026-08-05 17:22:15 +02:00
adisposkofh 8cd7241d81 modified coodle data migration 2026-08-03 16:35:59 +02:00
adisposkofh fa0422f577 modified coodle data migration 2026-08-03 16:34:38 +02:00
adisposkofh 0b07179986 coodle data migration 2026-08-03 16:06:29 +02:00
adisposkofh ddd54542ce redirecting old coodle urls to new coodle 2026-07-31 14:44:13 +02:00
adisposkofh 2af177ae87 reworked coodle external participants 2026-07-31 13:23:09 +02:00
adisposkofh 0c1abacebe fixed coodle bug, resetting cached freebusies when switching surveys 2026-07-31 11:33:02 +02:00
adisposkofh 30fda5b633 minor fix in coodle active surveys table config 2026-07-29 12:08:28 +02:00
adisposkofh e3377923ea minor mod to coodle participant search config 2026-07-28 10:35:19 +02:00
adisposkofh 0db5451c8c coodle, filtering existing participants from participant search results 2026-07-28 10:29:34 +02:00
adisposkofh 9c3651d97d Merge branch 'master' into feature/77174-nu-coodle 2026-07-27 15:52:35 +02:00
adisposkofh 74ee8fbb35 minor rename 2026-07-27 15:48:48 +02:00
adisposkofh f1ca657226 reimplemented coodle participant search with search library 2026-07-27 15:36:17 +02:00
adisposkofh 40a6acb61e coodle various minor fixes 2026-07-27 12:14:45 +02:00
adisposkofh bfc8da632a fixed use of conditionals with falsy empty arrays in coodle 2026-07-27 09:57:10 +02:00
adisposkofh a51d6ac4ea removed redundant coodle response meta 2026-07-27 09:51:44 +02:00
adisposkofh 92d191dc5d minor coodle fix 2026-07-27 09:46:25 +02:00
adisposkofh ae09eb712e removed obsolete import 2026-07-27 09:33:16 +02:00
adisposkofh d769e9db04 implemented pagination in coodle survey tables 2026-07-24 14:22:35 +02:00
adisposkofh 88304ff5a6 implemented localization in coodle 2026-07-24 14:04:56 +02:00
adisposkofh caa598e821 coodle external page appearance 2026-07-24 12:02:38 +02:00
adisposkofh 996e6b67f7 removed coodle ical redundant console logs 2026-07-24 10:13:01 +02:00
adisposkofh b8800af8fb implemented coodle external voting page 2026-07-23 16:06:47 +02:00
adisposkofh f0af0ba733 removed redundant route 2026-07-22 17:03:27 +02:00
adisposkofh 8ed61bd063 minor mod 2026-07-22 16:12:03 +02:00
adisposkofh cb985c3c25 implemented coodle ical comp and corresponding endpoint 2026-07-22 16:03:29 +02:00
adisposkofh d89ea5947e minor mod to coodle voting table appearance (grouping dates in top row) 2026-07-22 11:16:41 +02:00
adisposkofh e110a756c2 removed redundant coodle-related response meta 2026-07-22 11:14:34 +02:00
adisposkofh a4eb996f22 replaced coodle calendar timeslot card date and time inputs with vuedatepicker 2026-07-21 19:30:22 +02:00
adisposkofh ffa02a3c3d implemented basic logic for coodle external participants 2026-07-21 18:40:56 +02:00
adisposkofh 42a67187a4 implemented ui for adding external participants to coodle survey 2026-07-20 17:15:58 +02:00
adisposkofh dbbac6d6d3 added missing coodle localization 2026-07-20 15:44:53 +02:00
adisposkofh 913e623ba5 minor appearance rework of coodle room selection 2026-07-20 15:43:55 +02:00
adisposkofh 6021c824ef minor appearance rework of coodle room selection 2026-07-20 14:47:51 +02:00
adisposkofh 05374517f4 added filter for available rooms in coodle final selection 2026-07-20 14:39:37 +02:00
adisposkofh 48e35e4c05 added missing freebusy explainer localization 2026-07-20 14:21:24 +02:00
adisposkofh 54a57880a9 Merge branch 'master' into feature/77174-nu-coodle 2026-07-20 13:57:49 +02:00
adisposkofh 1dfc8b6a28 added organizer to coodle completed survey ics calendar invite 2026-07-20 13:47:14 +02:00
adisposkofh e7fde9bace using utc tz in coodle completed survey ics calendar invite 2026-07-20 13:32:04 +02:00
adisposkofh 686bfe3d22 coodle freebusy ics endpoint 2026-07-20 13:14:34 +02:00
adisposkofh 6eac071ef8 parsing internal freebusy (timetable and absences) for coodle 2026-07-17 16:07:10 +02:00
adisposkofh 0a9775cd83 minor mod to coodle participants formatting 2026-07-17 15:20:48 +02:00
adisposkofh 2cd5682536 parsing coodle freebusy calendars 2026-07-17 15:13:16 +02:00
adisposkofh c066b1979f displaying google-type freebusy in coodle calendar 2026-07-17 12:04:50 +02:00
adisposkofh cc505a88ab fixed issue with coodle survey timeslot/participant update 2026-07-16 15:17:19 +02:00
adisposkofh 51f9701322 removed redundant import from coodle survey api 2026-07-16 11:56:31 +02:00
adisposkofh d5c18412de fixed idempotency issue in freebusy form submission 2026-07-16 11:53:50 +02:00
adisposkofh abe0c88ebc fixed bug with querying coodle surveys 2026-07-16 11:17:36 +02:00
adisposkofh 16a07f6c17 disabled moveable columns in coodle survey tables 2026-07-16 11:16:06 +02:00
adisposkofh 8262412c3a added missing coodle phrases 2026-07-16 10:57:42 +02:00
adisposkofh 11e45cafa1 fixed coodle survey cancellation emails 2026-07-16 10:46:02 +02:00
adisposkofh 55a6c6b207 update coodle survey form validation fix 2026-07-16 10:27:28 +02:00
adisposkofh 39fe741f51 added coodle phrases 2026-07-15 23:48:03 +02:00
adisposkofh dd95f08a51 minor coodle fixes 2026-07-15 19:55:44 +02:00
adisposkofh 78c975df50 fixed disappearing coodle tab buttons 2026-07-15 11:14:23 +02:00
adisposkofh 1a53972aa0 minor mod to coodle/freebusy validations 2026-07-15 11:05:44 +02:00
adisposkofh 6dccb559c8 added form validations to coodle/freebusy 2026-07-15 10:53:26 +02:00
adisposkofh ceb2dbc99a when completing coodle survey, no room reservations and calendar invites if past timeslot selected 2026-07-14 17:18:03 +02:00
adisposkofh ce596eed82 minor mod to parsing fetched inactive coodle surveys 2026-07-14 16:43:40 +02:00
adisposkofh b2697c301c reworked inactive coodle survey 'canceled' and 'completed' columns into single 'ended' column 2026-07-14 16:39:40 +02:00
adisposkofh 7bc20a8562 option to switch coodle calendar modes on wider screens 2026-07-14 16:19:47 +02:00
adisposkofh 359e753d13 adapted coodle calendar for day view on mobile screens 2026-07-14 15:46:42 +02:00
adisposkofh 9d6a8c5a75 creating ics files for completed coodle surveys 2026-07-14 15:33:32 +02:00
adisposkofh 6463da1679 opening coodle survey based on route query param 2026-07-14 12:08:24 +02:00
adisposkofh 5ea8ddf3b5 added quick click option to add auth user to coodle survey participants 2026-07-14 12:00:46 +02:00
adisposkofh a8079b8e91 implemented various coodle-related emails 2026-07-14 11:29:00 +02:00
adisposkofh dae2c075de creating reservation for selected coodle timeslot 2026-07-13 18:32:00 +02:00
adisposkofh 59fc627c98 coodle voting minor fix 2026-07-13 11:23:04 +02:00
adisposkofh 385b5bdfac ported room reservation functionality from cis40_2026-05_ma_rc 2026-07-13 10:08:54 +02:00
adisposkofh 519da8433f implemented room selection in coodle completion form 2026-07-10 17:36:45 +02:00
adisposkofh fa94d9e03a updated coodle calendar to match latest renderers implementation 2026-07-10 16:55:56 +02:00
adisposkofh 74b916d0c5 implemented sending coodle voting reminders 2026-07-10 16:08:01 +02:00
adisposkofh c230990f25 merged master into 2026-07-10 15:50:02 +02:00
adisposkofh 85479a3c3a implemented coodle survey completion 2026-07-10 12:07:23 +02:00
adisposkofh de6ef0ce34 implemented coodle survey cancellation 2026-07-10 10:34:22 +02:00
adisposkofh f55adfb997 replaced use of browser pop-ups with fhc alert 2026-07-10 10:15:29 +02:00
adisposkofh 7af9ad8ead implemented coodle voting endpoint 2026-07-09 16:08:59 +02:00
adisposkofh 9ccf2f6e2e coodle voting table appearance when anon participants 2026-07-09 15:22:21 +02:00
adisposkofh 7659f21538 (in)active surveys tables 2026-07-09 11:33:57 +02:00
adisposkofh 036cabf871 coodle form minor styling fix 2026-07-08 10:23:12 +02:00
adisposkofh d5e0c2750a fixed incoming survey parsing 2026-07-08 10:20:37 +02:00
adisposkofh 4bec9a6023 creating coodle survey 2026-07-07 19:08:28 +02:00
adisposkofh a395a4383c initial work on displaying freebusy schedules in coodle 2026-07-07 10:51:11 +02:00
adisposkofh ab75fa9de6 formatting freebusy types 2026-07-06 12:58:19 +02:00
adisposkofh 534d963393 modified coodle/freebusy tables 2026-07-06 11:26:37 +02:00
adisposkofh 0f45712485 implemented coodle freebusy view 2026-06-26 19:09:34 +02:00
adisposkofh edfab4a6f6 can create coodle calendar events clicking through other events: 2026-06-26 11:04:10 +02:00
adisposkofh 6242c252b6 wrapping instead of truncating coodle basic info input labels 2026-06-25 15:31:56 +02:00
adisposkofh 098fdc991c minor fix 2026-06-25 15:27:31 +02:00
adisposkofh 80f46ae7e9 reworked coodle timeslot creation 2026-06-25 15:26:00 +02:00
adisposkofh a9ffdc2457 removed autoscroll 2026-06-25 11:36:17 +02:00
adisposkofh 3915b7418c minor fix 2026-06-25 10:59:35 +02:00
adisposkofh 158ba59d5d minor fix 2026-06-25 10:59:22 +02:00
adisposkofh f6dc4b7cbc added coodle privacy settings tab 2026-06-25 10:52:14 +02:00
adisposkofh bd004fe7f6 parsing coodle participant events 2026-06-25 10:51:16 +02:00
adisposkofh 77c162c95b implemented distinct coodle participant schedule colors 2026-06-24 17:32:41 +02:00
adisposkofh 338d01e9c6 preserving coodle timeslot id if removed, then reinstated in edit form 2026-06-24 16:34:48 +02:00
adisposkofh 600816dfca minor naming change 2026-06-24 16:25:22 +02:00
adisposkofh c473f98774 coodle calendar interaction with survey edit form 2026-06-24 16:24:34 +02:00
adisposkofh f63aa02c3a code formatting and minor fixes 2026-06-24 16:02:26 +02:00
adisposkofh a01764c5e6 added coodle event modal 2026-06-24 14:36:48 +02:00
adisposkofh 1bfd24313a implemented coodle survey calendar 2026-06-24 13:56:42 +02:00
adisposkofh d8a25dc0f3 debouncing and aborting coodle participants search 2026-06-22 14:58:18 +02:00
adisposkofh 1bd306cf74 implemented debounce helper 2026-06-22 14:46:12 +02:00
adisposkofh 3a27ddc410 reworked coodle voting table appearance 2026-06-22 14:30:26 +02:00
adisposkofh 3b0e62ff15 reworked coodle survey basic info appearance 2026-06-22 14:15:43 +02:00
adisposkofh 58882d99b7 minor fix 2026-06-22 14:12:25 +02:00
adisposkofh 82950bdd21 minor fix 2026-06-22 14:12:01 +02:00
adisposkofh 0064f93676 code formatting 2026-06-22 13:47:50 +02:00
adisposkofh 758a5a5253 reworked coodle voting table appearance 2026-06-22 13:47:10 +02:00
adisposkofh 60255775c1 reworked coodle voting table appearance 2026-06-22 13:42:13 +02:00
adisposkofh 6375ccde3b implemented api endpoint to search coodle survey participants 2026-06-22 13:06:46 +02:00
adisposkofh 359b37e184 coodle survey refactoring 2026-06-19 14:35:14 +02:00
adisposkofh 1e771694d7 coodle survey edit form 2026-06-18 18:22:45 +02:00
adisposkofh 10b09bce10 coodle ui 2026-06-17 19:21:06 +02:00
adisposkofh 1faf633034 added coodle view 2026-06-15 15:16:05 +02:00
411 changed files with 12941 additions and 37414 deletions
+20 -9
View File
@@ -23,15 +23,6 @@ Events::on('loadRenderers', function ($renderers) {
);
});
Events::on('loadRenderers', function ($renderers) {
$fhc_core_renderers =& $renderers();
$fhc_core_renderers["slot_room"] = array(
'modalTitle' => APP_ROOT.'public/js/components/Cis/Renderer/Slot/roomModalTitle.js',
'modalContent' => APP_ROOT.'public/js/components/Cis/Renderer/Slot/roomModalContent.js',
'calendarEventStyles' => APP_ROOT.'public/css/Cis4/CoreCalendarEvents.css'
);
});
Events::on('loadRenderers', function ($renderers) {
$fhc_core_renderers =& $renderers();
$fhc_core_renderers["ferien"] = array(
@@ -42,5 +33,25 @@ Events::on('loadRenderers', function ($renderers) {
);
});
Events::on('loadRenderers', function ($renderers) {
$fhc_core_renderers =& $renderers();
$fhc_core_renderers["coodle"] = array(
'calendarEvent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Coodle/calendarEvent.js'),
'modalTitle' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Coodle/modalTitle.js'),
'modalContent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Coodle/modalContent.js'),
'calendarEventStyles' => APP_ROOT . 'public/css/Cis4/CoreCalendarEvents.css'
);
});
Events::on('loadRenderers', function ($renderers) {
$fhc_core_renderers =& $renderers();
$fhc_core_renderers["freeBusy"] = array(
'calendarEvent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/FreeBusy/calendarEvent.js'),
'modalTitle' => absoluteJsImportUrl('public/js/components/Cis/Renderer/FreeBusy/modalTitle.js'),
'modalContent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/FreeBusy/modalContent.js'),
'calendarEventStyles' => APP_ROOT . 'public/css/Cis4/CoreCalendarEvents.css'
);
});
-1
View File
@@ -3,4 +3,3 @@
if (! defined('BASEPATH')) exit('No direct script access allowed');
$config['infocenter_studiengang_kz'] = '10021, 10027, 10002';
$config['infocenter_qualifikationskurs_kz'] = '10002';
-64
View File
@@ -1,64 +0,0 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
// Noten die keinen Prüfungsantritt verbrauchen. Fallback-PKs; massgeblich sind die per Bezeichnung
// aufgelösten Noten (NOTEN_OHNE_ANTRITT_BEZEICHNUNGEN), da die PKs je Installation abweichen.
$config['NOTEN_OHNE_ANTRITT'] = [9, 17]; // tbl_note pk
// 'Nicht beurteilt' ist eine Altlast: formal eine Note, inhaltlich keine Leistungsfeststellung.
// Wird weiterhin häufig vergeben und darf daher keinen Antritt kosten.
$config['NOTEN_OHNE_ANTRITT_BEZEICHNUNGEN'] = ['Noch nicht eingetragen', 'entschuldigt', 'Nicht beurteilt'];
// Anrechnungsnoten: die Leistung wurde vorab anerkannt, der/die Studierende ist zwar Teil der
// Lehrveranstaltung, tritt aber zu keiner Prüfung an. Solange die ZEUGNISNOTE eine davon ist, sind
// für diese Lehrveranstaltung keine Prüfungen möglich. Auflösung wie oben über die Bezeichnung,
// die PKs sind nur Fallback.
$config['NOTEN_ANRECHNUNG_BEZEICHNUNGEN'] = ['angerechnet', 'intern angerechnet'];
$config['NOTEN_ANRECHNUNG'] = [6, 16]; // tbl_note pk
$config['NOTEN_OCCURANCE_LIMIT_MAP'] = [17 => 1]; // über alle Antritte hinweg nur ein entschuldigt
// tbl_note pk of the 'entschuldigt' note. An entschuldigt Termin is preserved as its own dated
// entry when a new pruefung of the same type is created (instead of being overwritten).
$config['NOTE_ENTSCHULDIGT'] = 17;
// The maximum number of attempts that count, the first attempt and the kommissionelle attempt
// included. null derives the number from the old flags:
// 1 (the original assessment) + TERMIN2 + TERMIN3 + KOMMPRUEF
// The examination rules permit three attempts. With TERMIN2 and KOMMPRUEF the formula gives 3.
// An installation with TERMIN3 gets 4, which is one more attempt in the same chain.
$config['CIS_GESAMTNOTE_MAX_ANTRITTE'] = null;
// The exam types that take place before a commission.
$config['PRUEFUNG_KOMMISSIONELL_TYPEN'] = ['kommPruef', 'zusKommPruef'];
// The type that the tool writes for the last attempt. The last attempt is always kommissionell.
$config['PRUEFUNG_TYP_KOMMISSIONELL'] = 'kommPruef';
// Exam types that never use an attempt. A zusKommPruef repeats a kommissionelle Prüfung that had
// a procedural fault. It stands outside the attempt chain, and the student administration enters
// it. The examination rules do not describe it.
$config['PRUEFUNG_TYPEN_OHNE_ANTRITT'] = ['zusKommPruef'];
// Spaltenaufteilung der Prüfungen in der Notentabelle:
// 'antritt' - eine Spalte je Antrittsnummer, Datum steht in der Zelle (robust bei Einzelterminen)
// 'datum' - eine Spalte je Prüfungsdatum (kompakt, wenn ganze Jahrgänge am selben Tag antreten)
// Nur die Vorgabe; im Tool umschaltbar und pro Benutzer gespeichert.
$config['CIS_GESAMTNOTE_PRUEFUNGSSPALTEN'] = 'antritt';
// Bei der Notenübernahme durch die Assistenz den ersten Antritt als eigene Prüfung anlegen.
$config['CIS_GESAMTNOTE_ERSTANTRITT_BEI_UEBERNAHME'] = true;
// availability of the two Benotungstool import flows. When both are true they are shown as
// separate buttons/dialogs.
$config['CIS_GESAMTNOTE_PRUEFUNGSIMPORT'] = true; // dated import that creates a pruefung per row
$config['CIS_GESAMTNOTE_NOTENIMPORT'] = false; // classic note-only import (uid + note, no date)
// Noteneintragungsfrist (Prüfungsordnung §1): grade/pruefung entry is only permitted up to this
// deadline. The month/day below is applied to the studiensemester's year:
// Sommersemester (SSyyyy) -> deadline in the SAME calendar year (default 15th November)
// Wintersemester (WSyyyy) -> deadline in the FOLLOWING calendar year (default 15th May)
$config['CIS_GESAMTNOTE_NOTENEINTRAGUNGSFRIST'] = false; // switch to use the window enforcement
$config['NOTENEINTRAGUNGSFRIST_SS'] = ['month' => 11, 'day' => 15]; // Sommersemester deadline (same year)
$config['NOTENEINTRAGUNGSFRIST_WS'] = ['month' => 5, 'day' => 15]; // Wintersemester deadline (following year)
+6 -23
View File
@@ -61,29 +61,18 @@ $route['api/v1/organisation/[O|o]rganisationseinheit/(:any)'] = 'api/v1/organisa
$route['api/v1/ressource/[B|b]etriebsmittelperson/(:any)'] = 'api/v1/ressource/betriebsmittelperson2/$1';
$route['api/v1/system/[S|s]prache/(:any)'] = 'api/v1/system/sprache2/$1';
// Legacy CMS news routes
$route['api/frontend/v1/Cms/getNewsItem/(:num)'] = 'api/frontend/v1/NewsAdministrationAPI/getNewsItem/$1';
$route['api/frontend/v1/Cms/storeNewsItem'] = 'api/frontend/v1/NewsAdministrationAPI/storeNewsItem';
$route['api/frontend/v1/Cms/updateNewsItem/(:num)'] = 'api/frontend/v1/NewsAdministrationAPI/updateNewsItem/$1';
$route['api/frontend/v1/Cms/deleteNewsItem/(:num)'] = 'api/frontend/v1/NewsAdministrationAPI/deleteNewsItem/$1';
// Keep legacy uppercase URLs refreshable while using the canonical controller method casing
$route['CisVue/Cms/NewsAdministration'] = 'CisVue/Cms/newsAdministration';
$route['Cis/LvPlan/.*'] = 'Cis/LvPlan/index/$1';
$route['Cis/MyLvPlan/.*'] = 'Cis/MyLvPlan/index/$1';
$route['Cis/MyLv/.*'] = 'Cis/MyLv/index/$1';
$route['Cis/OtherLvPlan/.*'] = 'Cis/OtherLvPlan/index/$1';
//Route for LV Plan Stg/Semester/Verband/Gruppe
$route['Cis/StgOrgLvPlan/.*'] = 'Cis/StgOrgLvPlan/index/$1';
$route['Cis/Benotungstool/.*'] = 'Cis/Benotungstool/index/$1';
$route['Cis/MyReservation'] = 'Cis/MyReservation/index/$1';
$route['Cis/CoodleExternal/(:any)/(:any)'] = 'Cis/CoodleExternal/index/$1/$2';
//Route for Zeitsperrenma
$route['Cis/Zeitsperrenma/.*'] = 'Cis/Zeitsperrenma/index/$1';
//Route für Zeitsperren
$route['Cis/Zeitsperren/.*'] = 'Cis/Zeitsperren/index/$1';
$route['CoodleFreeBusy/(:any)'] = 'api/frontend/v1/coodle/FreeBusy/getCoodleFreeBusy/$1';
$route['CoodleIcal/encrypted/(:any)'] = 'api/frontend/v1/coodle/CoodleSurvey/getCoodleIcalEncrypted/$1';
$route['CoodleIcal/(:any)'] = 'api/frontend/v1/coodle/CoodleSurvey/getCoodleIcal/$1';
$route['Abgabetool/Assistenz'] = 'Cis/Abgabetool/Assistenz';
$route['Abgabetool/Assistenz/(:any)'] = 'Cis/Abgabetool/Assistenz/$1';
@@ -146,19 +135,13 @@ $route['api/frontend/v1/treemenudata/stv/.*'] = 'api/frontend/v1/stv/students/in
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/semester/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/semester/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)/semester/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStgOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)/semester/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByStgOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStgOrgform/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByStgOrgform/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/emp/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByEmp/$1/$2';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/emp/(:any)/stg/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByEmp/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/emp/(:any)/stg/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByEmp/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/le/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByLe/$1/$2';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/lv/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByLv/$1/$2';
// load routes from extensions, also look for environment-specific configs
$subdirs = ['application/config/extensions', 'application/config/' . ENVIRONMENT . '/extensions'];
+16
View File
@@ -872,3 +872,19 @@ $config['dms'] = [
)
)"
];
$config['group'] = [
'primarykey' => 'gruppe_kurzbz',
'table' => 'public.tbl_gruppe',
'searchfields' => [
'gruppe_kurzbz' => [
'comparison' => 'similar',
'field' => 'gruppe_kurzbz',
],
],
'resultfields' => [
"g.gruppe_kurzbz as name",
],
'resultjoin' => "
JOIN public.tbl_gruppe g USING (gruppe_kurzbz)"
];
@@ -0,0 +1,55 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
$CI =& get_instance();
$config['employee'] = $CI->config->item('employee', 'search');
unset($config['student']['searchfields']['email']);
unset($config['student']['searchfields']['tel']);
$config['employee']['resultfields'] = [
"m.mitarbeiter_uid AS uid",
"(p.vorname || ' ' || p.nachname) AS name",
];
$config['employee']['resultjoin'] = "
JOIN public.tbl_mitarbeiter m USING (mitarbeiter_uid)
JOIN public.tbl_benutzer b ON (b.uid = m.mitarbeiter_uid AND b.aktiv = true)
JOIN public.tbl_person p USING(person_id)
LEFT JOIN (
SELECT kontakt, standort_id
FROM public.tbl_kontakt
WHERE kontakttyp = 'telefon'
) k ON (k.standort_id = m.standort_id)";
$config['student'] = $CI->config->item('student', 'search');
unset($config['student']['searchfields']['email']);
unset($config['student']['searchfields']['tel']);
$config['student']['resultfields'] = [
"s.student_uid AS uid",
"(p.vorname || ' ' || p.nachname) AS name",
];
$config['student']['resultjoin'] = "
JOIN public.tbl_student s USING (student_uid)
JOIN public.tbl_benutzer b ON(b.uid = s.student_uid AND b.aktiv = true)
JOIN public.tbl_person p USING(person_id)";
$config['group'] = $CI->config->item('group', 'search');
$config['group']['resultfields'] = [
"g.gruppe_kurzbz as name",
"ARRAY(
SELECT bg.uid as uid
FROM public.tbl_benutzergruppe bg
WHERE bg.gruppe_kurzbz = g.gruppe_kurzbz
ORDER BY bg.uid
) AS user_uids",
"ARRAY(
SELECT p.vorname || ' ' || p.nachname AS name
FROM public.tbl_benutzergruppe bg
JOIN public.tbl_benutzer b ON(b.uid = bg.uid)
JOIN public.tbl_person p ON(p.person_id = b.person_id)
WHERE bg.gruppe_kurzbz = g.gruppe_kurzbz
ORDER BY bg.uid
) AS user_names",
];
+2 -3
View File
@@ -26,8 +26,7 @@ $config['root'] = [
'verband' => [
'group'
]
]
],
'orgform'
]
];
$config['root']['stg']['orgform'] = $config['root']['stg'];
@@ -1,37 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Benotungstool extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => array('lehre/benotungstool:rw', 'lehre/benotungstool_assistenz:rw')
]);
$this->_ci =& get_instance();
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
$viewData = array(
'uid'=>getAuthUID(),
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Benotungstool']);
}
}
-44
View File
@@ -1,44 +0,0 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Compat extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'ci' => ['basis/cis:r'],
'legacy' => ['basis/cis:r'],
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @access public
* @return void
*/
public function ci()
{
$this->load->view('CisRouterView/CisRouterView.php',['route' => 'Compat']);
}
/**
* @access public
* @return void
*/
public function legacy()
{
$this->load->view('CisRouterView/CisRouterView.php',['route' => 'Compat']);
}
}
@@ -5,7 +5,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Zeitsperrenma extends Auth_Controller
class Coodle extends Auth_Controller
{
/**
* Constructor
@@ -13,9 +13,8 @@ class Zeitsperrenma extends Auth_Controller
public function __construct()
{
parent::__construct([
'index' => ['cis/andere_zeitsperren:r']
'index' => [self::PERM_LOGGED],
]);
}
// -----------------------------------------------------------------------------------------------------------------
@@ -26,6 +25,6 @@ class Zeitsperrenma extends Auth_Controller
*/
public function index()
{
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'Zeitsperrenma']);
$this->load->view('CisRouterView/CisRouterView.php', ["viewData" => [], 'route' => 'Coodle']);
}
}
@@ -5,7 +5,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class ProjektabgabeUebersicht extends Auth_Controller
class CoodleExternal extends Auth_Controller
{
/**
* Constructor
@@ -13,7 +13,7 @@ class ProjektabgabeUebersicht extends Auth_Controller
public function __construct()
{
parent::__construct([
'index' => ['basis/cis:r']
'index' => [self::PERM_ANONYMOUS],
]);
}
@@ -25,6 +25,6 @@ class ProjektabgabeUebersicht extends Auth_Controller
*/
public function index()
{
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'ProjektabgabeUebersicht']);
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'CoodleExternal', 'isExternal' => true]);
}
}
@@ -1,33 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class MyReservation extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => ['basis/cis:r']
]);
// Load Config
$this->load->config('calendar');
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
$this->load->view('CisRouterView/CisRouterView.php', ['route' => 'MyReservation']);
}
}
@@ -1,30 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Zeitsperren extends Auth_Controller
{
public function __construct()
{
parent::__construct([
'index' => ['cis/eigene_zeitsperren:r'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
}
/**
* index loads the view Zeitsperren
* @access public
* @return void
*/
public function index()
{
$viewData = array(
'uid'=>getAuthUID(),
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'zeitsperren']);
}
}
+4 -13
View File
@@ -17,15 +17,14 @@ class Cms extends Auth_Controller
array(
'content' => 'basis/cis:r',
'getNews' => 'basis/cis:r',
'getNewsRowCount' => 'basis/cis:r',
'getRoomInformation' => 'basis/cis:r',
'news' => 'basis/cis:r',
'newsAdministration' => ['basis/news:r'],
'news' => 'basis/cis:r'
)
);
// Loads Libraries
$this->load->library('CmsLib');
$this->load->library('PermissionLib');
// Loads phrases system
$this->loadPhrases([
@@ -84,18 +83,10 @@ class Cms extends Auth_Controller
*/
public function news($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true)
{
$this->load->view('CisRouterView/CisRouterView.php', [
'route' => 'News',
]);
$viewData = array();
$this->load->view('CisRouterView/CisRouterView.php', ['viewData'=>$viewData, 'route' => 'News']);
}
public function newsAdministration()
{
$this->load->view('CisRouterView/CisRouterView.php', [
'route' => 'NewsAdministration',
]);
}
public function getRoomInformation($ort_kurzbz)
{
// Load Config
@@ -1916,7 +1916,7 @@ class Abgabe extends FHCAPI_Controller
if (!$mailres)
{
$this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailZweitBegutachterv2'), 'general');
$this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailBegutachterv2'), 'general');
}
}
@@ -16,7 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class AuthInfo extends FHCAPI_Controller
{
@@ -37,6 +38,7 @@ class AuthInfo extends FHCAPI_Controller
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
@@ -54,15 +56,16 @@ class AuthInfo extends FHCAPI_Controller
*/
public function getAuthUID()
{
$this->terminateWithSuccess(['uid'=>$this->uid]);
$this->terminateWithSuccess(['uid' => $this->uid]);
}
public function getAuthInfo()
{
$data = (object) array(
'uid' => $this->uid,
'isMitarbeiter' => $this->isMitarbeiter,
'isStudent' => $this->isStudent
'uid' => $this->uid,
'isMitarbeiter' => $this->isMitarbeiter,
'isStudent' => $this->isStudent,
'name' => getData($this->PersonModel->getFullName($this->uid)),
);
$this->terminateWithSuccess($data);
}
@@ -1,48 +0,0 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Benutzer extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getUserData' => self::PERM_LOGGED,
]);
$this->load->model('person/Benutzer_model', 'BenutzerModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getUserData()
{
$uid = $this->input->get("uid") ?? getAuthUID();
$this->BenutzerModel->addSelect("uid, person_id, insertamum");
$userResult = $this->BenutzerModel->load(["uid" => $uid]);
$userData = $this->getDataOrTerminateWithError($userResult);
$this->terminateWithSuccess($userData);
}
}
@@ -67,11 +67,8 @@ class CisMenu extends FHCAPI_Controller
private function generateUrlForMenuItem($menuItem)
{
if(!isset($menuItem->url))
{
$menuItem->url = $this->menuItemUrlHelper($menuItem);
unset($menuItem->content);
}
$menuItem->url = $this->menuItemUrlHelper($menuItem);
unset($menuItem->content);
if ($menuItem->childs && count($menuItem->childs)) {
$menuItem->childs = $this->generateUrlsForMenuItems($menuItem->childs);
@@ -86,7 +83,7 @@ class CisMenu extends FHCAPI_Controller
return site_url("/CisVue/Cms/content/" . $menuItem->content_id);
}
if (!isset($menuItem->content) || !$menuItem->content || !mb_strlen($menuItem->content)) {
if (!$menuItem->content || !mb_strlen($menuItem->content)) {
return '';
}
@@ -94,8 +91,6 @@ class CisMenu extends FHCAPI_Controller
$doc->loadXML($menuItem->content);
$urlElem = $doc->getElementsByTagName('url')->item(0);
$this->menuItemUrlTargetHelper($menuItem, $doc);
if (!$urlElem) {
return '';
}
@@ -127,18 +122,5 @@ class CisMenu extends FHCAPI_Controller
return $url;
}
private function menuItemUrlTargetHelper($menuItem, $xmldoc)
{
if($menuItem->template_kurzbz === 'redirect')
{
$targetElem = $xmldoc->getElementsByTagName('target')->item(0);
$target = ($targetElem) ? $targetElem->textContent : '';
if(!in_array($target, array('_self', '_top', '_blank')))
{
$target = '_self';
}
$menuItem->target = $target;
}
}
}
+27 -41
View File
@@ -36,15 +36,14 @@ class Cms extends FHCAPI_Controller
'ContentID' => self::PERM_LOGGED,
'getOrtKurzbzContent' => self::PERM_LOGGED,
'content' => self::PERM_LOGGED,
'newsForWidget' => self::PERM_LOGGED,
'news' => self::PERM_LOGGED,
'getNewsRowCount' => self::PERM_LOGGED,
'getNews' => self::PERM_LOGGED,
]);
$this->load->model('content/News_model', 'NewsModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
// setting up the papgination_size
$this->page_size = 10;
@@ -60,6 +59,7 @@ class Cms extends FHCAPI_Controller
//------------------------------------------------------------------------------------------------------------------
// Private methods
//------------------------------------------------------------------------------------------------------------------
// Public methods
@@ -106,7 +106,7 @@ class Cms extends FHCAPI_Controller
$this->terminateWithSuccess($content_id);
}
public function newsForWidget()
public function news()
{
// form validation
@@ -118,7 +118,7 @@ class Cms extends FHCAPI_Controller
$this->load->model('content/news_model', 'NewsModel');
$limit = $this->input->get('limit',TRUE);
//query the news
$news = $this->NewsModel->getAll($limit);
@@ -157,7 +157,23 @@ class Cms extends FHCAPI_Controller
}
public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = false, $titel = '', $edit = false, $sichtbar = true)
public function getNewsRowCount($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $fachbereich_kurzbz = null, $maxalter = 0, $edit = false, $sichtbar = true, $page = 1, $page_size = 10)
{
list($studiengang_kz, $semester) = $this->cmslib->getStgAndSem($studiengang_kz, $semester);
$all = $edit;
$this->load->model('content/News_model','NewsModel');
$num_rows = $this->NewsModel->countNewsWithContent(getSprache(), $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $page_size, $all, $mischen);
$num_rows = $this->getDataOrTerminateWithError($num_rows);
$this->terminateWithSuccess($num_rows);
}
public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true)
{
//form validation
$this->load->library('form_validation');
@@ -177,45 +193,15 @@ class Cms extends FHCAPI_Controller
// default value for the page_size is 10
$page_size = $page_size ?? 10;
$passedSichtbar = $this->input->get('published', true);
if($passedSichtbar !== null)
{
$sichtbar = $passedSichtbar;
}
$filterForDegreePrograms = false;
$entitledDegreePrograms = [];
$student = $this->StudentModel->loadWhere(['student_uid' => getAuthUID()]);
if(isError($student))
{
$this->terminateWithError(getError($student));
}
if(hasData($student))
{
$student = current(getData($student));
$degreeProgramSemesterDataResult = $this->PrestudentModel->getStudiengaengAndAusbildungssemesterByStudentUid(getAuthUID());
$degreeProgramSemesterData = $this->getDataOrTerminateWithError($degreeProgramSemesterDataResult)[0];
if ($degreeProgramSemesterData) {
$studiengang_kz = isset($degreeProgramSemesterData->studiengang_kz) ? $degreeProgramSemesterData->studiengang_kz : null;
$semester = isset($degreeProgramSemesterData->ausbildungssemester) ? $degreeProgramSemesterData->ausbildungssemester : null;
}
$mischen = true;
} else {
$filterForDegreePrograms = true;
$entitledDegreePrograms = $this->permissionlib->getSTG_isEntitledFor("basis/news");
array_push($entitledDegreePrograms, 0);
}
$news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size, $sprache, $filterForDegreePrograms, $entitledDegreePrograms, true);
$news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size, $sprache);
$news = $this->getDataOrTerminateWithError($news);
$this->addMeta('row_count', $news["row_count"] ?? 0);
$this->terminateWithSuccess($news["content"]);
$this->addMeta('phrases', json_decode($this->p->getJson()));
$this->terminateWithSuccess($news);
}
}
@@ -18,9 +18,18 @@
if (! defined('BASEPATH')) exit('No direct script access allowed');
//require_once('../../../include/studiengang.class.php');
//require_once('../../../include/student.class.php');
//require_once('../../../include/datum.class.php');
//require_once('../../../include/mail.class.php');
//require_once('../../../include/benutzerberechtigung.class.php');
//require_once('../../../include/phrasen.class.php');
//require_once('../../../include/projektarbeit.class.php');
//require_once('../../../include/projektbetreuer.class.php');
class Lehre extends FHCAPI_Controller
{
/**
* Object initialization
*/
@@ -31,56 +40,38 @@ class Lehre extends FHCAPI_Controller
'LV' => self::PERM_LOGGED,
'Pruefungen' => self::PERM_LOGGED,
'semesterAverageGrade' => self::PERM_LOGGED,
'getZugewieseneLv' => self::PERM_LOGGED,
'getLeForLv' => self::PERM_LOGGED
]);
$this->load->library('PhrasesLib');
$this->loadPhrases(
array(
'global',
'ui',
'abgabetool'
)
);
$this->load->helper('hlp_sancho_helper');
require_once(FHCPATH . 'include/studiengang.class.php');
require_once(FHCPATH . 'include/student.class.php');
require_once(FHCPATH . 'include/projektarbeit.class.php');
require_once(FHCPATH . 'include/projektbetreuer.class.php');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
/**
* constructs the emails of the groups from a lehrveranstaltung
*/
public function lvStudentenMail()
public function lvStudentenMail()
{
$lehreinheit_id = $this->input->get("lehreinheit_id",TRUE);
$lehreinheit_id = $this->input->get("lehreinheit_id",TRUE);
// return early if the required parameter is missing
if(!isset($lehreinheit_id))
{
$this->terminateWithError('Missing required parameter', self::ERROR_TYPE_GENERAL);
}
// return early if the required parameter is missing
if(!isset($lehreinheit_id))
{
$this->terminateWithError('Missing required parameter', self::ERROR_TYPE_GENERAL);
}
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$studentenMails = $this->LehreinheitModel->getStudentenMail($lehreinheit_id);
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$studentenMails = $this->LehreinheitModel->getStudentenMail($lehreinheit_id);
$studentenMails = $this->getDataOrTerminateWithError($studentenMails);
$studentenMails = $this->getDataOrTerminateWithError($studentenMails);
//convert array of objects into array of strings
$studentenMails = array_map(function($element){
return $element->mail;
}, $studentenMails);
$this->terminateWithSuccess($studentenMails);
$this->terminateWithSuccess($studentenMails);
}
public function LV($studiensemester_kurzbz, $lehrveranstaltung_id)
@@ -90,13 +81,13 @@ class Lehre extends FHCAPI_Controller
$result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID(), $studiensemester_kurzbz, getUserLanguage(), $lehrveranstaltung_id);
$result = current($this->getDataOrTerminateWithError($result));
$this->terminateWithSuccess($result);
}
/**
* fetches all Pruefungen of a student for a specific lehrveranstaltung
* if the student passed the Pruefung on the first attempt, no information about the Pruefungen is stored in the database
* if the student passed the Pruefung on the first attempt, no information about the Pruefungen is stored in the database
* @param mixed $lehrveranstaltung_id
* @return void
*/
@@ -154,46 +145,5 @@ class Lehre extends FHCAPI_Controller
$this->terminateWithSuccess(['average_grade' => $averageGrade, 'weighted_average_grade' => $weightedAverageGrade]);
}
/**
* fetches all assigned lehrveranstaltungen of a mitarbeiter for a given semester
* @param mixed $uid
* @param mixed $sem_kurzbz
* @return void
*/
public function getZugewieseneLv() {
$uid = $this->input->get("uid",TRUE);
$sem_kurzbz = $this->input->get("sem_kurzbz",TRUE);
// TODO: error messages
if(!isset($sem_kurzbz) || isEmptyString($sem_kurzbz))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
if (!isset($uid) || isEmptyString($uid))
$uid = getAuthUID();
// querying other ma_uids data requires admin permission
if($uid !== getAuthUID()) {
$this->load->library('PermissionLib');
$isAdmin = $this->permissionlib->isBerechtigt('admin');
if(!$isAdmin) $this->terminateWithError($this->p->t('ui', 'keineBerechtigung'), 'general');
}
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvForLektorInSemester($sem_kurzbz, $uid);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getLeForLv() {
$lv_id = $this->input->get("lv_id",TRUE);
$sem_kurzbz = $this->input->get("sem_kurzbz",TRUE);
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
// $this->terminateWithSuccess($this->LehreinheitModel->getLesForLv($lv_id, $sem_kurzbz));
$this->terminateWithSuccess($this->LehreinheitModel->getAllLehreinheitenForLvaAndMaUid($lv_id, getAuthUID(), $sem_kurzbz));
}
}
@@ -28,10 +28,7 @@ class Lehrveranstaltung extends FHCAPI_Controller
{
parent::__construct([
'getByEmp' => ['admin:r', 'assistenz:r'],
'getByLe' => ['admin:r', 'assistenz:r'],
'getByLv' => ['admin:r', 'assistenz:r'],
'getByStg' => ['admin:r', 'assistenz:r'],
'getByStgOrgform' => ['admin:r', 'assistenz:r'],
'loadByLV' => ['admin:r', 'assistenz:r'],
]);
@@ -80,117 +77,41 @@ class Lehrveranstaltung extends FHCAPI_Controller
$this->terminateWithSuccess($tree);
}
public function getByLe($studiensemester_kurzbz = null, $lehreinheit_id = null)
{
if (is_null($lehreinheit_id))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$lehreinheiten = $this->_ci->LehreinheitModel->getByLeStudiensemester($lehreinheit_id, $studiensemester_kurzbz);
$lehreinheiten_data = $this->getDataOrTerminateWithError($lehreinheiten);
$this->terminateWithSuccess($lehreinheiten_data);
}
public function getByLv($studiensemester_kurzbz = null, $lehrveranstaltung_id = null)
{
if (is_null($lehrveranstaltung_id))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$tree = [];
$this->_ci->LehrveranstaltungModel->addSelect('studiengang_kz');
$lv = $this->_ci->LehrveranstaltungModel->load($lehrveranstaltung_id);
$lv = $this->getDataOrTerminateWithError($lv);
if (empty($lv))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehrveranstaltungen_data = array();
foreach ($this->_loadLvRows(current($lv)->studiengang_kz, $studiensemester_kurzbz) as $row)
{
if ((string)$row->lehrveranstaltung_id === (string)$lehrveranstaltung_id)
{
$lehrveranstaltungen_data[] = $row;
break;
}
}
if (empty($lehrveranstaltungen_data))
{
$this->_ci->LehrveranstaltungModel->addSelect('
tbl_lehrveranstaltung.*,
tbl_lehrveranstaltung.kurzbz as lv_kurzbz,
lehrveranstaltung_id,
lehrtyp_kurzbz,
studiengang_kz as lv_studiengang_kz,
UPPER(CONCAT(tbl_studiengang.typ, tbl_studiengang.kurzbz)) as studiengang,
semester as semester,
tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung,
ects as lv_ects,
lehreverzeichnis as lv_lehreverzeichnis,
planfaktor as lv_planfaktor,
planlektoren as lv_planlektoren,
planpersonalkosten as lv_planpersonalkosten,
plankostenprolektor as lv_plankostenprolektor,
tbl_lehrveranstaltung.orgform_kurzbz as orgform_kurzbz,
tbl_lehrveranstaltung.sprache as sprache,
lehrform_kurzbz as lv_lehrform_kurzbz,
tbl_lehrveranstaltung.bezeichnung_english as lv_bezeichnung_english,
semesterstunden as lv_semesterstunden,
');
$this->_ci->LehrveranstaltungModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
$lehrveranstaltungen = $this->_ci->LehrveranstaltungModel->load($lehrveranstaltung_id);
$lehrveranstaltungen_data = $this->getDataOrTerminateWithError($lehrveranstaltungen);
}
foreach ($lehrveranstaltungen_data as $lehrveranstaltung)
{
$lehreinheiten = $this->_ci->LehreinheitModel->getByLvidStudiensemester($lehrveranstaltung->lehrveranstaltung_id, $studiensemester_kurzbz);
$lehreinheiten_data = $this->getDataOrTerminateWithError($lehreinheiten);
if (!isset($lehrveranstaltung->_children))
{
$lehrveranstaltung->_children = $lehreinheiten_data;
}
$tree[] = $lehrveranstaltung;
}
$counter = 0;
$this->assignUniqueIndex($tree, $counter);
$this->terminateWithSuccess($tree);
}
public function getByStg($studiensemester_kurzbz = null, $stg_kz = null, $semester = null)
{
$this->_getLvTree($studiensemester_kurzbz, $stg_kz, $semester, null);
}
public function getByStgOrgform($studiensemester_kurzbz = null, $stg_kz = null, $orgform = null, $semester = null)
{
$orgform_kurzbz = $this->getOrgformKurzbz($orgform);
$this->_getLvTree($studiensemester_kurzbz, $stg_kz, $semester, $orgform_kurzbz);
}
private function _getLvTree($studiensemester_kurzbz, $stg_kz, $semester, $orgform_kurzbz)
{
$studiengang_kz = $this->getStudiengangKz($stg_kz);
if (is_null($studiengang_kz) || !preg_match("/^(-?[1-9][0-9]*|0)$/", (string)$studiengang_kz))
if (is_null($studiengang_kz) || !preg_match("/^-?[1-9][0-9]*$/", (string)$studiengang_kz))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
if (!is_null($semester) && !ctype_digit((string)$semester))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$verband = null;
if (!is_null($semester) && !is_numeric($semester))
{
$verband = $this->getOrgformKurzbz($semester);
$semester = null;
}
$this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel');
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$studienplan_data = $this->_ci->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $studiensemester_kurzbz, $semester, $verband);
$lehrveranstaltungen_data = $this->_loadLvRows($studiengang_kz, $studiensemester_kurzbz, $semester, $orgform_kurzbz);
$studienplan_ids = array();
$only_ids = array();
$placeholders = array();
if (hasData($studienplan_data))
{
foreach (getData($studienplan_data) as $studienplan) {
$placeholders[] = "(?, ?)";
$studienplan_ids[] = $studienplan->studienplan_id;
$studienplan_ids[] = $studienplan->semester;
$only_ids[] = $studienplan->studienplan_id;
}
}
$lehrveranstaltungen_data = $this->_ci->LehrveranstaltungModel->getLvsByStudiengang($studienplan_ids, $placeholders, $only_ids, $studiengang_kz, $studiensemester_kurzbz, $semester, $verband);
$lehrveranstaltungen_data = hasData($lehrveranstaltungen_data) ? getData($lehrveranstaltungen_data) : array();
$tree = [];
foreach ($lehrveranstaltungen_data as $row)
@@ -323,31 +244,6 @@ class Lehrveranstaltung extends FHCAPI_Controller
$this->LehreinheitModel->getLvsByFachbereich($fachbereich, $studiensemester_kurzbz, $mitarbeiter_uid);
}*/
private function _loadLvRows($studiengang_kz, $studiensemester_kurzbz, $semester = null, $orgform_kurzbz = null)
{
$this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel');
$studienplan_data = $this->_ci->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $studiensemester_kurzbz, $semester, $orgform_kurzbz);
$studienplan_ids = array();
$only_ids = array();
$placeholders = array();
if (hasData($studienplan_data))
{
foreach (getData($studienplan_data) as $studienplan) {
$placeholders[] = "(?, ?)";
$studienplan_ids[] = $studienplan->studienplan_id;
$studienplan_ids[] = $studienplan->semester;
$only_ids[] = $studienplan->studienplan_id;
}
}
$lehrveranstaltungen_data = $this->_ci->LehrveranstaltungModel->getLvsByStudiengang($studienplan_ids, $placeholders, $only_ids, $studiengang_kz, $studiensemester_kurzbz, $semester, $orgform_kurzbz);
return hasData($lehrveranstaltungen_data) ? getData($lehrveranstaltungen_data) : array();
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
@@ -413,8 +309,8 @@ class Lehrveranstaltung extends FHCAPI_Controller
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
return $orgform_kurzbz;
return current($data)->orgform_kurzbz;
}
}
}
@@ -36,8 +36,7 @@ class LvMenu extends FHCAPI_Controller
public function __construct()
{
parent::__construct([
'getLvMenu' => self::PERM_LOGGED,
'getMultipleLvMenu' => self::PERM_LOGGED
'getLvMenu' => self::PERM_LOGGED
]);
$this->load->model("ressource/Mitarbeiter_model");
@@ -62,23 +61,24 @@ class LvMenu extends FHCAPI_Controller
/**
* alternative function to get multiple lvMenus with a single http request
* not yet working as intended as the menu_lv.inc.php scripts called by the
* lvMenuBuild event have logic coupled to require_once import which results in
* a wrong logic after the first invocation -> faulty results for lvinfo, moodle
* and several others
*/
public function getMultipleLvMenu(){
$lvMenuOptionList = $this->input->post('lvMenuOptionList', true);
public function getMultipleLvMenu($lvMenuOptionList){
$result =[];
foreach($lvMenuOptionList as $lvMenuOptions){
$lvMenu = $this->getLvMenuInternal($lvMenuOptions['lvid'],$lvMenuOptions['studiensemester_kurzbz']);
$lvMenu = $this->getLvMenu($lvMenuOptions['lvid'],$lvMenuOptions['studiensemester_kurzbz']);
if(isError($lvMenu)){
// TODO: some lvMenu threw an error, handle error here
}
$result[$lvMenuOptions['lvid']]=$lvMenu;
}
$this->terminateWithSuccess($result);
}
private function getLvMenuInternal($lvid, $studiensemester_kurzbz) {
/**
*
*/
public function getLvMenu($lvid, $studiensemester_kurzbz)
{
// return early if parameters are missing
if(!isset($lvid) || !isset($studiensemester_kurzbz))
@@ -89,14 +89,14 @@ class LvMenu extends FHCAPI_Controller
// get the user
if (!$user=getAuthUID())
$this->terminateWithError($this->p->t('global', 'nichtAngemeldet'));
$this->terminateWithError($this->p->t('global', 'nichtAngemeldet'));
// check if is_lector
$is_lector = false;
$mares = $this->Mitarbeiter_model->isMitarbeiter($user);
if(hasData($mares))
{
$is_lector = getData($mares);
$is_lector = getData($mares);
}
// definition of user_is_allowed_to_upload
@@ -105,7 +105,7 @@ class LvMenu extends FHCAPI_Controller
// load lehrveranstaltung
$lvres = $this->Lehrveranstaltung_model->load($lvid);
if(!hasData($lvres))
if(!hasData($lvres))
{
$this->terminateWithError('LV ' . $lvid . ' not found.');
}
@@ -124,7 +124,7 @@ class LvMenu extends FHCAPI_Controller
$stgres = $this->Studiengang_model->load(strval($studiengang_kz));
if(!hasData($stgres))
{
$this->terminateWithError('Stg ' . $lv->studiengang_kz . ' not found.');
$this->terminateWithError('Stg ' . $lv->studiengang_kz . ' not found.');
}
$stg = (getData($stgres))[0];
$kurzbz = strtoupper($stg->typ . $stg->kurzbz);
@@ -139,7 +139,7 @@ class LvMenu extends FHCAPI_Controller
$angemeldet = false;
$lesres = $this->Lehreinheit_model->getLehreinheitenForStudentAndStudienSemester(
$lvid, $user, $angezeigtes_stsem
$lvid, $user, $angezeigtes_stsem
);
if(hasData($lesres) && count(getData($lesres)) > 0)
@@ -148,7 +148,7 @@ class LvMenu extends FHCAPI_Controller
// lehrfach
$lehrfach_id='';
if(defined('CIS_LEHRVERANSTALTUNG_LEHRFACH_ANZEIGEN') && CIS_LEHRVERANSTALTUNG_LEHRFACH_ANZEIGEN)
{
// Wenn der eingeloggte User zu einer der Lehreinheiten zugeteilt ist
@@ -211,8 +211,8 @@ class LvMenu extends FHCAPI_Controller
foreach($fbs as $row)
{
$lehrfach_oe_kurzbz_arr[] = $row->oe_kurzbz;
if($this->PermissionLib->isBerechtigt('lehre', null, $row->oe_kurzbz)
|| $this->PermissionLib->isBerechtigt('assistenz', null, $stg->oe_kurzbz))
if($this->PermissionLib->isBerechtigt('lehre', null, $row->oe_kurzbz)
|| $this->PermissionLib->isBerechtigt('assistenz', null, $stg->oe_kurzbz))
{
$user_is_allowed_to_upload=true;
}
@@ -224,21 +224,21 @@ class LvMenu extends FHCAPI_Controller
$menu = array();
$this->fhc_menu_lvinfo($menu, $lvid, $studiengang_kz, $lektor_der_lv, $is_lector, $lehrfach_oe_kurzbz_arr);
$this->fhc_menu_feedback($menu, $angemeldet, $lvid);
$this->fhc_menu_gesamtnote($menu, $angemeldet, $lvid, $lv, $is_lector, $angezeigtes_stsem);
$this->fhc_menu_emailStudierende($menu, $user, $angemeldet, $lvid, $angezeigtes_stsem);
$this->fhc_menu_abmeldung($menu, $user, $is_lector, $lvid, $angezeigtes_stsem);
$this->fhc_menu_lehretools($menu, $lvid, $angezeigtes_stsem, $sprache);
$this->fhc_menu_anrechnungStudent($menu, $lvid, $angezeigtes_stsem);
$this->fhc_menu_anrechnungLector($menu, $angezeigtes_stsem);
// Addons Menu Logic
// ##########################################################################################
@@ -272,18 +272,18 @@ class LvMenu extends FHCAPI_Controller
'permissionLib' => &$this->PermissionLib,
'phrasesLib' => &$this->PhrasesLib
];
Events::trigger('lvMenuBuild',
// passing $menu per reference
function & () use (&$menu) {
return $menu;
},
$params
Events::trigger('lvMenuBuild',
// passing $menu per reference
function & () use (&$menu) {
return $menu;
},
$params
);
// Menu sortieren
// ##########################################################################################
foreach ($menu as $key => $row){
// removes menu points that are not needed in the c4 lvUebersicht
@@ -291,7 +291,7 @@ class LvMenu extends FHCAPI_Controller
unset($menu[$key]);
continue;
}
// fills pos array to sort the menu
$pos[$key] = $row['position'];
@@ -299,18 +299,11 @@ class LvMenu extends FHCAPI_Controller
array_multisort($pos, SORT_ASC, SORT_NUMERIC, $menu);
return $menu;
}
/**
*
*/
public function getLvMenu($lvid, $studiensemester_kurzbz)
{
$menu = $this->getLvMenuInternal($lvid, $studiensemester_kurzbz);
// HTTP response
// ##########################################################################################
$this->terminateWithSuccess($menu);
}
private function fhc_menu_lvinfo(&$menu, $lvid, $studiengang_kz, $lektor_der_lv, $is_lector, $lehrfach_oe_kurzbz_arr){
@@ -379,8 +372,7 @@ class LvMenu extends FHCAPI_Controller
'name'=>$this->p->t('lehre', 'gesamtnote'),
'phrase' => 'lehre/gesamtnote',
'c4_icon'=> base_url('skin/images/button_endnote.png'),
'c4_link'=> site_url('Cis/Benotungstool/'.urlencode($lvid).'/'.urlencode($angezeigtes_stsem))
//'c4_link'=> base_url('cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem))
'c4_link'=> base_url('cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem))
//'c4_link'=> base_url('benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem))
);
}
@@ -549,4 +541,4 @@ class LvMenu extends FHCAPI_Controller
);
}
}
}
}
@@ -47,7 +47,7 @@ class LvPlan extends FHCAPI_Controller
'fetchFerienEvents' => self::PERM_LOGGED,
'getStudiengaenge' => self::PERM_LOGGED,
'getLehrverband' => self::PERM_LOGGED,
'permissionOtherLvPlan' => self::PERM_LOGGED,
'permissionOtherLvPlan' => self::PERM_ANONYMOUS,
'compactibleEventTypes' => self::PERM_LOGGED,
'getLeEvents' => self::PERM_LOGGED,
'getLvEvents' => self::PERM_LOGGED,
@@ -62,6 +62,7 @@ class LvPlan extends FHCAPI_Controller
'dbExecuteUser' => 'RESTful API'
));
$this->load->library('PermissionLib');
$this->load->library('form_validation');
$this->load->library('PhrasesLib');
$this->loadPhrases(
@@ -437,7 +438,7 @@ class LvPlan extends FHCAPI_Controller
*/
public function permissionOtherLvPlan()
{
$this->terminateWithSuccess($this->permissionlib->isBerechtigt('basis/other_lv_plan'));
$this->terminateWithSuccess(getAuthUID() && $this->permissionlib->isBerechtigt('basis/other_lv_plan'));
}
/**
@@ -1,167 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class MaZeitsperren extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getAllActiveZeitsperren' => ['cis/andere_zeitsperren:r', 'admin:r', 'assistenz:r'],
'getAllZeitsperrenFixeMa' => ['cis/andere_zeitsperren:r', 'admin:r', 'assistenz:r'],
'getAllZeitsperrenLector' => ['cis/andere_zeitsperren:r', 'admin:r', 'assistenz:r'],
'getAllZeitsperrenOes' => ['cis/andere_zeitsperren:r', 'admin:r', 'assistenz:r'],
'getZeitsperrenAss' => ['cis/andere_zeitsperren:r', 'admin:r', 'assistenz:r'],
'getStgLectors' => self::PERM_LOGGED,
'loadZeitsperrenLectorStg' => ['cis/andere_zeitsperren:r', 'admin:r', 'assistenz:r'],
'loadZeitsperrenMa' => ['cis/andere_zeitsperren:r', 'admin:r', 'assistenz:r'],
'getDetailsMa' => self::PERM_LOGGED
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'person',
'zeitsperren'
]);
// Load models
$this->load->model('ressource/Zeitsperre_model', 'ZeitsperreModel');
}
//only user with zeitsperren
public function getAllActiveZeitsperren($days)
{
$result = $this->ZeitsperreModel->getZeitsperrenForNextDays($days);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
//TODO: check query: more results after join with hr-table
//all fixe Ma
public function getAllZeitsperrenFixeMa($days)
{
$von = date('Y-m-d');
$bis = date('Y-m-d', strtotime("+{$days} days"));
$result = $this->ZeitsperreModel->getMitarbeiterWithZeitsperren($von, $bis, true, false, null, false);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getAllZeitsperrenLector($days)
{
$von = date('Y-m-d');
$bis = date('Y-m-d', strtotime("+{$days} days"));
$result = $this->ZeitsperreModel->getMitarbeiterWithZeitsperren($von, $bis, false, true, null, false);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getZeitsperrenAss($days)
{
$von = date('Y-m-d');
$bis = date('Y-m-d', strtotime("+{$days} days"));
$result = $this->ZeitsperreModel->getMitarbeiterWithZeitsperren($von, $bis, false, false, null, true);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getAllZeitsperrenOes($days, $oe)
{
if(!$oe)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'OE Kurzbezeichnung']), self::ERROR_TYPE_GENERAL);
}
$von = date('Y-m-d');
$bis = date('Y-m-d', strtotime("+{$days} days"));
$result = $this->ZeitsperreModel->getMitarbeiterWithZeitsperren($von, $bis, false, false, $oe, false);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadZeitsperrenLectorStg($days, $stg)
{
if(!$stg)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Studiengangskennzahl']), self::ERROR_TYPE_GENERAL);
}
if(!is_numeric($stg))
{
return $this->terminateWithError($this->p->t('ui', 'error_paramNoNumber', ['param'=> 'Studiengangskennzahl']), self::ERROR_TYPE_GENERAL);
}
$von = date('Y-m-d');
$bis = date('Y-m-d', strtotime("+{$days} days"));
$result = $this->ZeitsperreModel->getMitarbeiterWithZeitsperren($von, $bis, false, true, false, false, $stg);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getStgLectors()
{
$sql = "
select
studiengang_kz,
kurzbz,
kurzbzlang,
typ,
bezeichnung,
kurzbzlang || ' (' || bezeichnung || ')' AS label,
aktiv
from
public.tbl_studiengang
where
typ in ('b','m')
order by typ asc, kurzbz Asc
";
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$result = $this->StudiengangModel->execReadOnlyQuery($sql);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadZeitsperrenMa($days, $uid)
{
if ($uid === null || $uid === '')
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Mitarbeiter UID']), self::ERROR_TYPE_GENERAL);
}
$result = $this->ZeitsperreModel->getZeitsperrenForNextDays($days, $uid);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getDetailsMa($uid)
{
if ($uid === null || $uid === '')
{
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Mitarbeiter UID']), self::ERROR_TYPE_GENERAL);
}
$this->load->model('person/Person_model', 'PersonModel');
$result = $this->PersonModel->getFullName($uid);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -1,948 +0,0 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
class NewsAdministrationAPI extends FHCAPI_Controller
{
/**
* News API constructor.
*/
public function __construct()
{
parent::__construct([
'getNews' => 'basis/news:r',
'getNewsItem' => 'basis/news:r',
'storeNewsItem' => 'basis/news:w',
'updateNewsItem' => 'basis/news:w',
'deleteNewsItem' => 'basis/news:w'
]);
$this->load->model('content/Content_model', 'ContentModel');
$this->load->model('content/Contentsprache_model', 'ContentspracheModel');
$this->load->model('content/News_model', 'NewsModel');
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('system/Sprache_model', 'SpracheModel');
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$this->loadPhrases([
'global'
]);
$this->load->library('CmsLib');
$this->load->helper('hlp_sancho_helper');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $titel = '', $active = true, $sichtbar = true)
{
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('page','Page','required|is_natural');
$this->form_validation->set_rules('page_size', 'PageSize', 'is_natural');
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
$page = intval($this->input->get('page', true));
$page_size = intval($this->input->get('page_size', true));
$sprache = $this->input->get('sprache', true);
if(!$sprache)
{
$sprache = getUserLanguage();
}
// default value for the page_size is 10
$page_size = $page_size ?? 10;
$passedSichtbar = $this->input->get('published', true);
if($passedSichtbar !== null)
{
$sichtbar = $passedSichtbar;
}
$passedIsActive = $this->input->get('isActive', true);
if ($passedIsActive !== null)
{
$isActive = filter_var(
$passedIsActive,
FILTER_VALIDATE_BOOLEAN,
FILTER_NULL_ON_FAILURE
);
if ($isActive !== null)
{
$active = $isActive;
}
}
$degreeProgramShortCode = $this->input->get('degreeProgramShortCode', true);
if ($degreeProgramShortCode !== null && $degreeProgramShortCode !== '')
{
if (!ctype_digit((string)$degreeProgramShortCode))
{
$this->terminateWithValidationErrors([
'degreeProgramShortCode' => 'A valid degree program is required'
]);
}
$studiengang_kz = $degreeProgramShortCode;
}
$passedSemester = $this->input->get('semester', true);
if ($passedSemester !== null && $passedSemester !== '')
{
if (
!ctype_digit((string)$passedSemester)
|| (int)$passedSemester < 1
|| (int)$passedSemester > 8
)
{
$this->terminateWithValidationErrors([
'semester' => 'A valid semester is required'
]);
}
$semester = filter_var($passedSemester, FILTER_VALIDATE_INT);
}
$entitledDegreePrograms = $this->permissionlib->getSTG_isEntitledFor("basis/news");
$news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, false, $titel, true, $sichtbar, $page, $page_size, $sprache, true, $entitledDegreePrograms, $active);
$news = $this->getDataOrTerminateWithError($news);
$this->addMeta('row_count', $news["row_count"] ?? 0);
$this->terminateWithSuccess($news["content"]);
}
/**
* Returns one news entry with all available language versions for editing.
*
* @return void
*/
public function getNewsItem($newsId)
{
if (!is_numeric($newsId) || (int)$newsId < 1)
{
$this->terminateWithValidationErrors([
'newsId' => 'A valid news ID is required'
]);
}
$newsId = (int)$newsId;
$newsResult = $this->NewsModel->load($newsId);
if (isError($newsResult))
{
$this->terminateWithError(getError($newsResult), self::ERROR_TYPE_DB);
}
if (!hasData($newsResult))
{
$this->terminateWithValidationErrors([
'newsId' => 'The requested news entry does not exist'
]);
}
$news = current(getData($newsResult));
$entitledDegreePrograms = $this->permissionlib->getSTG_isEntitledFor("basis/news");
if (!in_array($news->studiengang_kz, $entitledDegreePrograms)) {
$this->terminateWithError('You are not entitled to access this news entry', self::ERROR_TYPE_PERMISSION);
}
$translationsResult = $this->ContentspracheModel->loadWhere([
'content_id' => $news->content_id
]);
if (isError($translationsResult))
{
$this->terminateWithError(getError($translationsResult), self::ERROR_TYPE_DB);
}
$languages = [];
foreach ((array)getData($translationsResult) as $translation)
{
$languages[$translation->sprache] = true;
}
$translations = [];
foreach (array_keys($languages) as $language)
{
$contentResult = $this->ContentModel->getContent(
$news->content_id,
$language,
null,
null,
false
);
if (isError($contentResult))
{
$this->terminateWithError(getError($contentResult), self::ERROR_TYPE_DB);
}
$content = getData($contentResult);
$document = new DOMDocument('1.0', 'UTF-8');
if ($content->content !== '' && $document->loadXML($content->content) === false)
{
$this->terminateWithError(
'The stored news content is invalid',
self::ERROR_TYPE_GENERAL
);
}
$author = $document->getElementsByTagName('verfasser')->item(0);
$title = $document->getElementsByTagName('betreff')->item(0);
$text = $document->getElementsByTagName('text')->item(0);
$translations[] = [
'language' => $language,
'author' => $author ? $author->nodeValue : '',
'title' => $title ? $title->nodeValue : '',
'text' => $text ? str_replace('dms.php', APP_ROOT . 'cms/dms.php', $text->nodeValue) : '',
'isPublished' => (bool)$content->sichtbar
];
}
$this->terminateWithSuccess([
'newsId' => (int)$news->news_id,
'visibleFrom' => $news->datum,
'visibleTo' => $news->datum_bis,
'degreeProgramShortCode' => $news->studiengang_kz,
'semester' => $news->semester,
'translations' => $translations
]);
}
/**
* Creates a news entry and all supplied translations.
*
* @return void
*/
public function storeNewsItem()
{
$this->load->library('form_validation');
$postData = $this->input->post(null, true);
$this->form_validation->set_data(is_array($postData) ? $postData : []);
$this->form_validation->set_rules('visibleFrom', 'Visible from', 'required|is_valid_date');
$this->form_validation->set_rules('visibleTo', 'Visible to', 'is_valid_date');
$this->form_validation->set_rules(
'degreeProgramShortCode',
'Degree program',
'required|is_natural'
);
$this->form_validation->set_rules(
'semester',
'Semester',
'is_natural_no_zero|less_than_equal_to[8]'
);
$errors = $this->form_validation->run() === false
? $this->form_validation->error_array()
: [];
$visibleFrom = $this->input->post('visibleFrom', true);
$visibleTo = $this->input->post('visibleTo', true);
$translations = $this->input->post('translations', true);
if (
is_string($visibleFrom)
&& is_string($visibleTo)
&& $visibleTo !== ''
&& is_valid_date($visibleFrom)
&& is_valid_date($visibleTo)
&& new DateTime($visibleTo) < new DateTime($visibleFrom)
)
{
$errors['visibleTo'] = 'Visible to must not be before Visible from';
}
if (!is_array($translations) || count($translations) === 0)
{
$errors['translations'] = 'At least one translation is required';
}
else
{
foreach ($translations as $index => $translation)
{
if (!is_array($translation))
{
$errors['translations.' . $index] = 'Each translation must be an object';
}
}
}
if (count($errors) > 0)
{
$this->terminateWithValidationErrors($errors);
}
$this->_ensureUserIsEntitledForDegreeProgram($this->input->post('degreeProgramShortCode', true));
$degreeProgramShortCode = $this->input->post('degreeProgramShortCode', true);
$semester = $this->input->post('semester', true);
$semester = $semester === '' ? null : $semester;
$visibleTo = $visibleTo === '' ? null : $visibleTo;
$studiengang = $this->_getStudiengang($degreeProgramShortCode);
$data = [
'studiengang_kz' => $degreeProgramShortCode,
'semester' => $semester,
'datum' => $visibleFrom,
'datum_bis' => $visibleTo,
'translations' => []
];
foreach ($translations as $index => $translation)
{
$data['translations'][$index] = [
'sprache' => $translation['language'] ?? '',
'verfasser' => $translation['author'] ?? '',
'betreff' => $translation['title'] ?? '',
'text' => $translation['text'] ?? '',
'sichtbar' => isset($translation['isPublished']) ? (bool)$translation['isPublished'] : false
];
}
$this->_validateLanguages($data['translations']);
foreach ($data['translations'] as $index => $translation)
{
$data['translations'][$index]['content'] = $this->_buildNewsXml($translation);
}
$uid = getAuthUID();
$now = date('Y-m-d H:i:s');
if ($this->db->trans_begin() === false)
{
$this->terminateWithError($this->db->error(), self::ERROR_TYPE_DB);
}
$contentResult = $this->ContentModel->insert([
'template_kurzbz' => 'news',
'oe_kurzbz' => $studiengang->oe_kurzbz,
'aktiv' => true,
'menu_open' => false,
'insertamum' => $now,
'insertvon' => $uid
]);
$contentId = (int)$this->_getInsertedIdOrRollback($contentResult);
$newsResult = $this->NewsModel->insert([
'uid' => $uid,
'studiengang_kz' => $data['studiengang_kz'],
'semester' => $data['semester'],
'datum' => $data['datum'],
'datum_bis' => $data['datum_bis'],
'content_id' => $contentId,
'insertamum' => $now,
'insertvon' => $uid,
'updateamum' => $now,
'updatevon' => $uid
]);
$newsId = (int)$this->_getInsertedIdOrRollback($newsResult);
foreach ($data['translations'] as $translation)
{
$translation['content'] = $this->formatContentURLsToRelative($translation['content']);
$translationResult = $this->ContentspracheModel->insert([
'sprache' => $translation['sprache'],
'content_id' => $contentId,
'version' => 1,
'sichtbar' => $translation['sichtbar'],
'content' => $translation['content'],
'titel' => $translation['betreff'],
'insertamum' => $now,
'insertvon' => $uid,
'updateamum' => $now,
'updatevon' => $uid
]);
$this->_getInsertedIdOrRollback($translationResult);
}
$newsItemResult = $this->NewsModel->load($newsId);
$newsItem = $this->getDataOrTerminateWithError($newsItemResult);
$newsItem = $newsItem[0];
$this->_sendNewsItemTranslationRequiredMail(
$newsItem
);
if ($this->db->trans_status() === false)
{
$error = $this->db->error();
$this->db->trans_rollback();
$this->terminateWithError($error, self::ERROR_TYPE_DB);
}
if ($this->db->trans_commit() === false)
{
$error = $this->db->error();
$this->db->trans_rollback();
$this->terminateWithError($error, self::ERROR_TYPE_DB);
}
$this->terminateWithSuccess($newsId);
}
/**
* Updates a news entry and its supplied translations.
*
* @return void
*/
public function updateNewsItem($newsId)
{
if (!is_numeric($newsId) || (int)$newsId < 1)
{
$this->terminateWithValidationErrors([
'newsId' => 'A valid news ID is required'
]);
}
$newsId = (int)$newsId;
$existingNewsResult = $this->NewsModel->load($newsId);
if (isError($existingNewsResult))
{
$this->terminateWithError(getError($existingNewsResult), self::ERROR_TYPE_DB);
}
if (!hasData($existingNewsResult))
{
$this->terminateWithValidationErrors([
'newsId' => 'The requested news entry does not exist'
]);
}
$existingNews = current(getData($existingNewsResult));
$this->_ensureUserIsEntitledForDegreeProgram($existingNews->studiengang_kz);
$this->load->library('form_validation');
$postData = $this->input->post(null, true);
$this->form_validation->set_data(is_array($postData) ? $postData : []);
$this->form_validation->set_rules('visibleFrom', 'Visible from', 'required|is_valid_date');
$this->form_validation->set_rules('visibleTo', 'Visible to', 'is_valid_date');
$this->form_validation->set_rules(
'degreeProgramShortCode',
'Degree program',
'required|is_natural'
);
$this->form_validation->set_rules(
'semester',
'Semester',
'is_natural_no_zero|less_than_equal_to[8]'
);
$errors = $this->form_validation->run() === false
? $this->form_validation->error_array()
: [];
$visibleFrom = $this->input->post('visibleFrom', true);
$visibleTo = $this->input->post('visibleTo', true);
$translations = $this->input->post('translations', true);
if (
is_string($visibleFrom)
&& is_string($visibleTo)
&& $visibleTo !== ''
&& is_valid_date($visibleFrom)
&& is_valid_date($visibleTo)
&& new DateTime($visibleTo) < new DateTime($visibleFrom)
)
{
$errors['visibleTo'] = 'Visible to must not be before Visible from';
}
if (!is_array($translations) || count($translations) === 0)
{
$errors['translations'] = 'At least one translation is required';
}
else
{
foreach ($translations as $index => $translation)
{
if (!is_array($translation))
{
$errors['translations.' . $index] = 'Each translation must be an object';
}
}
}
if (count($errors) > 0)
{
$this->terminateWithValidationErrors($errors);
}
$degreeProgramShortCode = $this->input->post('degreeProgramShortCode', true);
$semester = $this->input->post('semester', true);
$semester = $semester === '' ? null : $semester;
$visibleTo = $visibleTo === '' ? null : $visibleTo;
$studiengang = $this->_getStudiengang($degreeProgramShortCode);
$data = [
'studiengang_kz' => $degreeProgramShortCode,
'semester' => $semester,
'datum' => $visibleFrom,
'datum_bis' => $visibleTo,
'translations' => []
];
foreach ($translations as $index => $translation)
{
$data['translations'][$index] = [
'sprache' => $translation['language'] ?? '',
'verfasser' => $translation['author'] ?? '',
'betreff' => $translation['title'] ?? '',
'text' => $translation['text'] ?? '',
'sichtbar' => isset($translation['isPublished']) ? (bool)$translation['isPublished'] : false
];
}
$this->_validateLanguages($data['translations']);
foreach ($data['translations'] as $index => $translation)
{
$data['translations'][$index]['content'] = $this->_buildNewsXml($translation);
}
$uid = getAuthUID();
$now = date('Y-m-d H:i:s');
if ($this->db->trans_begin() === false)
{
$this->terminateWithError($this->db->error(), self::ERROR_TYPE_DB);
}
$contentResult = $this->ContentModel->update($existingNews->content_id, [
'oe_kurzbz' => $studiengang->oe_kurzbz,
'updateamum' => $now,
'updatevon' => $uid
]);
if (isError($contentResult))
{
$this->db->trans_rollback();
$this->terminateWithError(getError($contentResult), self::ERROR_TYPE_DB);
}
$newsResult = $this->NewsModel->update($newsId, [
'studiengang_kz' => $data['studiengang_kz'],
'semester' => $data['semester'],
'datum' => $data['datum'],
'datum_bis' => $data['datum_bis'],
'updateamum' => $now,
'updatevon' => $uid
]);
if (isError($newsResult))
{
$this->db->trans_rollback();
$this->terminateWithError(getError($newsResult), self::ERROR_TYPE_DB);
}
$existingTranslationsResult = $this->ContentspracheModel->loadWhere([
'content_id' => $existingNews->content_id
]);
if (isError($existingTranslationsResult))
{
$this->db->trans_rollback();
$this->terminateWithError(getError($existingTranslationsResult), self::ERROR_TYPE_DB);
}
$existingTranslations = [];
foreach ((array)getData($existingTranslationsResult) as $existingTranslation)
{
$language = $existingTranslation->sprache;
if (
!isset($existingTranslations[$language])
|| (int)$existingTranslation->version > (int)$existingTranslations[$language]->version
)
{
$existingTranslations[$language] = $existingTranslation;
}
}
$submittedLanguages = array_column($data['translations'], 'sprache');
$this->db->where('content_id', $existingNews->content_id);
$this->db->where_not_in('sprache', $submittedLanguages);
if ($this->db->delete('campus.tbl_contentsprache') === false)
{
$error = $this->db->error();
$this->db->trans_rollback();
$this->terminateWithError($error, self::ERROR_TYPE_DB);
}
foreach ($data['translations'] as $translation)
{
$translation['content'] = $this->formatContentURLsToRelative($translation['content']);
$translationData = [
'sichtbar' => $translation['sichtbar'],
'content' => $translation['content'],
'titel' => $translation['betreff'],
'updateamum' => $now,
'updatevon' => $uid
];
$existingTranslation = $existingTranslations[$translation['sprache']] ?? null;
if ($existingTranslation)
{
$translationResult = $this->ContentspracheModel->update(
$existingTranslation->contentsprache_id,
$translationData
);
}
else
{
$translationResult = $this->ContentspracheModel->insert([
'sprache' => $translation['sprache'],
'content_id' => $existingNews->content_id,
'version' => 1,
'insertamum' => $now,
'insertvon' => $uid
] + $translationData);
}
$this->_getInsertedIdOrRollback($translationResult);
}
if ($this->db->trans_status() === false)
{
$error = $this->db->error();
$this->db->trans_rollback();
$this->terminateWithError($error, self::ERROR_TYPE_DB);
}
if ($this->db->trans_commit() === false)
{
$error = $this->db->error();
$this->db->trans_rollback();
$this->terminateWithError($error, self::ERROR_TYPE_DB);
}
$this->terminateWithSuccess($newsId);
}
/**
* Deletes one news entry and its linked content.
*
* @return void
*/
public function deleteNewsItem($newsId)
{
if (!is_numeric($newsId) || (int)$newsId < 1)
{
$this->terminateWithValidationErrors([
'newsId' => 'A valid news ID is required'
]);
}
$newsId = (int)$newsId;
$newsResult = $this->NewsModel->load($newsId);
if (isError($newsResult))
{
$this->terminateWithError(getError($newsResult), self::ERROR_TYPE_DB);
}
if (!hasData($newsResult))
{
$this->terminateWithValidationErrors([
'newsId' => 'The requested news entry does not exist'
]);
}
$news = current(getData($newsResult));
$this->_ensureUserIsEntitledForDegreeProgram($news->studiengang_kz);
if ($this->db->trans_begin() === false)
{
$this->terminateWithError($this->db->error(), self::ERROR_TYPE_DB);
}
$newsDeleteResult = $this->NewsModel->delete($newsId);
if (isError($newsDeleteResult))
{
$this->db->trans_rollback();
$this->terminateWithError(getError($newsDeleteResult), self::ERROR_TYPE_DB);
}
$this->db->where('content_id', $news->content_id);
if ($this->db->delete('campus.tbl_contentsprache') === false)
{
$error = $this->db->error();
$this->db->trans_rollback();
$this->terminateWithError($error, self::ERROR_TYPE_DB);
}
$contentDeleteResult = $this->ContentModel->delete($news->content_id);
if (isError($contentDeleteResult))
{
$this->db->trans_rollback();
$this->terminateWithError(getError($contentDeleteResult), self::ERROR_TYPE_DB);
}
if ($this->db->trans_status() === false)
{
$error = $this->db->error();
$this->db->trans_rollback();
$this->terminateWithError($error, self::ERROR_TYPE_DB);
}
if ($this->db->trans_commit() === false)
{
$error = $this->db->error();
$this->db->trans_rollback();
$this->terminateWithError($error, self::ERROR_TYPE_DB);
}
$this->terminateWithSuccess($newsId);
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
/**
* Loads the requested Studiengang or reports a validation error.
*
* @param integer $studiengangKz
* @return stdClass
*/
private function _getStudiengang($studiengangKz)
{
$result = $this->StudiengangModel->load($studiengangKz);
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
}
if (!hasData($result))
{
$this->terminateWithValidationErrors([
'studiengang_kz' => 'The requested Studiengang does not exist'
]);
}
$studiengaenge = getData($result);
return current($studiengaenge);
}
/**
* Ensures that all supplied languages exist in tbl_sprache.
*
* @param array $translations
* @return void
*/
private function _validateLanguages($translations)
{
$languages = [];
foreach ($translations as $translation)
{
$languages[] = $translation['sprache'];
}
$result = $this->SpracheModel->loadMultiple($languages);
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
}
$existingLanguages = [];
foreach ((array)getData($result) as $language)
{
$existingLanguages[$language->sprache] = true;
}
$errors = [];
foreach ($translations as $index => $translation)
{
if (!isset($existingLanguages[$translation['sprache']]))
{
$errors['translations.' . $index . '.sprache'] = 'The requested language does not exist';
}
}
if (count($errors) > 0)
{
$this->terminateWithValidationErrors($errors);
}
}
private function _ensureUserIsEntitledForDegreeProgram($degreeProgramShortCode)
{
$entitledDegreePrograms = $this->permissionlib->getSTG_isEntitledFor("basis/news:w");
if (!is_array($entitledDegreePrograms))
{
$this->terminateWithError('Failed to retrieve entitled degree programs for the user', self::ERROR_TYPE_GENERAL);
}
if (!in_array($degreeProgramShortCode, $entitledDegreePrograms)) {
$this->terminateWithError("User is not entitled for the specified degree program");
}
}
/**
* Returns an inserted identifier or rolls the transaction back on error.
*
* @param stdClass $result
* @return mixed
*/
private function _getInsertedIdOrRollback($result)
{
if (isError($result))
{
$this->db->trans_rollback();
$this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
}
return getData($result);
}
/**
* Builds the XML format consumed by existing news readers.
*
* @param array $translation
* @return string
*/
private function _buildNewsXml($translation)
{
$document = new DOMDocument('1.0', 'UTF-8');
$news = $document->createElement('news');
$document->appendChild($news);
$this->_appendCdataElement($document, $news, 'verfasser', $translation['verfasser']);
$this->_appendCdataElement($document, $news, 'betreff', $translation['betreff']);
$this->_appendCdataElement($document, $news, 'text', $translation['text']);
return $document->saveXML($news);
}
/**
* Appends a CDATA element and safely preserves CDATA terminators.
*
* @param DOMDocument $document
* @param DOMElement $parent
* @param string $name
* @param string $value
* @return void
*/
private function _appendCdataElement($document, $parent, $name, $value)
{
$element = $document->createElement($name);
$parts = explode(']]>', $value);
$lastIndex = count($parts) - 1;
foreach ($parts as $index => $part)
{
if ($index > 0)
{
$part = '>' . $part;
}
if ($index < $lastIndex)
{
$part .= ']]';
}
$element->appendChild($document->createCDATASection($part));
}
$parent->appendChild($element);
}
private function _sendNewsItemTranslationRequiredMail($newsItem)
{
$translatorsResult = $this->BenutzerfunktionModel->getBenutzerFunktionen("translate", $newsItem->studiengang_kz);
$translators = $this->getDataOrTerminateWithError($translatorsResult);
$newsItemContentResult = $this->ContentspracheModel->loadWhere([
'content_id' => $newsItem->content_id,
'sprache' => 'German'
]);
$newsItemContentEntry = getData($newsItemContentResult)[0] ?? null;
if ($newsItemContentEntry) {
$newsItem->sichtbar = $newsItemContentEntry->sichtbar ?? false;
$newsItem->content = $newsItemContentEntry->content;
}
$content = getData(
$this->cmslib->createNewsContent(
$this->cmslib->createNewsWrapper($newsItem, true),
false,
""
)
);
foreach ($translators as $translator) {
sendSanchoMail(
"Sancho_Mail_News_Translation_Req",
[
"newsItemUrl" => APP_ROOT . "cis.php/CisVue/Cms/newsAdministration?newsId=" . $newsItem->news_id,
"newsItemAuthor" => $newsItem->verfasser,
"newsItemSubject" => $newsItem->betreff,
"newsItemContent" => $content
],
$translator->uid . "@" . DOMAIN,
"Übersetzung erforderlich / Translation required"
);
}
}
private function formatContentURLsToRelative($content)
{
$content = preg_replace(
'#https?://[^"\'>\s]*/(dms\.php(?:\?[^"\'>\s]*)?)#i',
'$1',
$content
);
$content = preg_replace(
'#(?:\.\./)+[^"\'>\s]*/(dms\.php(?:\?[^"\'>\s]*)?)#i',
'$1',
$content
);
$content = preg_replace(
'#/[^"\'>\s]*/(dms\.php(?:\?[^"\'>\s]*)?)#i',
'$1',
$content
);
return $content;
}
}
File diff suppressed because it is too large Load Diff
+6 -137
View File
@@ -25,19 +25,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
*/
class Ort extends FHCAPI_Controller
{
// advanced filters of getRooms: tbl_ort column => filter type, the same list as in Raumsuche.js.
// text: contains, case-insensitive; select: equals; range: <column>_min, <column>_max; flag: true; exists: not null
const ADVANCED_FILTERS = [
'ort_kurzbz' => 'text',
'bezeichnung' => 'text',
'planbezeichnung' => 'text',
'stockwerk' => 'range',
'gebteil' => 'select',
'm2' => 'range',
'lehre' => 'flag',
'content_id' => 'exists'
];
/**
* Object initialization
*/
@@ -48,10 +36,7 @@ class Ort extends FHCAPI_Controller
'ContentID' => self::PERM_LOGGED,
'getOrtKurzbzContent' => self::PERM_LOGGED,
'getRooms' => self::PERM_LOGGED,
'getTypes' => self::PERM_LOGGED,
'getRoomInfo' => self::PERM_LOGGED,
'getStandorte' => self::PERM_LOGGED,
'getAdvancedFilterOptions' => self::PERM_LOGGED
'getTypes' => self::PERM_LOGGED
]);
$this->load->model('ressource/Ort_model', 'OrtModel');
@@ -71,17 +56,6 @@ class Ort extends FHCAPI_Controller
$this->form_validation->set_rules('datum','Datum','required');
$this->form_validation->set_rules('von','Uhrzeit Von','required|regex_match[/^[0-9]{2}:[0-9]{2}$/]');
$this->form_validation->set_rules('bis','Uhrzeit Bis','required|regex_match[/^[0-9]{2}:[0-9]{2}$/]');
$this->form_validation->set_rules('standort_id','Standort','regex_match[/^([0-9]+|none)$/]');
foreach (self::ADVANCED_FILTERS as $column => $type) {
if ($type == 'range') {
$this->form_validation->set_rules($column.'_min', $column, 'numeric');
$this->form_validation->set_rules($column.'_max', $column, 'numeric');
} elseif ($type == 'flag' || $type == 'exists') {
$this->form_validation->set_rules($column, $column, 'in_list[true]');
} else {
$this->form_validation->set_rules($column, $column, 'max_length[255]');
}
}
if($this->form_validation->run() == FALSE) {
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
@@ -91,7 +65,6 @@ class Ort extends FHCAPI_Controller
$bis = $this->input->get('bis', TRUE);
$typ = $this->input->get('typ', TRUE);
$personenanzahl = $this->input->get('personenanzahl', TRUE);
$standort_id = $this->input->get('standort_id', TRUE);
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
@@ -101,36 +74,22 @@ class Ort extends FHCAPI_Controller
$vonStunde = getData($this->StundeModel->getStundeForTime($von))[0]->stunde;
$bisStunde = getData($this->StundeModel->getStundeForTime($bis))[0]->stunde;
$this->load->model('ressource/Ort_model', 'OrtModel');
$params = array();
$qry = "SELECT DISTINCT tbl_ort.*, tbl_standort.bezeichnung AS standort
$qry = "SELECT DISTINCT tbl_ort.*
FROM public.tbl_ort JOIN public.tbl_ortraumtyp USING(ort_kurzbz)
LEFT JOIN public.tbl_standort USING(standort_id)
WHERE aktiv AND reservieren";
WHERE aktiv AND lehre AND ort_kurzbz NOT LIKE '\\\\_%'";
if($typ) {
$params[] = $typ;
$qry.= " AND raumtyp_kurzbz = ?";
$qry.= "AND raumtyp_kurzbz = ?";
}
if($standort_id === 'none') { // rooms without a Standort
$qry.= " AND standort_id IS NULL";
} elseif($standort_id) {
$params[] = $standort_id;
$qry.= " AND standort_id = ?";
} else {
$qry.= " AND standort_id IS NOT NULL";
}
$qry.= $this->advancedFilterSql($params);
if(!$isMitarbeiter) { // students are only allowed to get a subset defined by config
$qry.= ' AND raumtyp_kurzbz IN ?';
$params[] = $this->config->item('roomtypes_student');
$this->addMeta('config', $this->config->item('roomtypes_student'));
}
$qry.= " AND (max_person>= ? OR max_person is null)";
$qry.= "AND (max_person>= ? OR max_person is null)";
$params[] = $personenanzahl;
$qry.=" AND ort_kurzbz NOT IN
@@ -168,41 +127,6 @@ class Ort extends FHCAPI_Controller
$this->terminateWithSuccess(getData($result));
}
/**
* Standorte of the rooms that pass the base filter of getRooms
*/
public function getStandorte()
{
$qry = "SELECT DISTINCT standort_id, tbl_standort.bezeichnung
FROM public.tbl_ort JOIN public.tbl_standort USING(standort_id)
WHERE aktiv AND reservieren
ORDER BY tbl_standort.bezeichnung";
$result = $this->OrtModel->execReadOnlyQuery($qry);
$this->terminateWithSuccess($this->getDataOrTerminateWithError($result));
}
/**
* Values of the select filters: column => distinct values of the rooms that pass the base filter of getRooms
*/
public function getAdvancedFilterOptions()
{
$options = [];
foreach (self::ADVANCED_FILTERS as $column => $type) {
if ($type != 'select')
continue;
$result = $this->OrtModel->execReadOnlyQuery("SELECT DISTINCT ".$column." AS value
FROM public.tbl_ort
WHERE aktiv AND reservieren AND ".$column." <> ''
ORDER BY ".$column);
$options[$column] = array_column($this->getDataOrTerminateWithError($result), 'value');
}
$this->terminateWithSuccess($options);
}
/**
* Gets a JSON body via HTTP POST and provides the parameters
*/
@@ -250,60 +174,5 @@ class Ort extends FHCAPI_Controller
$this->terminateWithSuccess($content);
}
public function getRoomInfo()
{
$ortKurzbz = $this->input->get("ortKurzbz");
$roomResult = $this->OrtModel->getRoomInfo($ortKurzbz);
$roomData = $this->getDataOrTerminateWithError($roomResult);
$room = count($roomData) ? $roomData[0] : null;
$this->terminateWithSuccess($room);
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
/**
* SQL conditions of the advanced filters in the GET parameters, adds their values to $params
*/
private function advancedFilterSql(&$params)
{
// no xss_clean: the values are bound, and it could change a select value so that it no longer equals the column
$sql = '';
foreach (self::ADVANCED_FILTERS as $column => $type) {
if ($type == 'range') {
$min = $this->input->get($column.'_min');
$max = $this->input->get($column.'_max');
if ($min !== null && $min !== '') {
$sql.= " AND tbl_ort.".$column." >= ?::numeric";
$params[] = $min;
}
if ($max !== null && $max !== '') {
$sql.= " AND tbl_ort.".$column." <= ?::numeric";
$params[] = $max;
}
continue;
}
$value = $this->input->get($column);
if ($value === null || $value === '')
continue;
if ($type == 'flag') {
$sql.= " AND tbl_ort.".$column;
} elseif ($type == 'exists') {
$sql.= " AND tbl_ort.".$column." IS NOT NULL";
} elseif ($type == 'select') {
$sql.= " AND tbl_ort.".$column." = ?";
$params[] = $value;
} else {
$sql.= " AND strpos(lower(tbl_ort.".$column."), lower(?)) > 0";
$params[] = $value;
}
}
return $sql;
}
}
@@ -1,6 +1,6 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,61 +0,0 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Permission extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getPermissions' => self::PERM_LOGGED,
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* retrieves permissions for auth user
* @access public
*/
public function getPermissions()
{
$permissionsParam = $this->input->post("permissions");
if (!$permissionsParam || !is_array($permissionsParam)) {
$this->terminateWithError("Invalid parameter!");
}
$permissions = [];
foreach ($permissionsParam as $permission) {
$permissions[$permission] = $this->permissionlib->isBerechtigt($permission);
}
$this->terminateWithSuccess($permissions);
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
}
@@ -1,67 +0,0 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Reservierung extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getMyReservation' => 'basis/cis:r',
'deleteReservation' => 'lehre/reservierung:rw'
]);
$this->load->model('ressource/Reservierung_model', 'ReservierungModel');
}
/**
* Retrieves all reservations from lehre.vw_reservation of the logged in user
*/
public function getMyReservation()
{
$result = $this->ReservierungModel->getMyReservation();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* deletes a reservation by ID
*/
public function deleteReservation()
{
$reservierung_id = $this->input->post('reservierung_id');
if ($reservierung_id === NULL || trim((string)$reservierung_id) === '') {
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
}
$result = $this->ReservierungModel->deleteReservation($reservierung_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -25,7 +25,7 @@ class RouteInfo extends FHCAPI_Controller
public function __construct()
{
parent::__construct([
'info' => self::PERM_LOGGED,
'info' => self::PERM_ANONYMOUS,
]);
$this->load->model('system/Webservicelog_model', 'WebservicelogModel');
@@ -33,6 +33,8 @@ class RouteInfo extends FHCAPI_Controller
public function info()
{
if (!getAuthUID()) $this->terminateWithSuccess(null);
$payload = json_decode($this->input->raw_input_stream);
if (isset($payload->app) && isset($payload->path) && $this->isValidApp($payload->app) && $this->isValidPath($payload->path))
@@ -27,7 +27,7 @@ class Studgang extends FHCAPI_Controller
{
parent::__construct([
'getStudiengangInfo'=> self::PERM_LOGGED,
'getDegreePrograms'=> self::PERM_LOGGED,
]);
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
@@ -43,46 +43,15 @@ class Studgang extends FHCAPI_Controller
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getDegreePrograms() {
$entitledDegreePrograms = $this->permissionlib->getSTG_isEntitledFor("basis/news");
if (!$entitledDegreePrograms) {
$this->terminateWithError("User is not entitled for any degree program");
}
$activeDegreePrograms = $this->StudiengangModel->getDegreePrograms();
$activeDegreePrograms= $this->getDataOrTerminateWithError($activeDegreePrograms);
$activeDegreePrograms = array_values(array_filter($activeDegreePrograms, function($degreeProgram) use ($entitledDegreePrograms) {
return in_array($degreeProgram->studiengang_kz, $entitledDegreePrograms);
}));
$this->terminateWithSuccess($activeDegreePrograms);
}
public function getStudiengangInfo(){
$studiengang_kz = $this->input->get('studiengang_kz', true);
$semester = $this->input->get('semester', true);
// without a Studiengang the info of the logged in Student is returned
if (!is_numeric($studiengang_kz))
{
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID());
$isMitarbeiter = $this->getDataOrTerminateWithError($isMitarbeiter);
if($isMitarbeiter) {
$this->terminateWithSuccess(null);
}
$studiengang_kz = null;
$semester = null;
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID());
$isMitarbeiter = $this->getDataOrTerminateWithError($isMitarbeiter);
if($isMitarbeiter) {
$this->terminateWithSuccess(null);
}
else
{
$studiengang_kz = (int)$studiengang_kz;
$semester = is_numeric($semester) ? (int)$semester : null;
}
// fetches the Studiengang Information which is used next to the news
$studiengangInfo = $this->StudiengangModel->getStudiengangInfoForNews($studiengang_kz, $semester);
$studiengangInfo = $this->StudiengangModel->getStudiengangInfoForNews();
$studiengangInfo= $this->getDataOrTerminateWithError($studiengangInfo);
$this->terminateWithSuccess($studiengangInfo);
}
@@ -1,67 +0,0 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Studiensemester extends FHCAPI_Controller
{
private $_ci;
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getStudiensemester'=> self::PERM_LOGGED,
]);
$this->_ci =& get_instance();
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* GET METHOD
* returns List of all studiensemester as well as current one
*/
public function getStudiensemester()
{
$this->_ci->StudiensemesterModel->addOrder("start", "DESC");
$result = $this->_ci->StudiensemesterModel->load();
$studiensemester = getData($result);
$result = $this->_ci->StudiensemesterModel->getAkt();
$aktuell = getData($result);
$this->terminateWithSuccess(array($studiensemester, $aktuell));
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
}
@@ -1,145 +0,0 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class StudstatusAntraege extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getTodos' => self::PERM_LOGGED
]);
//load models
$this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel');
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* gets all todos of antraegen of the user with stg leitungsfunction
* or list of open antraege for user with assistance function
* @access public
* @return array || []
*/
public function getTodos()
{
$uid = getAuthUID();
//at first get studiengang with leitungsfunktion
$result = $this->BenutzerfunktionModel->getSTGLByUID($uid);
if(hasData($result))
{
$funktionen = getData($result);
$studiengaenge = [];
foreach ($funktionen as $funktion) {
$studiengaenge[] = $funktion->studiengang_kz;
}
$dataAntrage = [];
$result = $this->StudierendenantragModel->getOpenAntraegeForStgl($studiengaenge);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$dataAntrage[] = getData($result) ?: [];
$statusRole = 1;
$this->terminateWithSuccess([count($dataAntrage) > 0 ? $dataAntrage[0] : $dataAntrage, $statusRole]);
}
//TODO delete after check if needed or not
//get studiengaenge of assistance (regarding benutzerfunktion)
//$result = $this->BenutzerfunktionModel->getSTGAssByUID($uid);
/* if(hasData($result)) {
$statusRole = 2;
$funktionen = getData($result);
$studiengaenge = [];
foreach ($funktionen as $funktion) {
$studiengaenge[] = $funktion->studiengang_kz;
}
$ci->addMeta('stgAss', $studiengaenge);
$dataAntrage = [];
foreach ($studiengaenge as $studiengang)
{
$result = $this->StudierendenantragModel->getOpenAntraegeForAss($studiengang);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
if(hasData($result)) {
$dataAntrage[] = getData($result);
$statusRole = 2;
}
}
}
else
{
$statusRole = 0;
$dataAntrage = [];
//$this->terminateWithSuccess([[], $statusRole]);
}*/
//get studiengaenge of assistance (regarding rights)
$stgAss = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag');
if(!is_array($stgAss))
{
$statusRole = 0;
$this->terminateWithSuccess([[], $statusRole]);
}
else {
$statusRole = 2;
$studiengaenge = [];
foreach ($stgAss as $stg) {
$studiengaenge[] = (int) $stg;
}
$dataAntrage = [];
$result = $this->StudierendenantragModel->getOpenAntraegeForAss($studiengaenge);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
if(hasData($result)) {
$dataAntrage[] = getData($result);
$statusRole = 2;
}
$this->terminateWithSuccess([count($dataAntrage) > 0 ? $dataAntrage[0] : $dataAntrage, $statusRole]);
}
}
}
@@ -1,367 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Zeitsperren extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getZeitsperrenUser' => ['cis/eigene_zeitsperren:r', 'admin:r', 'assistenz:r'],
'getTypenZeitsperren' => self::PERM_LOGGED,
'getTypenErreichbarkeit' => self::PERM_LOGGED,
'getStunden' => self::PERM_LOGGED,
'loadZeitsperre' => ['cis/eigene_zeitsperren:r', 'admin:r', 'assistenz:r'],
'add' => ['cis/eigene_zeitsperren:rw', 'admin:rw', 'assistenz:rw'],
'update' => ['cis/eigene_zeitsperren:rw', 'admin:rw', 'assistenz:rw'],
'delete' => ['cis/eigene_zeitsperren:rw', 'admin:rw', 'assistenz:rw'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'person',
'zeitsperren'
]);
// Load models
$this->load->model('ressource/Zeitsperre_model', 'ZeitsperreModel');
$this->load->model('ressource/Zeitsperretyp_model', 'ZeitsperretypModel');
$this->load->model('ressource/Erreichbarkeit_model', 'ErreichbarkeitModel');
$this->load->model('ressource/Stunde_model', 'StundeModel');
$this->load->model('ressource/Zeitaufzeichnung_model', 'ZeitaufzeichnungModel');
}
public function getZeitsperrenUser($uid)
{
//check if $uid is passedUser
$loggedInUser = getAuthUID();
if($loggedInUser != $uid) {
$this->load->library('PermissionLib');
$isAdmin = $this->permissionlib->isBerechtigt('admin');
if(!$isAdmin) {
$this->terminateWithError($this->p->t('ui', 'noAdmin'), self::ERROR_TYPE_GENERAL);
}
}
$result = $this->ZeitsperreModel->getZeitsperrenUser($uid);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getTypenZeitsperren()
{
$excludedTypes = array('ZVerfueg');
$result = $this->ZeitsperretypModel->getTypenZeitsperren($excludedTypes);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getTypenErreichbarkeit()
{
$result = $this->ErreichbarkeitModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getStunden()
{
$this->StundeModel->addOrder('stunde', 'ASC');
$result = $this->StundeModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function loadZeitsperre($zeitsperre_id)
{
$this->ZeitsperreModel->addSelect(
'campus.tbl_zeitsperre.*, typ.*,
ma.person_id AS ma_person_id, ma.vorname AS ma_vorname, ma.nachname AS ma_nachname,
ma.titelpre AS ma_titelpre, ma.titelpost AS ma_titelpost'
);
$this->ZeitsperreModel->addJoin('campus.tbl_zeitsperretyp typ', 'ON (typ.zeitsperretyp_kurzbz = campus.tbl_zeitsperre.zeitsperretyp_kurzbz)');
$this->ZeitsperreModel->addJoin('public.tbl_benutzer ben', 'ON (ben.uid = campus.tbl_zeitsperre.vertretung_uid)', 'LEFT');
$this->ZeitsperreModel->addJoin('public.tbl_person ma', 'ON (ma.person_id = ben.person_id)', 'LEFT');
$result = $this->ZeitsperreModel->loadWhere(
array('zeitsperre_id' => $zeitsperre_id)
);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((current(getData($result)) ?: []));
}
public function add($mitarbeiter_uid)
{
$loggedInUser = getAuthUID();
if($mitarbeiter_uid != $loggedInUser)
$this->terminateWithError($this->p->t('ui', 'noPermission'), self::ERROR_TYPE_GENERAL);
$this->form_validation->set_rules('zeitsperretyp_kurzbz', 'Grund Zeitsperre', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Grund Zeitsperre'])
]);
$this->form_validation->set_rules('vondatum', 'VonDatum', 'required|is_valid_date', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'VonDatum']),
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VonDatum'])
]);
$this->form_validation->set_rules('bisdatum', 'BisDatum', 'required|is_valid_date|callback_check_von_bis_datum|callback_check_diff_intval', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'BisDatum']),
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'BisDatum']),
'check_von_bis_datum' => $this->p->t('zeitsperre', 'error_VonDatumGroesserAlsBisDatum'),
'check_diff_intval' => $this->p->t('zeitsperre', 'error_zeitraumAuffallendHoch')
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$bezeichnung = $this->input->post('bezeichnung');
$vondatum = $this->input->post('vondatum');
$vonstunde = $this->input->post('vonstunde');
$bisdatum = $this->input->post('bisdatum');
$bisstunde = $this->input->post('bisstunde');
//$vonIso = $this->input->post('vonISO'); //Timestamp für Stunde
//$bisIso = $this->input->post('bisISO'); //Timestamp für Stunde
$erreichbarkeit_kurzbz = $this->input->post('erreichbarkeit_kurzbz');
$vertretung_uid = $this->input->post('vertretung_uid');
$zeitsperretyp_kurzbz = $this->input->post('zeitsperretyp_kurzbz');
//check if existing zeitsperre
$result = $this->ZeitsperreModel->getSperreByDate($mitarbeiter_uid, $vondatum, $vonstunde, true);
$data = $this->getDataOrTerminateWithError($result);
if(hasData($result))
{
$this->terminateWithError($this->p->t('zeitsperren', 'error_existingZeitsperre', ['typ'=> current($data)->zeitsperretyp_kurzbz]), self::ERROR_TYPE_GENERAL);
}
//check if existing zeitaufzeichnung
if(in_array($zeitsperretyp_kurzbz, Zeitsperre_model::BLOCKIERENDE_ZEITSPERREN))
{
$result = $this->ZeitsperreModel->existsZeitaufzeichnung($mitarbeiter_uid, $vondatum, $bisdatum);
if(hasData($result))
$this->terminateWithError($this->p->t('zeitsperren', 'error_existingZeitaufzeichnung'), self::ERROR_TYPE_GENERAL);
}
$result = $this->ZeitsperreModel->insert(
[
'mitarbeiter_uid' => $mitarbeiter_uid,
'bezeichnung' => $bezeichnung,
'vondatum' => $vondatum,
'vonstunde' => $vonstunde,
'bisdatum' => $bisdatum,
'bisstunde' => $bisstunde,
'erreichbarkeit_kurzbz' => $erreichbarkeit_kurzbz,
'zeitsperretyp_kurzbz' => $zeitsperretyp_kurzbz,
'vertretung_uid' => $vertretung_uid,
'insertvon' => $loggedInUser,
'insertamum' => date('c'),
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function update($zeitsperre_id)
{
//check if loggedin User is owner of the zeitsperre
$loggedInUser = getAuthUID();
$result = $this->ZeitsperreModel->load($zeitsperre_id);
$data = $this->getDataOrTerminateWithError($result);
$uid = current($data)->mitarbeiter_uid;
if($uid != $loggedInUser)
$this->terminateWithError($this->p->t('ui', 'noPermission'), self::ERROR_TYPE_GENERAL);
if(!$zeitsperre_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Zeitsperre_id']), self::ERROR_TYPE_GENERAL);
}
//get current params
$array_update = [
'bezeichnung',
'vondatum',
'vonstunde',
'bisdatum',
'bisstunde',
// 'vonISO', //Timestamp für Stunde
// 'bisISO', //Timestamp für Stunde
'erreichbarkeit_kurzbz',
'vertretung_uid',
'zeitsperretyp_kurzbz',
'mitarbeiter_uid',
];
$post = $this->input->post();
$update = [];
foreach ($array_update as $prop)
{
if (array_key_exists($prop, $post))
{
$update[$prop] = $post[$prop];
}
}
// Validation
$rulesDefined = false; //necessary, otherwise CI validation will always be triggered, even without rules
foreach ($update as $key => $val) {
switch ($key) {
case 'zeitsperretyp_kurzbz':
$this->form_validation->set_rules(
$key,
'Grund Zeitsperre',
'required',
['required' => $this->p->t('ui', 'error_fieldRequired', ['field'=>'Grund Zeitsperre'])]
);
$rulesDefined = true;
break;
case 'vondatum':
$this->form_validation->set_rules(
$key,
'VonDatum',
'required|is_valid_date',
[
'required' => $this->p->t('ui', 'error_fieldRequired', ['field'=>'VonDatum']),
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field'=>'VonDatum'])
]
);
$rulesDefined = true;
break;
case 'bisdatum':
$rules = 'required|is_valid_date';
if (array_key_exists('vondatum', $update)) {
$rules .= '|callback_check_von_bis_datum|callback_check_diff_intval';
}
$this->form_validation->set_rules(
$key,
'BisDatum',
$rules,
[
'required' => $this->p->t('ui', 'error_fieldRequired', ['field'=>'BisDatum']),
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field'=>'BisDatum']),
'check_von_bis_datum' => $this->p->t('zeitsperre', 'error_VonDatumGroesserAlsBisDatum'),
'check_diff_intval' => $this->p->t('zeitsperre', 'error_zeitraumAuffallendHoch')
]
);
$rulesDefined = true;
break;
}
}
if ($rulesDefined && $this->form_validation->run() == false) {
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
if(array_key_exists('vondatum', $post) || array_key_exists('bisdatum', $post))
{
$result = $this->ZeitsperreModel->load($zeitsperre_id);
$data = $this->getDataOrTerminateWithError($result);
$data = current($data);
$mitarbeiter_uid = array_key_exists('mitarbeiter_uid', $post) ? $update['mitarbeiter_uid'] : $data->mitarbeiter_uid;
$vondatum = array_key_exists('vondatum', $post) ? $update['vondatum'] : $data->vondatum;
$bisdatum = array_key_exists('bisdatum', $post) ? $update['bisdatum'] : $data->bisdatum;
$vonstunde = array_key_exists('vonstunde', $post) ? $update['vonstunde'] : $data->vonstunde;
$zeitsperretyp_kurzbz = array_key_exists('zeitsperretyp_kurzbz', $post) ? $update['zeitsperretyp_kurzbz'] : $data->zeitsperretyp_kurzbz;
$result = $this->ZeitsperreModel->getSperreByDate($mitarbeiter_uid, $vondatum, $vonstunde, true);
$data = $this->getDataOrTerminateWithError($result);
if(hasData($result))
{
$this->terminateWithError($this->p->t('zeitsperren', 'error_existingZeitsperre', ['typ'=> current($data)->zeitsperretyp_kurzbz]), self::ERROR_TYPE_GENERAL);
}
//check if existing zeitaufzeichnung
if(in_array($zeitsperretyp_kurzbz, Zeitsperre_model::BLOCKIERENDE_ZEITSPERREN))
{
$result = $this->ZeitsperreModel->existsZeitaufzeichnung($mitarbeiter_uid, $vondatum, $bisdatum);
if(hasData($result))
$this->terminateWithError($this->p->t('zeitsperren', 'error_existingZeitaufzeichnung'), self::ERROR_TYPE_GENERAL);
}
}
if (!empty($update)) {
$update['updatevon'] = $loggedInUser;
$update['updateamum'] = date('c');
$result = $this->ZeitsperreModel->update($zeitsperre_id, $update);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
else
$this->terminateWithSuccess("no update");
}
public function delete($zeitsperre_id)
{
if (!is_numeric($zeitsperre_id) || (int)$zeitsperre_id <= 0)
{
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Zeitsperre_id']), self::ERROR_TYPE_GENERAL);
}
//check if loggedin User is owner of the zeitsperre
$loggedInUser = getAuthUID();
$result = $this->ZeitsperreModel->load($zeitsperre_id);
$data = $this->getDataOrTerminateWithError($result);
$uid = current($data)->mitarbeiter_uid;
if($uid != $loggedInUser)
$this->terminateWithError($this->p->t('ui', 'noPermission'), self::ERROR_TYPE_GENERAL);
$result = $this->ZeitsperreModel->delete(
array('zeitsperre_id' => $zeitsperre_id)
);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function check_von_bis_datum($bisdatum)
{
$vondatum = $this->input->post('vondatum');
return $vondatum <= $bisdatum;
}
public function check_diff_intval($bisdatum)
{
$vondatum = $this->input->post('vondatum');
// Intervall in days
$vonTs = strtotime($vondatum);
$bisTs = strtotime($bisdatum);
$tage = ($bisTs - $vonTs) / 86400;
// if intervall > 14
return $tage <= 14;
}
}
@@ -16,8 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH'))
exit('No direct script access allowed');
if (! defined('BASEPATH')) exit('No direct script access allowed');
class RoomPlan extends FHCAPI_Controller
{
@@ -34,7 +33,6 @@ class RoomPlan extends FHCAPI_Controller
'getGruppen' => self::PERM_LOGGED,
'getLektor' => self::PERM_LOGGED,
'getReservableMap' => self::PERM_LOGGED,
'getGroupOptions' => self::PERM_LOGGED,
]);
$this->load->library('LogLib');
@@ -151,14 +149,16 @@ class RoomPlan extends FHCAPI_Controller
$this->GruppeModel->addOrder('gruppe_kurzbz');
$this->GruppeModel->db->group_start();
foreach ($query_words as $word) {
foreach ($query_words as $word)
{
$this->GruppeModel->db->group_start();
$this->GruppeModel->db->where('gruppe_kurzbz ILIKE', "%" . $word . "%");
$this->GruppeModel->db->or_where('bezeichnung ILIKE', "%" . $word . "%");
$this->GruppeModel->db->or_where('beschreibung ILIKE', "%" . $word . "%");
$this->GruppeModel->db->or_where('orgform_kurzbz ILIKE', "%" . $word . "%");
if (is_numeric($word)) {
if (is_numeric($word))
{
$this->GruppeModel->db->or_where('studiengang_kz', $word);
}
$this->GruppeModel->db->group_end();
@@ -193,7 +193,8 @@ class RoomPlan extends FHCAPI_Controller
$this->MitarbeiterModel->addJoin('public.tbl_person', 'person_id');
$this->MitarbeiterModel->db->where('public.tbl_benutzer.aktiv', true);
$this->MitarbeiterModel->db->group_start();
foreach ($query_words as $word) {
foreach ($query_words as $word)
{
$this->MitarbeiterModel->db->group_start();
$this->MitarbeiterModel->db->where('tbl_person.vorname ILIKE', "%" . $word . "%");
$this->MitarbeiterModel->db->or_where('tbl_person.nachname ILIKE', "%" . $word . "%");
@@ -228,49 +229,4 @@ class RoomPlan extends FHCAPI_Controller
$this->terminateWithSuccess(array('reservierbarMap' => hasData($result) ? getData($result) : []));
}
public function getGroupOptions()
{
$studiengangKz = $this->input->get('studiengangKz');
$this->load->model('organisation/Lehrverband_model', 'LehrverbandModel');
$this->LehrverbandModel->addSelect('semester, verband, gruppe');
$this->LehrverbandModel->db->where('aktiv', true);
$this->LehrverbandModel->db->where('studiengang_kz', $studiengangKz);
$lehrverbandResult = $this->LehrverbandModel->load();
if (isError($lehrverbandResult))
$this->terminateWithError($lehrverbandResult);
$lehrverbanden = hasData($lehrverbandResult) ? getData($lehrverbandResult) : [];
$grouppedValues = [];
foreach ($lehrverbanden as $lehrverband) {
if (isset($grouppedValues[$lehrverband->semester]) && $lehrverband->verband !== ' ') {
$grouppedValues[$lehrverband->semester][] = $lehrverband;
} else if (!isset($grouppedValues[$lehrverband->semester]) && $lehrverband->verband !== ' ') {
$grouppedValues[$lehrverband->semester] = [$lehrverband];
} else if (!isset($grouppedValues[$lehrverband->semester])) {
$grouppedValues[$lehrverband->semester] = [];
}
}
$grouppedValues = array_map(
function ($semester) {
$verbandGruppen = [];
foreach ($semester as $lehrverband) {
if (isset($verbandGruppen[$lehrverband->verband]) && $lehrverband->gruppe !== ' ') {
$verbandGruppen[$lehrverband->verband][] = $lehrverband->gruppe;
} else if (!isset($verbandGruppen[$lehrverband->verband]) && $lehrverband->gruppe !== ' ') {
$verbandGruppen[$lehrverband->verband] = [$lehrverband->gruppe];
} else if (!isset($verbandGruppen[$lehrverband->verband])) {
$verbandGruppen[$lehrverband->verband] = [];
}
}
return $verbandGruppen;
},
$grouppedValues
);
$this->terminateWithSuccess($grouppedValues);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,322 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class FreeBusy extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getFreeBusyTypes' => self::PERM_LOGGED,
'getFreeBusyEntries' => self::PERM_LOGGED,
'createFreeBusyEntry' => self::PERM_LOGGED,
'updateFreeBusyEntry' => self::PERM_LOGGED,
'deleteFreeBusyEntry' => self::PERM_LOGGED,
'getFreeBusySchedule' => self::PERM_LOGGED,
'getCoodleFreeBusy' => self::PERM_ANONYMOUS,
]);
$this->load->model('person/Freebusy_model', 'FreeBusyModel');
$this->load->model('person/Freebusytyp_model', 'FreeBusyTypeModel');
$this->load->library('FreeBusyLib');
$this->load->library('form_validation');
$this->load->model("ressource/CoodleSurvey_model", "CoodleSurveyModel");
$this->load->model("ressource/CoodleSurveyTimeslot_model", "CoodleSurveyTimeslotModel");
$this->load->model("ressource/CoodleSurveyParticipant_model", "CoodleSurveyParticipantModel");
$this->loadPhrases([
'coodle'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getFreeBusyTypes()
{
$freeBusyTypesResult = $this->FreeBusyTypeModel->getActiveFreeBusyTypes();
$freeBusyTypes = $this->getDataOrTerminateWithError($freeBusyTypesResult);
$freeBusyTypes = $this->formatDefaultUrlsInFreeBusyTypes($freeBusyTypes);
$this->terminateWithSuccess($freeBusyTypes);
}
public function getFreeBusyEntries()
{
$this->FreeBusyModel->addOrder("freebusy_id");
$freeBusyEntries = $this->FreeBusyModel->loadWhere(["uid" => getAuthUID()]);
$freeBusyEntries = $this->getDataOrTerminateWithError($freeBusyEntries);
$this->terminateWithSuccess($freeBusyEntries);
}
public function createFreeBusyEntry()
{
$description = $this->input->post("description");
$type = $this->input->post("type") ?? "Sonstiges";
$url = $this->input->post("url");
$isActive = $this->input->post("isActive");
$this->form_validation->set_data([
"url" => $url,
"description" => $description,
]);
$this->form_validation->set_rules("url", "URL", "required|max_length[255]");
$this->form_validation->set_rules("description", "Description", "max_length[255]");
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
if (!$this->isUrlValid($url)) {
$this->terminateWithError($this->p->t("coodle", "url_not_working"));
}
$this->FreeBusyModel->insert(
[
"uid" => getAuthUID(),
"freebusytyp_kurzbz" => $type,
"url" => $url,
"aktiv" => $isActive,
"bezeichnung" => $description,
]
);
$this->terminateWithSuccess();
}
public function updateFreeBusyEntry()
{
$id = $this->input->post("id");
$description = $this->input->post("description");
$type = $this->input->post("type") ?? "Sonstiges";
$url = $this->input->post("url");
$isActive = $this->input->post("isActive");
$this->form_validation->set_data([
"url" => $url,
"description" => $description,
]);
$this->form_validation->set_rules("url", "URL", "required|max_length[255]");
$this->form_validation->set_rules("description", "Description", "max_length[255]");
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
if (!$this->isUrlValid($url)) {
$this->terminateWithError($this->p->t("coodle", "url_not_working"));
}
$existingFreeBusyEntryResult = $this->FreeBusyModel->load($id);
$existingFreeBusyEntry = $this->getDataOrTerminateWithError($existingFreeBusyEntryResult);
$existingFreeBusyEntry = $existingFreeBusyEntry && count($existingFreeBusyEntry) ? $existingFreeBusyEntry[0] : null;
if (!$existingFreeBusyEntry) {
$this->terminateWithError("FreeBusy entry not found!");
} else if ($existingFreeBusyEntry->uid !== getAuthUID()) {
$this->terminateWithError("You are not authorized to modify this FreeBusy entry!");
}
$this->FreeBusyModel->update(
$id,
[
"uid" => getAuthUID(),
"freebusytyp_kurzbz" => $type,
"url" => $url,
"aktiv" => $isActive,
"bezeichnung" => $description,
]
);
$this->terminateWithSuccess();
}
public function deleteFreeBusyEntry()
{
$id = $this->input->post("id");
$existingFreeBusyEntryResult = $this->FreeBusyModel->load($id);
$existingFreeBusyEntry = $this->getDataOrTerminateWithError($existingFreeBusyEntryResult);
$existingFreeBusyEntry = $existingFreeBusyEntry && count($existingFreeBusyEntry) ? $existingFreeBusyEntry[0] : null;
if (!$existingFreeBusyEntry) {
$this->terminateWithError("FreeBusy entry not found!");
} else if ($existingFreeBusyEntry->uid !== getAuthUID()) {
$this->terminateWithError("You are not authorized to delete this FreeBusy entry!");
}
$this->FreeBusyModel->delete($id);
$this->terminateWithSuccess();
}
public function getFreeBusySchedule()
{
$uid = $this->input->post("uid");
$coodleSurveyIdToExclude = $this->input->post("coodleSurveyIdToExclude");
$freeBusyEntries = $this->FreeBusyModel->loadWhere(["uid" => $uid, "aktiv" => true]);
$freeBusyEntries = $this->getDataOrTerminateWithError($freeBusyEntries);
$cumulativeFreeBusyEvents = $this->freebusylib->getDefaultInternalFreeBusy($uid);
foreach ($freeBusyEntries as $freeBusyEntry) {
// todo: following workaround is to use new coodle freebusy endpoint, remove once actual redirect is set up
// keep query param with excluded survey id, only remove url replacement
$freeBusyUrl = $freeBusyEntry->url;
if ($freeBusyEntry->freebusytyp_kurzbz === "Coodle") {
$freeBusyUrl = APP_ROOT . "cis.php/CoodleFreeBusy/" . $uid;
if ($coodleSurveyIdToExclude) {
$freeBusyUrl .= "?excludeSurvey=" . $coodleSurveyIdToExclude;
}
}
$freeBusyEvents = $this->freebusylib->getFreeBusy($freeBusyUrl);
$cumulativeFreeBusyEvents = array_merge(
$cumulativeFreeBusyEvents,
$freeBusyEvents
);
}
$this->terminateWithSuccess($cumulativeFreeBusyEvents);
}
public function getCoodleFreeBusy($uid)
{
$participantEntries = $this->CoodleSurveyParticipantModel->getParticipantEntriesByUid($uid);
$surveys = [];
if (count($participantEntries)) {
$surveyIds = array_map(
function ($participantEntry) {
return $participantEntry->survey_id;
},
$participantEntries
);
$surveys = $this->CoodleSurveyModel->getSurveys($surveyIds);
}
$surveyIdToBeExcluded = $this->input->get("excludeSurvey");
if ($surveyIdToBeExcluded) {
$surveyIdToBeExcluded = intval($surveyIdToBeExcluded);
$surveys = array_filter(
$surveys,
function ($survey) use ($surveyIdToBeExcluded) {
return $survey->id !== $surveyIdToBeExcluded;
}
);
}
$activeSurveys = array_filter(
$surveys,
function ($survey) {
return !$survey->completed_at && !$survey->canceled_at;
}
);
$timeslots = [];
if (count($activeSurveys)) {
$activeSurveyIds = array_map(
function ($activeSurvey) {
return $activeSurvey->id;
},
$activeSurveys
);
$timeslots = $this->CoodleSurveyTimeslotModel->getTimeslotsForMultipleSurveys($activeSurveyIds);
}
$formattedTimeslots = [];
if (count($timeslots)) {
$localTimezone = new DateTimeZone("Europe/Vienna");
$utcTimezone = new DateTimeZone("UTC");
foreach ($activeSurveys as $activeSurvey) {
$correspondingTimeslots = array_filter(
$timeslots,
function ($timeslot) use ($activeSurvey) {
return $timeslot->survey_id === $activeSurvey->id;
}
);
$formattedCorrespondingTimeslots = array_map(
function ($timeslot) use ($activeSurvey, $utcTimezone, $localTimezone) {
$startTime = new DateTime($timeslot->starts_at, $localTimezone);
$endTime = new DateTime($timeslot->starts_at, $localTimezone);
$endTime->modify("+$activeSurvey->timeslot_duration minutes");
$startTime->setTimezone($utcTimezone);
$endTime->setTimezone($utcTimezone);
$formattedStartTime = $startTime->format("Ymd\THis\Z");
$formattedEndTime = $endTime->format("Ymd\THis\Z");
return [
"start" => $formattedStartTime,
"end" => $formattedEndTime,
];
},
$correspondingTimeslots
);
$formattedTimeslots = array_merge($formattedTimeslots, $formattedCorrespondingTimeslots);
}
}
$coodleFreeBusyIcsFilePath = tempnam(sys_get_temp_dir(), "coodle_freebusy_");
$coodleFreeBusyIcsFile = fopen($coodleFreeBusyIcsFilePath, "w");
fwrite($coodleFreeBusyIcsFile, "BEGIN:VCALENDAR" . PHP_EOL);
fwrite($coodleFreeBusyIcsFile, "VERSION:2.0" . PHP_EOL);
fwrite($coodleFreeBusyIcsFile, "PRDODID:" . CAMPUS_NAME . PHP_EOL);
fwrite($coodleFreeBusyIcsFile, "ATTENDEE:mailto:" . $uid . "@" . DOMAIN . PHP_EOL);
fwrite($coodleFreeBusyIcsFile, "BEGIN:VFREEBUSY" . PHP_EOL);
foreach ($formattedTimeslots as $timeslot) {
fwrite($coodleFreeBusyIcsFile, "FREEBUSY;FBTYPE=BUSY:" . $timeslot["start"] . "/" . $timeslot["end"] . PHP_EOL);
}
fwrite($coodleFreeBusyIcsFile, "END:VFREEBUSY" . PHP_EOL);
fwrite($coodleFreeBusyIcsFile, "END:VCALENDAR");
$this->terminateWithFileOutput("text/calendar", file_get_contents($coodleFreeBusyIcsFilePath), "coodle_freebusy_$uid.ics");
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
private function isUrlValid($url)
{
return !!@fopen($url, "r");
}
private function formatDefaultUrlsInFreeBusyTypes($freeBusyTypes)
{
$uid = getAuthUID();
return array_map(function ($freeBusyType) use ($uid) {
if (!$freeBusyType->url_vorlage || !strlen($freeBusyType->url_vorlage)) {
$freeBusyType->url_default = null;
unset($freeBusyType->url_vorlage);
return $freeBusyType;
}
$freeBusyType->url_default = str_replace('$uid', $uid, $freeBusyType->url_vorlage);
unset($freeBusyType->url_vorlage);
return $freeBusyType;
}, $freeBusyTypes);
}
}
@@ -101,9 +101,6 @@ class Widget extends FHCAPI_Controller
$tmpsetup = json_decode($widget->setup);
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
$widget->setup = $tmpsetup;
$widget->permitted = empty($widget->berechtigung_kurzbz)
|| $this->permissionlib->isBerechtigt($widget->berechtigung_kurzbz);
return $widget;
}, $widgets);
@@ -1,218 +0,0 @@
<?php
/**
* FH-Complete
*
* @package FHC-API
* @author FHC-Team
* @copyright Copyright (c) 2016, fhcomplete.org
* @license GPLv3
* @link http://fhcomplete.org
* @since Version 1.0
* @filesource
*/
// ------------------------------------------------------------------------
if (!defined('BASEPATH')) exit('No direct script access allowed');
use CI3_Events as Events;
class PaabgabeUebersicht extends FHCAPI_Controller
{
const DOWNLOAD_PERMISSION = 'lehre/abgabetool:download';
const ABGABE_TYPES = ['Bachelor', 'Diplom'];
/**
* PaabgabeUebersicht API constructor.
*/
public function __construct()
{
parent::__construct([
'viewData' => self::PERM_LOGGED,
'getPaAbgaben' => array('lehre/abgabetool:r'),
'getStudiengaenge' => array('lehre/abgabetool:r'),
'getTermine' => array('lehre/abgabetool:r'),
'getPaAbgabetypen' => array('lehre/abgabetool:r'),
'downloadZip' => array('lehre/abgabetool:r'),
//'downloadProjektarbeit' => array('lehre/abgabetool:r')
]);
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
$this->load->library('PermissionLib');
// Load Phrases
$this->loadPhrases([
'abgabetool'
]);
}
public function viewData()
{
$viewData = [
"uid" => getAuthUID(),
// TODO create permission
"showEdit" => true,
];
$this->terminateWithSuccess($viewData);
}
/**
* Get Projektabgaben for search criteria.
*/
public function getPaAbgaben()
{
$studiengang_kz = $this->input->get('studiengang_kz');
$abgabetyp_kurzbz = $this->input->get('abgabetyp_kurzbz');
$abgabedatum = $this->input->get('abgabedatum');
$personSearchString = $this->input->get('personSearchString');
$result = $this->PaabgabeModel->getPaAbgaben(self::ABGABE_TYPES, $studiengang_kz, $abgabetyp_kurzbz, $abgabedatum, $personSearchString);
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
// check wether Abgabe is in visual library
if (hasData($result))
{
Events::trigger('in_visual_library', getData($result));
}
$this->terminateWithSuccess(getData($result) ?: []);
}
/**
* Get all Studiengänge for which user is entitled for
*/
public function getStudiengaenge()
{
$studiengang_kz_arr = $this->permissionlib->getSTG_isEntitledFor(self::DOWNLOAD_PERMISSION);
if (!$studiengang_kz_arr) $this->terminateWithSuccess([]);
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$this->StudiengangModel->addSelect('tbl_studiengang.*, UPPER(tbl_studiengang.typ || tbl_studiengang.kurzbz) AS kuerzel', $studiengang_kz_arr);
$this->StudiengangModel->db->where_in('studiengang_kz', $studiengang_kz_arr);
$this->StudiengangModel->addOrder('typ, kurzbz');
$result = $this->StudiengangModel->load();
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
$this->terminateWithSuccess((getData($result) ?: []));
}
/**
* Get projekt work due dates, depending on search criteria.
*/
public function getTermine()
{
$studiengang_kz = $this->input->get('studiengang_kz');
$abgabetyp_kurzbz = $this->input->get('abgabetyp_kurzbz');
$result = $this->PaabgabeModel->getTermine(self::ABGABE_TYPES, $studiengang_kz, $abgabetyp_kurzbz);
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
$this->terminateWithSuccess((getData($result) ?: []));
}
/**
* Get all submission types.
*/
public function getPaAbgabetypen()
{
// Load model PaabgabetypModel
$this->load->model('education/Paabgabetyp_model', 'PaabgabetypModel');
$this->PaabgabetypModel->addOrder('bezeichnung');
$result = $this->PaabgabetypModel->load();
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
$this->terminateWithSuccess((getData($result) ?: []));
}
/**
* Download zip files with project works matching submission search criteria.
*/
public function downloadZip()
{
$studiengang_kz = $this->input->get('studiengang_kz');
$abgabetyp_kurzbz = $this->input->get('abgabetyp_kurzbz');
$abgabedatum = $this->input->get('abgabedatum');
$personSearchString = $this->input->get('personSearchString');
if (!isset($studiengang_kz) && !isset($abgabetyp_kurzbz) && !isset($abgabedatum) && !isset($personSearchString))
$this->terminateWithFileOutput('text/plain', $this->p->t('abgabetool', 'nichtsAusgewaehlt'));
$this->load->library('zip');
$result = $this->PaabgabeModel->getPaAbgaben(self::ABGABE_TYPES, $studiengang_kz, $abgabetyp_kurzbz, $abgabedatum, $personSearchString);
if (isError($result)) $this->terminateWithFileOutput('text/plain', getError($result));
$fileExists = false;
$studiengang_kuerzel = null;
if (!hasData($result)) $this->terminateWithFileOutput('text/plain', $this->p->t('abgabetool', 'keineDateienVorhanden'));
$abgaben = getData($result);
foreach ($abgaben as $abgabe)
{
$path = PAABGABE_PATH.$abgabe->paabgabe_id.'_'.$abgabe->uid.'.pdf';
if (file_exists($path))
{
$fileExists = true;
$studiengang_kuerzel = $abgabe->studiengang_kuerzel;
$this->zip->read_file($path);
}
}
if (!$fileExists) $this->terminateWithFileOutput('text/plain', $this->p->t('abgabetool', 'keineDateienVorhanden'));
$studiengang_kz = $this->input->get('studiengang_kz');
$zipFileName = 'Abgabe'.(isset($studiengang_kz) && isset($studiengang_kuerzel) ? '_'.$studiengang_kuerzel : '').'.zip';
$this->zip->download($zipFileName);
}
/**
* Download Projektarbeit document.
*/
//~ public function downloadProjektarbeit()
//~ {
//~ $paabgabe_id = $this->input->get('paabgabe_id');
//~ if (!is_numeric($paabgabe_id))
//~ $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Abgabe ID']), self::ERROR_TYPE_GENERAL);
//~ //$abgabeRes = $this->PaabgabeModel->getEndabgabe($projektarbeit_id);
//~ $this->PaabgabeModel->addSelect("paabgabe_id, student_uid, tbl_paabgabe.datum, tbl_paabgabe.abgabedatum, projekttyp_kurzbz, titel, titel_english,
//~ paabgabe_id || '_' || student_uid || '.pdf' AS filename");
//~ $this->PaabgabeModel->addJoin('lehre.tbl_projektarbeit', 'projektarbeit_id');
//~ $abgabeRes = $this->PaabgabeModel->load($paabgabe_id);
//~ if (isError($abgabeRes))
//~ show_error(getError($abgabeRes));
//~ if (hasData($abgabeRes))
//~ {
//~ $endabgabe = getData($abgabeRes)[0];
//~ $filepath = PAABGABE_PATH.$endabgabe->filename;
//~ if (file_exists($filepath))
//~ {
//~ $this->output
//~ ->set_status_header(200)
//~ ->set_content_type('application/pdf', 'utf-8')
//~ ->set_header('Content-Disposition: attachment; filename="'.$endabgabe->filename.'"')
//~ ->set_output(file_get_contents($filepath))
//~ ->_display();
//~ }
//~ else
//~ {
//~ show_error("File does not exist.");
//~ }
//~ }
//~ }
}
@@ -12,9 +12,9 @@ class Funktionen extends FHCAPI_Controller
parent::__construct(array(
'getAllFunctions' => ['admin:r', 'assistenz:r'],
'getAllUserFunctions' => ['admin:r', 'assistenz:r'],
'getOrgHeads' => self::PERM_LOGGED,
'getOrgetsForCompany' => self::PERM_LOGGED,
'getAllOrgUnits' => self::PERM_LOGGED,
'getOrgHeads' => ['admin:r', 'assistenz:r'],
'getOrgetsForCompany' => ['admin:r', 'assistenz:r'],
'getAllOrgUnits' => ['admin:r', 'assistenz:r'],
'loadFunction' => ['admin:r', 'assistenz:r'],
'insertFunction' => ['admin:rw', 'assistenz:rw'],
'updateFunction' => ['admin:rw', 'assistenz:rw'],
@@ -1,81 +0,0 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Betreuungen extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getBetreuungen' => self::PERM_LOGGED,
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getBetreuungen()
{
$semester = $this->input->get("semester");
if (!$semester) $this->terminateWithError("Missing parameters!");
$personId = getAuthPersonId();
$betreuungenQuery = "SELECT
tbl_lehrveranstaltung.bezeichnung,
tbl_projektarbeit.titel,
(SELECT nachname || ' ' || (CASE WHEN wahlname IS NOT NULL THEN wahlname ELSE vorname END)
FROM public.tbl_benutzer
JOIN public.tbl_person USING(person_id)
WHERE uid=student_uid)
as name,
(SELECT uid
FROM public.tbl_benutzer
WHERE uid=student_uid)
as uid,
tbl_lehrveranstaltung.studiengang_kz,
tbl_lehrveranstaltung.semester,
tbl_studiengang.kurzbzlang as studiengang,
tbl_studiengang.email,
tbl_betreuerart.beschreibung AS beutreuerart_beschreibung,
tbl_projektbetreuer.stunden
FROM
lehre.tbl_lehrveranstaltung, lehre.tbl_projektarbeit, lehre.tbl_projektbetreuer, public.tbl_studiengang, lehre.tbl_betreuerart
WHERE
tbl_lehrveranstaltung.lehrveranstaltung_id=tbl_projektarbeit.lehrveranstaltung_id AND
tbl_projektarbeit.studiensemester_kurzbz = '$semester' AND
tbl_projektarbeit.projektarbeit_id = tbl_projektbetreuer.projektarbeit_id AND
tbl_lehrveranstaltung.studiengang_kz = tbl_studiengang.studiengang_kz AND
tbl_projektbetreuer.betreuerart_kurzbz = tbl_betreuerart.betreuerart_kurzbz AND
tbl_projektbetreuer.person_id = '$personId'";
$this->addMeta("query", $betreuungenQuery);
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->execReadOnlyQuery($betreuungenQuery);
$result = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($result);
}
}
@@ -19,8 +19,7 @@ class Lehreinheit extends FHCAPI_Controller
'getLehrfach' => ['admin:r', 'assistenz:r'],
'getSprache' => ['admin:r', 'assistenz:r'],
'getRaumtyp' => ['admin:r', 'assistenz:r'],
'getLehrform' => ['admin:r', 'assistenz:r'],
'getLehreinheitenBySemester' => self::PERM_LOGGED,
'getLehrform' => ['admin:r', 'assistenz:r']
]);
$this->_ci = &get_instance();
@@ -439,27 +438,6 @@ class Lehreinheit extends FHCAPI_Controller
$this->terminateWithSuccess($this->p->t('global', 'gespeichert'));
}
public function getLehreinheitenBySemester()
{
$semester = $this->input->get('semester');
$lehreinheiten = $this->LehreinheitModel->getLehrenheitenBySemester(getAuthUID(), $semester);
$lehreinheiten = $this->getDataOrTerminateWithError($lehreinheiten);
foreach ($lehreinheiten as $lehreinheit) {
$groups = $this->LehreinheitModel->getGroupsByLehreinheit($lehreinheit->lehreinheit_id);
$groups = $this->getDataOrTerminateWithError($groups);
$stgKurzbz = $lehreinheit->stg_kurzbz;
$lehreinheit->groups = array_map(
function ($group) use ($stgKurzbz) {
return $group->gruppe_kurzbz ?? $stgKurzbz . "-" . $group->semester . $group->verband . $group->gruppe;
},
$groups
);
}
$this->terminateWithSuccess($lehreinheiten);
}
private function checkPermission($lehreinheit_id)
{
@@ -28,8 +28,7 @@ class Studiensemester extends FHCAPI_Controller
'getStudienjahrByStudiensemester' => self::PERM_LOGGED,
'getAllStudiensemesterAndAktOrNext' => self::PERM_LOGGED,
'current' => self::PERM_LOGGED,
'set' => self::PERM_LOGGED,
'getContainingOrNearestByDateRange' => self::PERM_LOGGED,
'set' => self::PERM_LOGGED
)
);
// Load model StudiensemesterModel
@@ -204,15 +203,4 @@ class Studiensemester extends FHCAPI_Controller
$this->terminateWithSuccess(true);
}
public function getContainingOrNearestByDateRange()
{
$from = $this->input->get("from");
$to = $this->input->get("to");
$result = $this->StudiensemesterModel->getContainingOrNearestByDateRange($from, $to);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -41,9 +41,6 @@ class Grades extends FHCAPI_Controller
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('PruefungsverlaufLib', null, 'VerlaufLib');
$this->load->config('noten');
// Load Phrases
$this->loadPhrases([
@@ -358,24 +355,23 @@ class Grades extends FHCAPI_Controller
$data['lehrveranstaltung_id'] = $lehrveranstaltung_id;
$data['student_uid'] = $student_uid;
$data['studiensemester_kurzbz'] = $studiensemester_kurzbz;
$this->ZeugnisnoteModel->insert($data);
if (defined('FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN')
&& FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN) {
$result = $this->addTestsForGrade(
$studiensemester_kurzbz,
$student_uid,
$lehrveranstaltung_id,
$teacherGrade->note,
$teacherGrade->punkte
);
$this->getDataOrTerminateWithError($result);
}
}
// Der erste Antritt wird bereits bei der Übernahme als eigene Prüfung angelegt, damit der
// Prüfungsverlauf von Anfang an vollständig ist und das Benotungstool ihn nicht erst beim
// Anlegen einer Wiederholung nachtragen muss. Läuft bewusst in BEIDEN Zweigen (auch beim
// Überschreiben einer bestehenden Zeugnisnote) und ist idempotent.
if ($this->config->item('CIS_GESAMTNOTE_ERSTANTRITT_BEI_UEBERNAHME')) {
$result = $this->addErstantrittForGrade(
$studiensemester_kurzbz,
$student_uid,
$lehrveranstaltung_id,
$teacherGrade
);
$this->getDataOrTerminateWithError($result);
}
$this->terminateWithSuccess(true);
}
@@ -495,32 +491,20 @@ class Grades extends FHCAPI_Controller
}
/**
* Legt bei der Notenübernahme den ersten Prüfungsantritt als eigenen Datensatz an
* (Eintrag in lehre.tbl_pruefung).
* Helper function that adds tests for a student
* (Entries in lehre.tbl_pruefung)
*
* Idempotent: existiert für den Studenten in dieser LV bereits ein Termin, passiert nichts -
* die Übernahme darf beliebig oft laufen, ohne den Verlauf zu verfälschen.
*
* Datiert auf das Freigabedatum der LV-Note: das ist der Zeitpunkt, zu dem die
* Leistungsfeststellung verbindlich wurde. Das Benotungsdatum ändert sich bei jeder Korrektur,
* der Übernahmezeitpunkt ist reine Verwaltungsarbeit - beide taugen nicht als Termindatum.
*
* @param string $studiensemester_kurzbz
* @param string $student_uid
* @param integer $lehrveranstaltung_id
* @param stdClass $teacherGrade die übernommene LV-Gesamtnote
* @param string $studiensemester_kurzbz
* @param string $student_uid
* @param integer $lehrveranstaltung_id
* @param integer $note
* @param numeric $punkte
*
* @return stdClass
*/
protected function addErstantrittForGrade($studiensemester_kurzbz, $student_uid, $lehrveranstaltung_id, $teacherGrade)
protected function addTestsForGrade($studiensemester_kurzbz, $student_uid, $lehrveranstaltung_id, $note, $punkte)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->load->model('education/LePruefung_model', 'LePruefungModel');
// bereits ein Termin vorhanden -> der Verlauf beginnt schon, nichts nachzutragen
$vorhanden = $this->VerlaufLib->getPruefungen($student_uid, $lehrveranstaltung_id, $studiensemester_kurzbz);
if (count($vorhanden) > 0)
return success(null);
// Get Lehreinheit
$result = $this->LehrveranstaltungModel->getLeByStudent($student_uid, $studiensemester_kurzbz, $lehrveranstaltung_id);
@@ -531,24 +515,19 @@ class Grades extends FHCAPI_Controller
return error($this->p->t("stv", "grades_error_lehreinheit_id"));
$le = current(getData($result));
$datum = $teacherGrade->freigabedatum ?: ($teacherGrade->benotungsdatum ?: date('Y-m-d'));
$now = date('Y-m-d H:i:s');
// Prepare
$this->load->model('education/LePruefung_model', 'LePruefungModel');
$data = [
"student_uid" => $student_uid,
"lehreinheit_id" => $le->lehreinheit_id,
"mitarbeiter_uid" => $teacherGrade->mitarbeiter_uid,
"datum" => $datum,
"pruefungstyp_kurzbz" => $this->VerlaufLib->legacyTypFuerAntritt(1),
"note" => $teacherGrade->note,
"insertamum" => $now,
"insertvon" => getAuthUID()
"datum" => date('Y-m-d'),
"pruefungstyp_kurzbz" => "Termin1",
"note" => $note
];
if (defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE)
$data["punkte"] = $teacherGrade->punkte;
$data["punkte"] = $punkte;
// Get Anwesenheit
$this->load->model('education/Anwesenheit_model', 'AnwesenheitModel');
$result = $this->AnwesenheitModel->loadAnwesenheitStudiensemester($studiensemester_kurzbz, $student_uid, $lehrveranstaltung_id);
@@ -556,8 +535,7 @@ class Grades extends FHCAPI_Controller
return $result;
$anwesenheit = getData($result);
if (defined('FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN') && FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN
&& $anwesenheit && (float)current($anwesenheit)->prozent < FAS_ANWESENHEIT_ROT) {
if ($anwesenheit && (float)current($anwesenheit)->prozent < FAS_ANWESENHEIT_ROT) {
// Get Anwesenheitsbefreiung
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$result = $this->BenutzerfunktionModel->getBenutzerFunktionByUidInStdsem($student_uid, $studiensemester_kurzbz, 'awbefreit');
@@ -567,10 +545,7 @@ class Grades extends FHCAPI_Controller
$anwesenheitsbefreit = hasData($result);
// Bei zu geringer Anwesenheit ohne Befreiung wird ein zusätzlicher Termin
// 'Nicht beurteilt' vor dem eigentlichen Antritt festgehalten. ACHTUNG: diese Note
// zählt nicht mehr als Antritt (NOTEN_OHNE_ANTRITT_BEZEICHNUNGEN) - der frühere
// "Antritt abziehen"-Effekt entfällt damit, der Eintrag ist reine Dokumentation.
// Wenn nicht Anwesenheitsbefreit und Anwesenheit unter einem bestimmten Prozentsatz fällt dann wird ein Pruefungsantritt abgezogen
if (!$anwesenheitsbefreit) {
$data2 = $data;
$data2["note"] = 7;
@@ -581,6 +556,8 @@ class Grades extends FHCAPI_Controller
if (isError($result))
return $result;
$data["pruefungstyp_kurzbz"] = "Termin2";
}
}
@@ -574,19 +574,6 @@ class Kontakt extends FHCAPI_Controller
$person_id = $this->input->post('person_id');
$standort_id = $this->input->post('standort_id');
//check person_id: allow editing only of persons who are no mitarbeiter
if($person_id)
{
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->BenutzerModel->addJoin('public.tbl_mitarbeiter ma', 'ON (ma.mitarbeiter_uid = public.tbl_benutzer.uid)');
$result = $this->BenutzerModel->loadWhere([
'person_id' => $person_id
]);
if(hasData($result))
return $this->terminateWithError($this->p->t('ui', 'editingMitarbeiterPVonly'), self::ERROR_TYPE_GENERAL);
}
$result = $this->KontaktModel->update(
[
'kontakt_id' => $kontakt_id
@@ -370,7 +370,6 @@ class LvTermine extends FHCAPI_Controller
$result->semester = $item->semester;
$result->verband = $item->verband;
$result->gruppe = $item->gruppe;
$result->studiensemester_kurzbz = $item->studiensemester_kurzbz;
return $result;
},
$lehrverband_query_result));
@@ -42,8 +42,6 @@ class Projektarbeit extends FHCAPI_Controller
$this->load->model('education/Note_model', 'NoteModel');
$this->load->model('education/Projektbetreuer_model', 'BetreuerModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
// load libraries
$this->load->library('PermissionLib');
@@ -102,16 +100,16 @@ class Projektarbeit extends FHCAPI_Controller
private function fetchProjektarbeitById($projektarbeit_id) {
$this->ProjektarbeitModel->resetQuery();
$this->ProjektarbeitModel->addSelect(
'lehre.tbl_projektarbeit.projektarbeit_id, titel, titel_english, themenbereich, projekttyp_kurzbz, lehrveranstaltung_id, lehreinheit_id,
tbl_projektarbeit.studiensemester_kurzbz, firma_id, beginn, ende, gesperrtbis, note, final, freigegeben, tbl_projektarbeit.anmerkung, fa.name AS firma_name'
'lehre.tbl_projektarbeit.projektarbeit_id, titel, titel_english, themenbereich, projekttyp_kurzbz, lehrveranstaltung_id, lehreinheit_id,
firma_id, beginn, ende, gesperrtbis, note, final, freigegeben, tbl_projektarbeit.anmerkung, fa.name AS firma_name'
);
$this->ProjektarbeitModel->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id');
$this->ProjektarbeitModel->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id');
$this->ProjektarbeitModel->addJoin('public.tbl_firma fa', 'firma_id', 'LEFT');
return $this->ProjektarbeitModel->loadWhere(
array('projektarbeit_id' => $projektarbeit_id)
);
}
/**
@@ -248,38 +246,14 @@ class Projektarbeit extends FHCAPI_Controller
$additional_lehrveranstaltung_id = $this->input->get('additional_lehrveranstaltung_id');
if (!isset($student_uid)) $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
if (!isset($studiensemester_kurzbz)) $this->terminateWithError('Studiensemester missing', self::ERROR_TYPE_GENERAL);
if (!isset($studiensemester_kurzbz)) $this->terminateWithError('Studiensemster missing', self::ERROR_TYPE_GENERAL);
// get prestudent_id from student model
$studentRes = $this->StudentModel->load(['student_uid' => $student_uid]);
if(hasData($studentRes)) {
$student = getData($studentRes);
} else {
$this->terminateWithError($studentRes, self::ERROR_TYPE_GENERAL);
}
// to get prestudent_status history
$historyRes = $this->PrestudentstatusModel->getHistoryPrestudent($student[0]->prestudent_id);
if(hasData($historyRes)) {
$history = getData($historyRes);
} else {
$this->terminateWithError($historyRes, self::ERROR_TYPE_GENERAL);
}
// query for every lva of a studiengang that has projektarbeit flag true
// get Lvs
$lvsResult = $this->LehrveranstaltungModel->getLvsForProjektarbeit($student_uid, $studiengang_kz, $additional_lehrveranstaltung_id);
if (isError($lvsResult)) return $this->terminateWithError($lvsResult, self::ERROR_TYPE_GENERAL);
$lvs = hasData($lvsResult) ? getData($lvsResult) : [];
$lvsIDs = array_column($lvs, 'lehrveranstaltung_id');
// get current studienplan_id from status history to find out which lva options are actually assigned to the students studienplan
// important so the projektarbeit has the correct lva assigned to be able to find and print the thesis title on the degree documents!
$currentStatus = $history[0];
$lvByStudienPlanRes = $this->LehrveranstaltungModel->getLvsByStudienplanByLvaIDs($currentStatus->studienplan_id, $lvsIDs);
if(hasData($lvByStudienPlanRes)) {
$lvs = getData($lvByStudienPlanRes);
}
foreach ($lvs as $lv)
{
@@ -346,18 +320,11 @@ class Projektarbeit extends FHCAPI_Controller
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Projekttyp'])
]);
$this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'is_natural', [
$this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'required|is_natural', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehreinheit']),
'is_natural' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Lehreinheit'])
]);
$this->form_validation->set_rules('lehrveranstaltung_id', 'Lehrveranstaltung', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehrveranstaltung'])
]);
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Studiensemester'])
]);
$this->form_validation->set_rules('beginn', 'Beginn', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Beginn'])
]);
@@ -387,8 +354,6 @@ class Projektarbeit extends FHCAPI_Controller
'projekttyp_kurzbz' => $formData['projekttyp_kurzbz'],
'firma_id' => $formData['firma_id'] ?? null,
'lehreinheit_id' => $formData['lehreinheit_id'],
'lehrveranstaltung_id' => $formData['lehrveranstaltung_id'],
'studiensemester_kurzbz' => $formData['studiensemester_kurzbz'],
'beginn' => isset($formData['beginn']) && !isEmptyString($formData['beginn']) ? $formData['beginn'] : null,
'ende' => isset($formData['ende']) && !isEmptyString($formData['ende']) ? $formData['ende'] : null,
'note' => $formData['note'] ?? null,
@@ -13,7 +13,6 @@ class Mylv extends Auth_Controller
*/
public function __construct()
{
parent::__construct([
'Student' => self::PERM_LOGGED,
'Studiensemester' => self::PERM_LOGGED,
@@ -45,27 +44,13 @@ class Mylv extends Auth_Controller
public function Studiensemester()
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$isMitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter(getAuthUID())) ?? false;
if($isMitarbeiter) {
$result = $this->StudiensemesterModel->getWhereMitarbeiterHasLvs(getAuthUID());
$result = $this->StudiensemesterModel->getWhereStudentHasLvs(getAuthUID());
if (isError($result))
return $this->outputJsonError(getError($result));
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
} else if(getData($this->StudentModel->isStudent(getAuthUID())) ?? false) { // $isStudent
$result = $this->StudiensemesterModel->getWhereStudentHasLvs(getAuthUID());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
} else {
$this->outputJsonError('neither student or mitarbeiter');
}
$this->outputJsonSuccess(getData($result));
}
/**
@@ -73,27 +58,13 @@ class Mylv extends Auth_Controller
public function Lvs($studiensemester_kurzbz)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$isMitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter(getAuthUID())) ?? false;
if($isMitarbeiter) {
$result = $this->LehrveranstaltungModel->getLvsByMitarbeiterInSemester(getAuthUID(), $studiensemester_kurzbz);
$result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID(), $studiensemester_kurzbz, getUserLanguage());
if (isError($result))
return $this->outputJsonError(getError($result));
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
} else if(getData($this->StudentModel->isStudent(getAuthUID())) ?? false) { // $isStudent
$result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID(), $studiensemester_kurzbz, getUserLanguage());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
} else {
$this->outputJsonError('neither student or mitarbeiter');
}
$this->outputJsonSuccess(getData($result));
}
/**
@@ -803,7 +803,7 @@ class ReihungstestJob extends JOB_Controller
{
if (!isset($studiensemester) || isEmptyString($studiensemester))
{
$this->logError("Studiensemester not passed as parameter");
$this->logError("Studiensemster not passed as parameter");
return;
}
@@ -215,11 +215,8 @@ class Pruefungsprotokoll extends Auth_Controller
if (hasData($abschlusspruefung))
{
$abschlusspruefung_data = getData($abschlusspruefung);
if ($this->permissionlib->isBerechtigt('admin')
|| (
isset($abschlusspruefung_data->studiengang_kz)
&& $this->permissionlib->isBerechtigt('assistenz', 'suid', $abschlusspruefung_data->studiengang_kz)
)
if ($this->permissionlib->isBerechtigt('admin') ||
(isset($abschlusspruefung_data->studiengang_kz) && $this->permissionlib->isBerechtigt('assistenz', 'suid', $abschlusspruefung_data->studiengang_kz))
|| $this->_uid === $abschlusspruefung_data->uid_vorsitz)
$result = $abschlusspruefung;
else
@@ -34,9 +34,6 @@ class InfoCenter extends Auth_Controller
const PREV_FILTER_ID = 'prev_filter_id';
const KEEP_TABLESORTER_FILTER = 'keepTsFilter';
const ONBOARDING_INSERTVON = 'onboarding';
const ONBOARDING_KENNZEICHENTYP = 'eobRegistrierungsId';
private $_uid; // contains the UID of the logged user
// Used to log with PersonLogLib
@@ -178,7 +175,6 @@ class InfoCenter extends Auth_Controller
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Geschlecht_model', 'GeschlechtModel');
$this->load->model('person/adresse_model', 'AdresseModel');
$this->load->model('person/Kennzeichen_model', 'KennzeichenModel');
// Loads libraries
$this->load->library('PersonLogLib');
@@ -1456,100 +1452,6 @@ class InfoCenter extends Auth_Controller
$this->outputJsonSuccess("Done!");
}
public function getAbsageData()
{
$stg_typ = $this->getStudienArtBerechtigung(['b', 'm']);
if (!is_null($stg_typ))
{
$statusgruende = $this->StatusgrundModel->getStatus(self::ABGEWIESENERSTATUS, true)->retval;
$studienSemester = $this->variablelib->getVar('infocenter_studiensemester');
$studiengaenge = $this->StudiengangModel->getStudiengaengeWithOrgForm(array_column($stg_typ, 'typ'), $studienSemester);
$data = array (
'statusgruende' => $statusgruende,
'studiengaenge' => $studiengaenge->retval
);
$this->outputJsonSuccess($data);
}
else
$this->outputJsonSuccess(null);
}
public function getStudienArtBerechtigung($typ = null)
{
$studiengang_kz_all = $this->permissionlib->getSTG_isEntitledFor('infocenter');
$stg_typ = $this->StudiengangModel->getStudiengangTyp($studiengang_kz_all, $typ);
return getData($stg_typ);
}
public function getStudienartData()
{
$this->outputJsonSuccess($this->getStudienArtBerechtigung(['b', 'm', 'l']));
}
public function saveAbsageForAll()
{
$statusgrund = $this->input->post('statusgrund');
$studiengang = $this->input->post('studiengang');
$abgeschickt = $this->input->post('abgeschickt');
$personen = $this->input->post('personen');
$studienSemester = $this->variablelib->getVar('infocenter_studiensemester');
if ($statusgrund === 'null' || $studiengang === 'null' || $abgeschickt === 'null' || empty($personen))
$this->terminateWithJsonError("Bitte füllen Sie alle Felder aus");
if ($studiengang === 'all' && $abgeschickt === 'all')
{
foreach($personen as $person)
{
$prestudenten = $this->PrestudentModel->getByPersonWithoutLehrgang($person, $studienSemester);
if (!hasData($prestudenten))
continue;
$prestudentenData = getData($prestudenten);
foreach ($prestudentenData as $prestudent)
{
$this->saveAbsage($prestudent->prestudent_id, $statusgrund);
}
}
}
else
{
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$this->StudienplanModel->addSelect('1');
$this->StudienplanModel->addJoin('lehre.tbl_studienordnung so', 'studienordnung_id');
$escaped = $this->StudienplanModel->db->escape(strtoupper($studiengang));
$this->StudienplanModel->db->where("UPPER(so.studiengangkurzbzlang || ':' || tbl_studienplan.orgform_kurzbz) = $escaped");
$this->StudienplanModel->addLimit(1);
$studiengangResult = $this->StudienplanModel->load();
if (hasData($studiengangResult))
{
foreach($personen as $person)
{
$prestudent = $this->PrestudentModel->getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester, $abgeschickt, $abgeschickt === 'all');
if (!hasData($prestudent))
continue;
$prestudentData = getData($prestudent);
$this->saveAbsage($prestudentData[0]->prestudent_id, $statusgrund);
}
}
else
$this->terminateWithJsonError("Falschen Studiengang übergeben!");
}
$this->outputJsonSuccess("Success");
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
@@ -2044,17 +1946,6 @@ class InfoCenter extends Auth_Controller
show_error(getError($user_person));
}
// add info about first electronig onboarding login
$this->KennzeichenModel->addSelect('insertamum');
$onboarding_first_login = $this->KennzeichenModel->loadWhere(
array('person_id' => $person_id, 'kennzeichentyp_kurzbz' => self::ONBOARDING_KENNZEICHENTYP)
);
if (isError($onboarding_first_login))
{
show_error(getError($onboarding_first_login));
}
$data = array (
'lockedby' => $lockedby,
'lockedbyother' => $lockedbyother,
@@ -2064,9 +1955,7 @@ class InfoCenter extends Auth_Controller
'messages' => $messages->retval,
'logs' => $logs,
'notizen' => $notizen->retval,
'notizenbewerbung' => $notizen_bewerbung->retval,
'created_by_onboarding' => $stammdaten->retval->insertvon == self::ONBOARDING_INSERTVON,
'onboarding_first_login' => hasData($onboarding_first_login) ? getData($onboarding_first_login)[0]->insertamum : null
'notizenbewerbung' => $notizen_bewerbung->retval
);
return $data;
@@ -2486,4 +2375,97 @@ class InfoCenter extends Auth_Controller
$this->loglib->logError('Studiengang has no mail for sending Freigabe mail');
}
}
public function getAbsageData()
{
$stg_typ = $this->getStudienArtBerechtigung(['b', 'm']);
if (!is_null($stg_typ))
{
$statusgruende = $this->StatusgrundModel->getStatus(self::ABGEWIESENERSTATUS, true)->retval;
$studienSemester = $this->variablelib->getVar('infocenter_studiensemester');
$studiengaenge = $this->StudiengangModel->getStudiengaengeWithOrgForm(array_column($stg_typ, 'typ'), $studienSemester);
$data = array (
'statusgruende' => $statusgruende,
'studiengaenge' => $studiengaenge->retval
);
$this->outputJsonSuccess($data);
}
else
$this->outputJsonSuccess(null);
}
public function getStudienArtBerechtigung($typ = null)
{
$studiengang_kz_all = $this->permissionlib->getSTG_isEntitledFor('infocenter');
$stg_typ = $this->StudiengangModel->getStudiengangTyp($studiengang_kz_all, $typ);
return getData($stg_typ);
}
public function getStudienartData()
{
$this->outputJsonSuccess($this->getStudienArtBerechtigung(['b', 'm', 'l']));
}
public function saveAbsageForAll()
{
$statusgrund = $this->input->post('statusgrund');
$studiengang = $this->input->post('studiengang');
$abgeschickt = $this->input->post('abgeschickt');
$personen = $this->input->post('personen');
$studienSemester = $this->variablelib->getVar('infocenter_studiensemester');
if ($statusgrund === 'null' || $studiengang === 'null' || $abgeschickt === 'null' || empty($personen))
$this->terminateWithJsonError("Bitte füllen Sie alle Felder aus");
if ($studiengang === 'all' && $abgeschickt === 'all')
{
foreach($personen as $person)
{
$prestudenten = $this->PrestudentModel->getByPersonWithoutLehrgang($person, $studienSemester);
if (!hasData($prestudenten))
continue;
$prestudentenData = getData($prestudenten);
foreach ($prestudentenData as $prestudent)
{
$this->saveAbsage($prestudent->prestudent_id, $statusgrund);
}
}
}
else
{
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$this->StudienplanModel->addSelect('1');
$this->StudienplanModel->addJoin('lehre.tbl_studienordnung so', 'studienordnung_id');
$escaped = $this->StudienplanModel->db->escape(strtoupper($studiengang));
$this->StudienplanModel->db->where("UPPER(so.studiengangkurzbzlang || ':' || tbl_studienplan.orgform_kurzbz) = $escaped");
$this->StudienplanModel->addLimit(1);
$studiengangResult = $this->StudienplanModel->load();
if (hasData($studiengangResult))
{
foreach($personen as $person)
{
$prestudent = $this->PrestudentModel->getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester, $abgeschickt, $abgeschickt === 'all');
if (!hasData($prestudent))
continue;
$prestudentData = getData($prestudent);
$this->saveAbsage($prestudentData[0]->prestudent_id, $statusgrund);
}
}
else
$this->terminateWithJsonError("Falschen Studiengang übergeben!");
}
$this->outputJsonSuccess("Success");
}
}
@@ -7,8 +7,6 @@ class Rueckstellung extends Auth_Controller
private $_ci; // Code igniter instance
private $_uid;
const ZGV_UEBERPRUEFUNG_MAIL_VORLAGE = 'ZGVUEP';
public function __construct()
{
parent::__construct(
@@ -25,7 +23,6 @@ class Rueckstellung extends Auth_Controller
$this->load->model('crm/RueckstellungStatus_model', 'RueckstellungStatusModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->library('PersonLogLib');
$this->load->library('MessageLib');
$this->_setAuthUID(); // sets property uid
@@ -81,8 +78,6 @@ class Rueckstellung extends Auth_Controller
$this->_log($person_id, $status_kurzbz);
if ($status_kurzbz === 'onhold_zgv')
$this->sendRueckstellungMessage($person_id);
$this->outputJson($result);
}
@@ -109,10 +104,6 @@ class Rueckstellung extends Auth_Controller
if (isError($result))
$this->terminateWithJsonError(getError($result));
$this->_log($person, $status_kurzbz);
if ($status_kurzbz === 'onhold_zgv')
$this->sendRueckstellungMessage($person);
}
$this->outputJsonSuccess("Erfolgreich gespeichert!");
}
@@ -169,26 +160,4 @@ class Rueckstellung extends Auth_Controller
$this->_uid
);
}
private function sendRueckstellungMessage($person_id)
{
$person = $this->_ci->PersonModel->load($person_id);
if (hasData($person))
{
$person = getData($person)[0];
return $this->messagelib->sendMessageUserTemplate(
$person_id,
self::ZGV_UEBERPRUEFUNG_MAIL_VORLAGE,
array(
'anrede' => $person->anrede,
'nachname' => $person->nachname
),
null,
getAuthPersonId(),
'infocenter'
);
}
}
}
-15
View File
@@ -82,21 +82,6 @@ function generateCSSsInclude($CSSs)
}
}
/**
* Generates tags for the style sheets you want to include, the parameter could by a string or an array of strings
*/
function generatePrintCSS($path)
{
$cssLink = '<link rel="stylesheet" media="print" href="%s" />';
$ci =& get_instance();
$cachetoken = '?'.$ci->config->item('fhcomplete_build_version');
if (isset($path)) {
echo sprintf($cssLink, base_url($path).$cachetoken) . PHP_EOL;
}
}
/**
* Generates global JS-Object to pass parms to other javascripts
*/
+15 -1
View File
@@ -33,6 +33,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
* @param string $headerImg Filename of the specific Sancho header image.
* @param string $cc Sets CC of mail.
* @param string $bcc Sets BCC of mail.
* @param array $attachments array of arrays with 'filePath' and (optional) 'altName' keys
* @return void
*/
function sendSanchoMail(
@@ -44,7 +45,8 @@ function sendSanchoMail(
$footerImg = '',
$from = null,
$cc = null,
$bcc = null
$bcc = null,
$attachments = []
)
{
$ci =& get_instance();
@@ -116,6 +118,18 @@ function sendSanchoMail(
$ci->email->attach($sanchoFooter_img, 'inline');
$cid_header = $ci->email->attachment_cid($sanchoHeader_img); // sets unique content id for embedding
$cid_footer = $ci->email->attachment_cid($sanchoFooter_img); // sets unique content id for embedding
// attach files
if (count($attachments)) {
foreach ($attachments as $attachment) {
if (isset($attachment["altName"])) {
$ci->email->attach($attachment["filePath"], 'attachment', $attachment["altName"]);
} else {
$ci->email->attach($attachment["filePath"], 'attachment');
}
}
}
}
// Set specific mail content into specific content template
+1 -1
View File
@@ -741,7 +741,7 @@ class AnrechnungLib
$fullname = hasData($result) ? $result->retval[0]->vorname. $result->retval[0]->nachname : '';
// Return filename
return 'Anrechnungsantrag'. $orgform_kurzbz .'_LV-'. $lehrveranstaltung_id. '_'. $fullname . '.pdf';
return 'Anrechnungsantrag'. $orgform_kurzbz .'_LV-'. $lehrveranstaltung_id. '_'. $fullname;
}
public function LVhasLector($anrechnung_id)
+93 -75
View File
@@ -4,7 +4,6 @@ if (!defined('BASEPATH'))
exit('No direct script access allowed');
use \DateTime as DateTime;
use \DateInterval as DateInterval;
use \DOMDocument as DOMDocument;
use \XSLTProcessor as XSLTProcessor;
@@ -142,6 +141,63 @@ class CmsLib
]);
}
/**
* @param stdClass $stg_obj
*
* @return stdClass
*/
protected function getNewsExtras($stg_obj, $semester)
{
$this->ci->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$stg_ltg = $this->ci->StudiengangModel->getLeitungDetailed($stg_obj->studiengang_kz);
if (isError($stg_ltg))
return $stg_ltg;
$stg_ltg = getData($stg_ltg) ?: [];
$gf_ltg = $this->ci->BenutzerfunktionModel->getBenutzerFunktionenDetailed('gLtg', $stg_obj->oe_kurzbz);
if (isError($gf_ltg))
return $gf_ltg;
$gf_ltg = getData($gf_ltg) ?: [];
$stv_ltg = $this->ci->BenutzerfunktionModel->getBenutzerFunktionenDetailed('stvLtg', $stg_obj->oe_kurzbz);
if (isError($stv_ltg))
return $stv_ltg;
$stv_ltg = getData($stv_ltg) ?: [];
$ass = $this->ci->BenutzerfunktionModel->getBenutzerFunktionenDetailed('ass', $stg_obj->oe_kurzbz);
if (isError($ass))
return $ass;
$ass = getData($ass) ?: [];
$hochschulvertr = $this->ci->BenutzerfunktionModel->getBenutzerFunktionenDetailed('hsv');
if (isError($hochschulvertr))
return $hochschulvertr;
$hochschulvertr = getData($hochschulvertr) ?: [];
$stdv = $this->ci->BenutzerfunktionModel->getBenutzerFunktionenDetailed('stdv', $stg_obj->oe_kurzbz);
if (isError($stdv))
return $stdv;
$stdv = getData($stdv) ?: [];
$jahrgangsvertr = $this->ci->BenutzerfunktionModel->getBenutzerFunktionenDetailed('jgv', $stg_obj->oe_kurzbz, $semester);
if (isError($jahrgangsvertr))
return $jahrgangsvertr;
$jahrgangsvertr = getData($jahrgangsvertr) ?: [];
return success($this->ci->load->view('Cis/Cms/News/Xml/NewsExtras', [
'studiengang' => $stg_obj,
'semester' => $semester,
'stg_ltg' => $stg_ltg,
'gf_ltg' => $gf_ltg,
'stv_ltg' => $stv_ltg,
'ass' => $ass,
'hochschulvertr' => $hochschulvertr,
'stdv' => $stdv,
'jahrgangsvertr' => $jahrgangsvertr
], true));
}
/**
* @param string $studiengang_kz
* @param string $semester
@@ -177,102 +233,64 @@ class CmsLib
*
* @return void
*/
public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true, $page = 1, $page_size = 10, $sprache, $filterForDegreePrograms = false, $allowedDegreePrograms = [], $active = true)
public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true, $page = 1, $page_size = 10, $sprache)
{
$this->ci->load->model('organisation/Studiengang_model', 'StudiengangModel');
list($studiengang_kz, $semester) = $this->getStgAndSem($studiengang_kz, $semester);
$all = $edit;
$xml = '<?xml version="1.0" encoding="UTF-8"?><content>';
$this->ci->load->model('content/News_model', 'NewsModel');
$news = $this->ci->NewsModel->getNewsWithContent($sprache, $studiengang_kz, $semester, null, $sichtbar, $page, $page_size, $active, $mischen, $filterForDegreePrograms, $allowedDegreePrograms);
$news = getData($news) ?? [];
$newsWrappers = [];
$news = $this->ci->NewsModel->getNewsWithContent($sprache, $studiengang_kz, $semester, null, $sichtbar, 0, $page, $page_size, $all, $mischen);
if (isError($news))
return $news;
$news = getData($news);
foreach ($news as $newsobj) {
if ($studiengang_kz && $edit && !$newsobj->studiengang_kz)
continue;
$newsWrappers[] = $this->createNewsWrapper($newsobj, $edit);
$date = new DateTime($newsobj->datum);
$datum = '<datum><![CDATA[' . $date->format('d.m.Y') . ']]></datum>';
$datum .= '<datumdetail><![CDATA[' . $date->format('Y-m-d H:i') . ']]></datumdetail>';
$id = $edit ? '<news_id><![CDATA[' . $newsobj->news_id . ']]></news_id>' : '';
$xml .= "<newswrapper>" . $newsobj->content . $datum . $id . "</newswrapper>";
}
$content = $this->createNewsContent($newsWrappers, $infoscreen, $titel);
if (isError($content))
return $content;
/* if ($studiengang_kz != 0) {
$stg_obj = $this->ci->StudiengangModel->load($studiengang_kz);
if (isError($stg_obj))
return $stg_obj;
$stg_obj = current(getData($stg_obj) ?: []);
return success([
"content" => getData($content),
"row_count" => $news[0]->row_count ?? 0
]);
}
/**
* Creates a newswrapper XML element from a news item.
*
* @param stdClass $newsobj
* @param boolean $edit
*
* @return DOMElement
*/
public function createNewsWrapper($newsobj, $edit)
{
$id = $edit ? '<news_id><![CDATA[' . $newsobj->news_id . ']]></news_id>' : '';
$isPublished = $edit ? '<is_published><![CDATA[' . ($newsobj->sichtbar ? 'true' : 'false') . ']]></is_published>' : '';
$date = new DateTime($newsobj->datum);
$datum = '<datum><![CDATA[' . $date->format('d.m.Y') . ']]></datum>';
$datum .= '<datumdetail><![CDATA[' . $date->format('Y-m-d H:i') . ']]></datumdetail>';
$hasVisibleToDate = isset($newsobj->datum_bis) && $newsobj->datum_bis !== '';
$datumTo = $hasVisibleToDate
? new DateTime($newsobj->datum_bis)
: (clone $date)->add(new DateInterval('P' . MAXNEWSALTER . 'D'));
if ($hasVisibleToDate)
$datumTo->setTime(23, 59, 59);
$now = new DateTime();
$isActive = '<is_active><![CDATA[' . ($datumTo >= $now ? 'true' : 'false') . ']]></is_active>';
$newsWrapper = new DOMDocument();
$newsWrapper->loadXML('<newswrapper>' . $newsobj->content . $datum . $id . $isPublished . $isActive . '</newswrapper>');
return $newsWrapper->documentElement;
}
/**
* Creates rendered news content from one or more newswrapper XML elements.
*
* @param DOMElement|array $newsWrappers
* @param boolean $infoscreen
* @param string $titel
*
* @return stdClass
*/
public function createNewsContent($newsWrappers, $infoscreen, $titel)
{
if (!is_array($newsWrappers))
$newsWrappers = [$newsWrappers];
$XML = new DOMDocument('1.0', 'UTF-8');
$contentElement = $XML->createElement('content');
$XML->appendChild($contentElement);
foreach ($newsWrappers as $newsWrapper)
$contentElement->appendChild($XML->importNode($newsWrapper, true));
if ($stg_obj) {
if (!$edit && !$infoscreen) {
$extras = $this->getNewsExtras($stg_obj, $semester);
if (isError($extras))
return $extras;
$xml .= getData($extras);
}
$xml .= '<studiengang_bezeichnung><![CDATA[' . $stg_obj->bezeichnung . ']]></studiengang_bezeichnung>';
}
} */
if ($titel != '') {
$titleElement = $XML->createElement('news_titel');
$titleElement->appendChild($XML->createTextNode($titel));
$contentElement->appendChild($titleElement);
$xml .= '<news_titel>' . $titel . '</news_titel>';
}
$xml .= '</content>';
//XSLT Vorlage laden
$template = $this->ci->TemplateModel->load($infoscreen ? 'news_infoscreen' : 'news');
if (isError($template))
return $template;
$template = current(getData($template));
$XML = new DOMDocument();
$XML->loadXML($xml);
$xsltemplate = new DOMDocument();
$xsltemplate->loadXML($template->xslt_xhtml_c4);
+14 -1
View File
@@ -25,4 +25,17 @@ class CryptLib
return $cipher->encrypt($value);
}
}
public static function RIJNDAEL_256_ECB_DECRYPT($value, $key, $paddingDisabled = false)
{
if (isEmptyString($value) || isEmptyString($key)) return null;
$cipher = new Rijndael(Rijndael::MODE_ECB);
$cipher->setBlockLength(256);
$cipher->setKey($key);
if ($paddingDisabled === true) $cipher->disablePadding();
return $cipher->decrypt($value);
}
}
+242
View File
@@ -0,0 +1,242 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH'))
exit('No direct script access allowed');
// require_once('../../include/ical.class.php');
class FreeBusyLib
{
private $_ci; // Code igniter instance
public function __construct()
{
$this->_ci =& get_instance();
$this->_ci->load->model("ressource/Zeitsperre_model", "ZeitsperreModel");
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getFreeBusy($url)
{
$fileStream = @fopen($url, "r");
if (!$fileStream)
return [];
$busyTimeslots = [];
$fileContent = file_get_contents($url);
if (mb_strpos($fileContent, "BEGIN:VFREEBUSY") !== false) {
$busyTimeslots = $this->parseFreeBusyFormat($fileContent);
} else {
$busyTimeslots = $this->parseConventionalFormat($fileContent);
}
return $busyTimeslots;
}
public function getDefaultInternalFreeBusy($uid)
{
$events = [];
$this->_ci->load->library('StundenplanLib');
$startDate = new DateTime();
$startDate = $startDate->format("Y-m-d");
$endDate = new DateTime();
$endDate->modify("+1 year");
$endDate = $endDate->format("Y-m-d");
$userEvents = getData($this->_ci->stundenplanlib->getEventsUser($startDate, $endDate, $uid));
if ($userEvents && count($userEvents)) {
$userEvents = array_map(
function ($event) {
return [
"start" => $event->datum . " " . $event->beginn,
"end" => $event->datum . " " . $event->ende,
];
},
$userEvents
);
$events = array_merge($events, $userEvents);
}
$userAbsences = getData($this->_ci->ZeitsperreModel->getZeitsperre($uid));
if ($userAbsences && count($userAbsences)) {
$today = new DateTime();
$today = $today->format("Y-m-d");
$userAbsences = array_filter(
$userAbsences,
function ($absence) use ($today) {
return $absence->bisdatum >= $today;
}
);
$userAbsences = array_map(
function ($absence) {
return [
"start" => $absence->vondatum . " 00:00:00",
"end" => $absence->bisdatum . " 23:59:00",
];
},
$userAbsences
);
$events = array_merge($events, $userAbsences);
}
return $events;
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
private function parseConventionalFormat($fileContent)
{
$fileContentRows = explode("\n", $fileContent);
$fileContentRows = array_map(function ($row) {
return trim($row);
}, $fileContentRows);
$busyTimeslots = [];
$isParsingEvent = false;
$parsedEvent = ["start" => null, "end" => null];
$currentDateTime = new DateTime();
$currentDateTime = $currentDateTime->format("Y-m-d H:i:s");
foreach ($fileContentRows as $row) {
if (mb_strpos($row, "BEGIN:VEVENT") !== false) {
$isParsingEvent = true;
} else if (mb_strpos($row, "END:VEVENT") !== false) {
if (
$isParsingEvent &&
$parsedEvent["start"] &&
$parsedEvent["end"] &&
$parsedEvent["end"] > $currentDateTime
) {
$busyTimeslots[] = $parsedEvent;
}
$isParsingEvent = false;
$parsedEvent["start"] = null;
$parsedEvent["end"] = null;
} else if (mb_strpos($row, "DTSTART;VALUE=DATE") !== false) {
$startDateString = explode(":", $row)[1];
$start = substr($startDateString, 0, 4) . "-" . substr($startDateString, 4, 2) . "-" . substr($startDateString, 6, 2) . " 00:00:00";
$parsedEvent["start"] = $start;
} else if (mb_strpos($row, "DTSTART") !== false) {
$timestamp = explode(":", $row)[1];
if (mb_substr($timestamp, -1) === "Z") {
$timestamp = $this->convertTimestampToLocalTimezone($timestamp);
} else if (mb_strpos($row, "TZID=") !== false) {
$remainingString = explode("TZID=", $row)[1];
$remainingString = explode(":", $remainingString)[0];
$timezoneIdentifier = explode(";", $remainingString)[0];
$timestamp = $this->convertTimestampToLocalTimezone($timestamp, $timezoneIdentifier);
}
$startDate = substr($timestamp, 0, 4) . "-" . substr($timestamp, 4, 2) . "-" . substr($timestamp, 6, 2);
$startTime = substr($timestamp, 9, 2) . ":" . substr($timestamp, 11, 2) . ":" . substr($timestamp, 13, 2);
$parsedEvent["start"] = $startDate . " " . $startTime;
} else if (mb_strpos($row, "DTEND;VALUE=DATE") !== false) {
$endDateString = explode(":", $row)[1];
$end = substr($endDateString, 0, 4) . "-" . substr($endDateString, 4, 2) . "-" . substr($endDateString, 6, 2) . " 00:00:00";
$parsedEvent["end"] = $end;
} else if (mb_strpos($row, "DTEND") !== false) {
$timestamp = explode(":", $row)[1];
if (mb_substr($timestamp, -1) === "Z") {
$timestamp = $this->convertTimestampToLocalTimezone($timestamp);
} else if (mb_strpos($row, "TZID=") !== false) {
$remainingString = explode("TZID=", $row)[1];
$remainingString = explode(":", $remainingString)[0];
$timezoneIdentifier = explode(";", $remainingString)[0];
$timestamp = $this->convertTimestampToLocalTimezone($timestamp, $timezoneIdentifier);
}
$endDate = substr($timestamp, 0, 4) . "-" . substr($timestamp, 4, 2) . "-" . substr($timestamp, 6, 2);
$endTime = substr($timestamp, 9, 2) . ":" . substr($timestamp, 11, 2) . ":" . substr($timestamp, 13, 2);
$parsedEvent["end"] = $endDate . " " . $endTime;
}
}
return $busyTimeslots;
}
private function parseFreeBusyFormat($fileContent)
{
$fileContentRows = explode("\n", $fileContent);
$fileContentRows = array_map(function ($row) {
return trim($row);
}, $fileContentRows);
$busyTimeslots = [];
$currentDateTime = new DateTime();
$currentDateTime = $currentDateTime->format("Y-m-d H:i:s");
foreach ($fileContentRows as $row) {
if (
mb_strpos($row, "VFREEBUSY") !== false ||
mb_strpos($row, "FREEBUSY") === false ||
mb_strpos($row, "FBTYPE=FREE") !== false
)
continue;
$timestamps = explode(":", $row)[1];
$timestamps = explode(",", $timestamps);
foreach ($timestamps as $timestamp) {
$startEndTimestamps = explode("/", $timestamp);
$startTimestamp = $startEndTimestamps[0];
$endTimestamp = $startEndTimestamps[1];
if (mb_substr($startTimestamp, -1) === "Z") {
$startTimestamp = $this->convertTimestampToLocalTimezone($startTimestamp);
}
if (mb_substr($endTimestamp, -1) === "Z") {
$endTimestamp = $this->convertTimestampToLocalTimezone($endTimestamp);
}
$startDate = substr($startTimestamp, 0, 4) . "-" . substr($startTimestamp, 4, 2) . "-" . substr($startTimestamp, 6, 2);
$startTime = substr($startTimestamp, 9, 2) . ":" . substr($startTimestamp, 11, 2) . ":" . substr($startTimestamp, 13, 2);
$start = $startDate . " " . $startTime;
$endDate = substr($endTimestamp, 0, 4) . "-" . substr($endTimestamp, 4, 2) . "-" . substr($endTimestamp, 6, 2);
$endTime = substr($endTimestamp, 9, 2) . ":" . substr($endTimestamp, 11, 2) . ":" . substr($endTimestamp, 13, 2);
$end = $endDate . " " . $endTime;
if ($end < $currentDateTime)
continue;
$busyTimeslots[] = ["start" => $start, "end" => $end];
}
}
return $busyTimeslots;
}
private function convertTimestampToLocalTimezone($timestamp, $originalTimezoneIdentifier = "UTC")
{
$originalTimezone = new DateTimeZone($originalTimezoneIdentifier);
$localTimezone = new DateTimeZone("Europe/Vienna");
$date = new DateTime($timestamp, $originalTimezone);
$date->setTimezone($localTimezone);
return $date->format("Ymd\THis");
}
}
@@ -1,410 +0,0 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* The exam history of one student in one course: the order of the attempts, the attempt count
* and the limits. This class is the only source of the examination rules. The controller and the
* client only read the result.
*/
class PruefungsverlaufLib
{
/** The first attempt: the original assessment, which is the transcript grade itself. */
const ROLLE_ERSTANTRITT = 'erstantritt';
/** Each attempt after the first one. */
const ROLLE_PRUEFUNG = 'pruefung';
/** The last attempt. The examination rules require a commission for it. */
const ROLLE_KOMMISSIONELL = 'kommissionell';
/** Maps an attempt number to the old exam type. Kept for backward compatibility. */
private static $_legacyTypen = [1 => 'Termin1', 2 => 'Termin2', 3 => 'Termin3'];
private $_ci;
private $_noteCache = [];
private $_specialNotes = null;
private $_typen = null;
public function __construct()
{
$this->_ci =& get_instance();
$this->_ci->load->model('education/LePruefung_model', 'LePruefungModel');
$this->_ci->load->model('education/Note_model', 'NoteModel');
$this->_ci->load->model('education/Pruefungstyp_model', 'PruefungstypModel');
$this->_ci->load->config('noten');
}
/**
* @param mixed $lvNote counts as the implicit first attempt while no exam counts
* @param mixed $zeugnisNote a credited grade makes all exams impossible
* @return stdClass
*/
public function getVerlauf($student_uid, $lv_id, $sem_kurzbz, $lvNote = null, $zeugnisNote = null)
{
return $this->buildVerlauf($this->getPruefungen($student_uid, $lv_id, $sem_kurzbz), $lvNote, $zeugnisNote);
}
/** All exams of one student in one course, in chronological order. @return array */
public function getPruefungen($student_uid, $lv_id, $sem_kurzbz)
{
$result = $this->_ci->LePruefungModel->getPruefungenByUidTypLvStudiensemester($student_uid, null, $lv_id, $sem_kurzbz);
if (isError($result) || !hasData($result)) return [];
return $this->sortPruefungen(getData($result));
}
/** Sort keys: datum, then tbl_pruefungstyp.sort (old rows without a date), then pruefung_id. */
public function sortPruefungen($pruefungen)
{
$pruefungen = array_values($pruefungen);
$typen = $this->getTypen();
usort($pruefungen, function ($a, $b) use ($typen) {
$da = substr((string) $a->datum, 0, 10);
$db = substr((string) $b->datum, 0, 10);
if ($da !== $db) {
if ($da === '') return -1;
if ($db === '') return 1;
return ($da < $db) ? -1 : 1;
}
$sa = isset($typen[$a->pruefungstyp_kurzbz]) ? (int) $typen[$a->pruefungstyp_kurzbz]->sort : 0;
$sb = isset($typen[$b->pruefungstyp_kurzbz]) ? (int) $typen[$b->pruefungstyp_kurzbz]->sort : 0;
if ($sa !== $sb) return ($sa < $sb) ? -1 : 1;
return ((int) $a->pruefung_id < (int) $b->pruefung_id) ? -1 : 1;
});
return $pruefungen;
}
/**
* Builds the history from a list of exams. Each exam gets: position, zaehlt, antritt_nr (null
* if the exam does not count) and terminal.
*
* @return stdClass
*/
public function buildVerlauf($pruefungen, $lvNote = null, $zeugnisNote = null)
{
$pruefungen = $this->sortPruefungen($pruefungen);
$antrittCount = 0;
$terminal = false;
$eintraege = [];
foreach ($pruefungen as $i => $p) {
$zaehlt = $this->zaehltAlsAntritt($p->note, $p->pruefungstyp_kurzbz);
if ($zaehlt) $antrittCount++;
// A kommissionelle exam closes the chain, also if its grade uses no attempt. A student
// with a kommissionelle Prüfung gets no further exam from this tool.
$kommissionell = $this->istKommissionell($p->pruefungstyp_kurzbz);
if ($kommissionell) $terminal = true;
$eintrag = clone $p;
$eintrag->position = $i + 1;
$eintrag->zaehlt = $zaehlt;
$eintrag->antritt_nr = $zaehlt ? $antrittCount : null;
$eintrag->kommissionell = $kommissionell;
$eintraege[] = $eintrag;
}
// if no exam counts, the course grade itself is the first attempt
$implizit = ($antrittCount === 0 && $lvNote !== null && $this->zaehltAlsAntritt($lvNote));
if ($implizit) $antrittCount = 1;
$maxAntritte = $this->getMaxAntritte();
// credited: the row stays visible, but you cannot enter anything
$angerechnet = $this->istAnrechnungsnote($zeugnisNote);
$verlauf = new stdClass();
$verlauf->pruefungen = $eintraege;
$verlauf->antrittCount = $antrittCount;
$verlauf->maxAntritte = $maxAntritte;
$verlauf->terminal = $terminal;
$verlauf->angerechnet = $angerechnet;
$verlauf->impliziterErstantritt = $implizit;
$verlauf->canAdd = !$terminal && !$angerechnet && $antrittCount < $maxAntritte;
// after the first exam each new entry is a repeat attempt
$verlauf->erstantrittMoeglich = !$angerechnet && (count($eintraege) === 0);
// The last attempt of the chain is kommissionell (§17 Abs 1). The role therefore follows
// from the position, and the user interface offers no type to select.
if (count($eintraege) === 0 && !$implizit) {
$verlauf->naechsteRolle = self::ROLLE_ERSTANTRITT;
} elseif (($antrittCount + 1) >= $maxAntritte) {
$verlauf->naechsteRolle = self::ROLLE_KOMMISSIONELL;
} else {
$verlauf->naechsteRolle = self::ROLLE_PRUEFUNG;
}
return $verlauf;
}
/** 'angerechnet' or 'intern angerechnet'. The TRANSCRIPT grade decides. @return bool */
public function istAnrechnungsnote($note)
{
if ($note === null || $note === '') return false;
return in_array($note, $this->getSpecialNotes()['anrechnung']);
}
/**
* All attempts that count, the kommissionelle attempt included. The explicit configuration
* wins. Without it the number comes from the old flags: the original assessment, one attempt
* for each active repeat, and the kommissionelle attempt.
*
* @return int
*/
public function getMaxAntritte()
{
$max = $this->_ci->config->item('CIS_GESAMTNOTE_MAX_ANTRITTE');
if (is_numeric($max) && (int) $max > 0) return (int) $max;
$max = 1;
if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) $max++;
if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) $max++;
if (defined('CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF') && CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF) $max++;
return $max;
}
/**
* The NOTE decides, therefore the same type can occur more than one time. The type decides in
* one case only: a type in PRUEFUNG_TYPEN_OHNE_ANTRITT never uses an attempt.
*
* @return bool
*/
public function zaehltAlsAntritt($note, $typ = null)
{
if ($typ !== null && in_array($typ, $this->getTypenOhneAntritt())) return false;
if ($note === null || $note === '') return false;
if (in_array($note, $this->getSpecialNotes()['ohneAntritt'])) return false;
// a credited grade is not an assessment, therefore it uses no attempt
if ($this->istAnrechnungsnote($note)) return false;
$noteRow = $this->getNote($note);
return $noteRow ? (bool) $noteRow->lehre : false;
}
/** Tells you if an exam takes place before a commission. @return bool */
public function istKommissionell($typ)
{
$typen = $this->_ci->config->item('PRUEFUNG_KOMMISSIONELL_TYPEN');
if (!is_array($typen)) $typen = ['kommPruef', 'zusKommPruef'];
return in_array($typ, $typen);
}
/** The exam types that never use an attempt. @return array */
public function getTypenOhneAntritt()
{
$typen = $this->_ci->config->item('PRUEFUNG_TYPEN_OHNE_ANTRITT');
return is_array($typen) ? $typen : ['zusKommPruef'];
}
/**
* The type for an attempt number. The student administration still reads this column, so the
* value must be correct. The last attempt gets the kommissionelle type, the attempts before it
* get the old Termin types.
*
* @return string
*/
public function legacyTypFuerAntritt($antrittNr)
{
$antrittNr = max(1, (int) $antrittNr);
$typen = $this->getTypen();
$maxAntritte = $this->getMaxAntritte();
$kommissionell = $this->_ci->config->item('PRUEFUNG_TYP_KOMMISSIONELL');
if (!is_string($kommissionell) || $kommissionell === '') $kommissionell = 'kommPruef';
if ($maxAntritte > 1 && $antrittNr >= $maxAntritte && isset($typen[$kommissionell])) {
return $kommissionell;
}
for ($n = $antrittNr; $n >= 1; $n--) {
if (isset(self::$_legacyTypen[$n]) && isset($typen[self::$_legacyTypen[$n]])) {
return self::$_legacyTypen[$n];
}
}
return self::$_legacyTypen[1];
}
/**
* The old type for a new repeat attempt. It is never lower than Termin2, also if the first
* exam does not use an attempt.
*
* @return string
*/
public function legacyTypFuerWiederholung($verlauf)
{
return $this->legacyTypFuerAntritt(max(2, $verlauf->antrittCount + 1));
}
/** @return array{entschuldigt: mixed, ohneAntritt: array, anrechnung: array, limitMap: array} */
public function getSpecialNotes()
{
if ($this->_specialNotes !== null) return $this->_specialNotes;
$cfgEntschuldigt = $this->_ci->config->item('NOTE_ENTSCHULDIGT');
$cfgOhneAntritt = $this->_ci->config->item('NOTEN_OHNE_ANTRITT');
$cfgLimitMap = $this->_ci->config->item('NOTEN_OCCURANCE_LIMIT_MAP');
$bezeichnungen = $this->_ci->config->item('NOTEN_OHNE_ANTRITT_BEZEICHNUNGEN');
if (!is_array($cfgOhneAntritt)) $cfgOhneAntritt = [];
if (!is_array($cfgLimitMap)) $cfgLimitMap = [];
if (!is_array($bezeichnungen)) $bezeichnungen = [];
$resEnt = $this->_ci->NoteModel->getEntschuldigtNote();
$entschuldigt = (!isError($resEnt) && hasData($resEnt)) ? getData($resEnt)[0]->note : $cfgEntschuldigt;
// The name wins against the configured key. Do NOT merge the two sets: the same key has a
// different meaning in each installation (17 is 'entschuldigt' here, but 'nicht zugelassen'
// in the standard data).
$ohneAntritt = [];
foreach ($bezeichnungen as $bezeichnung) {
$note = $this->getNoteByBezeichnung($bezeichnung);
if ($note !== null && !in_array($note, $ohneAntritt)) $ohneAntritt[] = $note;
}
if (count($ohneAntritt) === 0) $ohneAntritt = $cfgOhneAntritt;
if ($entschuldigt !== null && !in_array($entschuldigt, $ohneAntritt)) $ohneAntritt[] = $entschuldigt;
// move the configured limit for 'entschuldigt' to the key that was found
$limitMap = [];
foreach ($cfgLimitMap as $k => $v) {
$limitMap[($k == $cfgEntschuldigt) ? $entschuldigt : $k] = $v;
}
$this->_specialNotes = [
'entschuldigt' => $entschuldigt,
'ohneAntritt' => array_values($ohneAntritt),
'anrechnung' => $this->resolveNoten('NOTEN_ANRECHNUNG_BEZEICHNUNGEN', 'NOTEN_ANRECHNUNG'),
'limitMap' => $limitMap
];
return $this->_specialNotes;
}
/**
* The occurrence limit from NOTEN_OCCURANCE_LIMIT_MAP. $excludePruefungId skips the record
* that the user edits at this moment.
*
* @return bool
*/
public function ueberschreitetNotenLimit($pruefungen, $note, $excludePruefungId = null)
{
$limitMap = $this->getSpecialNotes()['limitMap'];
$limit = null;
foreach ($limitMap as $limitNote => $limitVal) {
if ($limitNote == $note) { $limit = $limitVal; break; }
}
if ($limit === null) return false;
$count = 0;
foreach ($pruefungen as $p) {
if ($excludePruefungId !== null && $p->pruefung_id == $excludePruefungId) continue;
if ($p->note == $note) $count++;
}
return ($count + 1) > $limit;
}
/** An exam with a later date locks the grade. You can still correct the date. @return bool */
public function hatSpaeterenTermin($verlauf, $pruefung_id)
{
$current = null;
foreach ($verlauf->pruefungen as $p) {
if ($p->pruefung_id == $pruefung_id) { $current = $p; break; }
}
if ($current === null) return false;
foreach ($verlauf->pruefungen as $p) {
if ($p->pruefung_id == $current->pruefung_id) continue;
if ($p->position > $current->position) return true;
}
return false;
}
/**
* tbl_pruefungstyp as a map. It sorts old rows, and it limits the legacy type to the types
* that exist. A type that does not exist breaks the foreign key. Termin3 is absent from the
* standard data.
*
* @return array
*/
private function getTypen()
{
if ($this->_typen !== null) return $this->_typen;
$this->_typen = [];
$result = $this->_ci->PruefungstypModel->load();
if (!isError($result) && hasData($result)) {
foreach (getData($result) as $typ) {
$this->_typen[$typ->pruefungstyp_kurzbz] = $typ;
}
}
return $this->_typen;
}
/** Finds the grades by their name. The configured keys are the fallback only. @return array */
private function resolveNoten($bezeichnungKey, $pkKey)
{
$bezeichnungen = $this->_ci->config->item($bezeichnungKey);
if (!is_array($bezeichnungen)) $bezeichnungen = [];
$noten = [];
foreach ($bezeichnungen as $bezeichnung) {
$note = $this->getNoteByBezeichnung($bezeichnung);
if ($note !== null && !in_array($note, $noten)) $noten[] = $note;
}
if (count($noten) === 0) {
$fallback = $this->_ci->config->item($pkKey);
if (is_array($fallback)) $noten = $fallback;
}
return array_values($noten);
}
/**
* @return stdClass|null
*/
private function getNote($note)
{
if (array_key_exists($note, $this->_noteCache)) return $this->_noteCache[$note];
$result = $this->_ci->NoteModel->load($note);
$this->_noteCache[$note] = (!isError($result) && hasData($result)) ? getData($result)[0] : null;
return $this->_noteCache[$note];
}
/**
* @return mixed|null
*/
private function getNoteByBezeichnung($bezeichnung)
{
$result = $this->_ci->NoteModel->loadWhere(['bezeichnung' => $bezeichnung]);
return (!isError($result) && hasData($result)) ? getData($result)[0]->note : null;
}
}
+4 -101
View File
@@ -33,7 +33,7 @@ class SearchBarLib
const ERROR_NOT_AUTH = 'ERR005';
// List of allowed types of search
const ALLOWED_TYPES = ['mitarbeiter', 'mitarbeiter_ohne_zuordnung', 'organisationunit', 'raum', 'person', 'student','studentStv', 'prestudent', 'document', 'cms', 'lehreinheit', 'lehrveranstaltung'];
const ALLOWED_TYPES = ['mitarbeiter', 'mitarbeiter_ohne_zuordnung', 'organisationunit', 'raum', 'person', 'student','studentStv', 'prestudent', 'document', 'cms'];
const PHOTO_IMG_URL = '/cis/public/bild.php?src=person&person_id=';
@@ -180,14 +180,10 @@ class SearchBarLib
protected function buildSearchClause(DB_Model $dbModel, array $columns, $searchstr)
{
$searchstr = preg_replace('/[[:punct:]]/', ' ', $searchstr);
$words = preg_split('/\s+/', trim($searchstr), -1, PREG_SPLIT_NO_EMPTY);
if (empty($words)) return array();
$document = implode(' || \' \' || ', $columns);
$query = '\'' . implode(':* & ', $words) . ':*\'';
$reversequery = '\'*:' . implode(' & *:', $words) . '\'';
$nospacequery = '\'' . implode('', $words) . ':*\'';
$query = '\'' . implode(':* & ', explode(' ', trim($searchstr))) . ':*\'';
$reversequery = '\'*:' . implode(' & *:', explode(' ', trim($searchstr))) . '\'';
$nospacequery = '\'' . implode('', explode(' ', trim($searchstr))) . ':*\'';
$searchclause = <<<EOSC
to_tsvector(lower(regexp_replace({$document}, '[[:punct:]]', ' ', 'g'))) @@ to_tsquery(lower({$query}))
@@ -600,98 +596,5 @@ EOSC;
// Otherwise return an empty array
return array();
}
private function _lehreinheit($searchstr, $type)
{
$dbModel = new DB_Model();
$idwhere = '';
if (ctype_digit(trim($searchstr)))
{
$id = (int)trim($searchstr);
$idwhere = ' OR le.lehreinheit_id = ' . $id;
}
$lehreinheit = $dbModel->execReadOnlyQuery('
SELECT
\'teachingunit\' AS renderer,
\''.$type.'\' AS type,
le.lehreinheit_id AS id,
le.studiensemester_kurzbz,
lv.bezeichnung,
\'lv_table_icon icon-\' AS foto,
UPPER(stg.typ || stg.kurzbz) AS studiengang,
le.lehrform_kurzbz,
lv.semester
FROM lehre.tbl_lehreinheit le
JOIN lehre.tbl_lehrveranstaltung lv ON (lv.lehrveranstaltung_id = le.lehrveranstaltung_id)
JOIN public.tbl_studiengang stg ON (stg.studiengang_kz = lv.studiengang_kz)
JOIN public.tbl_studiensemester sem ON (sem.studiensemester_kurzbz = le.studiensemester_kurzbz)
WHERE (' .
$this->buildSearchClause(
$dbModel,
array(
'(stg.typ || stg.kurzbz)',
'lv.semester',
'lv.bezeichnung'
),
$searchstr
) . ')' . $idwhere . '
');
// If something has been found then return it
if (hasData($lehreinheit)) return getData($lehreinheit);
// Otherwise return an empty array
return array();
}
private function _lehrveranstaltung($searchstr, $type)
{
$dbModel = new DB_Model();
$idwhere = '';
if (ctype_digit(trim($searchstr)))
{
$id = (int)trim($searchstr);
$idwhere = ' OR tbl_lehrveranstaltung.lehrveranstaltung_id = ' . $id;
}
$lehreinheit = $dbModel->execReadOnlyQuery('
SELECT
\'teachingunit\' AS renderer,
\''.$type.'\' AS type,
lehrveranstaltung_id as id,
tbl_lehrveranstaltung.bezeichnung,
\'lv_table_icon icon-lv\' as foto,
UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as studiengang,
semester,
lehrform_kurzbz,
tbl_organisationseinheit.bezeichnung as oe_bezeichnung
FROM lehre.tbl_lehrveranstaltung
JOIN public.tbl_studiengang USING(studiengang_kz)
JOIN public.tbl_organisationseinheit ON tbl_lehrveranstaltung.oe_kurzbz = tbl_organisationseinheit.oe_kurzbz
WHERE (' .
$this->buildSearchClause(
$dbModel,
array(
'(tbl_studiengang.typ || tbl_studiengang.kurzbz)',
'semester',
'tbl_lehrveranstaltung.bezeichnung'
),
$searchstr
) . ')' . $idwhere . '
');
// If something has been found then return it
if (hasData($lehreinheit)) return getData($lehreinheit);
// Otherwise return an empty array
return array();
}
}
@@ -159,6 +159,8 @@ class LvVwLib
if (!$stg->mischform)
return [];
$this->_ci->StudiengangModel->db->select('TRUE AS leaf', false);
return $this->_ci->stglib->orgform($path_template, $stg->studiengang_kz);
}
+19 -24
View File
@@ -31,20 +31,18 @@ class Vertrag_model extends DB_Model
*/
public function save($person_id, $mitarbeiter_uid, $lehrveranstaltung_id, $lehreinheit_id, $projektarbeit_id = null, $vertragsstunden, $betrag, $studiensemester_kurzbz)
{
$vertragstyp_kurzbz = (is_null($projektarbeit_id)) ? 'Lehrauftrag' : 'Betreuung';
$person_id = (isset($person_id) && is_numeric($person_id))
$person_id = (isset($person_id) && is_numeric($person_id))
? $person_id
: show_error('peron_id must be set and numeric.');
$lehreinheit_id = (isset($lehreinheit_id) && is_numeric($lehreinheit_id))
? $lehreinheit_id
: show_error('lehreinheit_id must be set and numeric.');
$lehrveranstaltung_id = (isset($lehrveranstaltung_id) && is_numeric($lehrveranstaltung_id))
? $lehrveranstaltung_id
: show_error('lehrveranstaltung_id must be set and numeric.');
$projektarbeit_id = (isset($projektarbeit_id) && is_numeric($projektarbeit_id))
? $projektarbeit_id
: null;
$lehreinheit_id = (isset($lehreinheit_id) && is_numeric($lehreinheit_id))
? $lehreinheit_id
: (($vertragstyp_kurzbz == 'Betreuung') ? null : show_error('lehreinheit_id must be set and numeric.'));
$vertragsstunden = (isset($vertragsstunden) && is_numeric($vertragsstunden))
? $vertragsstunden
: 0;
@@ -55,7 +53,7 @@ class Vertrag_model extends DB_Model
? $mitarbeiter_uid
: show_error('mitarbeiter_uid must be set and a string value.');;
$vertragstyp_kurzbz = (is_null($projektarbeit_id)) ? 'Lehrauftrag' : 'Betreuung';
// First check if Vertrag already exists for that Lehrauftrag or for that Projektbetreuerauftrag
if ($vertragstyp_kurzbz == 'Lehrauftrag')
@@ -259,7 +257,7 @@ class Vertrag_model extends DB_Model
}
elseif ($vertragstyp_kurzbz == 'Betreuung')
{
$this->addSelect('lehreinheit_id, lehre.tbl_projektarbeit.lehrveranstaltung_id, lehre.tbl_projektarbeit.studiensemester_kurzbz');
$this->addSelect('lehreinheit_id');
$this->addJoin('lehre.tbl_projektbetreuer', 'vertrag_id');
$this->addJoin('lehre.tbl_projektarbeit', 'projektarbeit_id');
if ($result = $this->loadWhere(array('vertrag_id' => $vertrag_id)))
@@ -283,22 +281,17 @@ class Vertrag_model extends DB_Model
{
if ($result = getData($this->getLehreinheitID($vertrag_id)))
{
if (!empty($result[0]->lehreinheit_id))
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->LehreinheitModel->addSelect($select);
if($result = $this->LehreinheitModel->load($result[0]->lehreinheit_id))
{
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->LehreinheitModel->addSelect($select);
if ($result = $this->LehreinheitModel->load($result[0]->lehreinheit_id))
{
return success($result->retval);
}
else
{
return error('Fehler beim Laden der Lehreinheit');
}
return success($result->retval);
}
else
{
return error('Fehler beim Laden der Lehreinheit');
}
return success($result);
}
else
{
@@ -570,13 +563,14 @@ SELECT
null::integer as pruefung_id,
projektarbeit_id,
(tbl_projektbetreuer.stunden*tbl_projektbetreuer.stundensatz) as betrag1,
tbl_projektarbeit.studiensemester_kurzbz,
tbl_lehreinheit.studiensemester_kurzbz,
tbl_projektbetreuer.betreuerart_kurzbz,
(SELECT nachname || ' ' || vorname FROM public.tbl_person JOIN public.tbl_benutzer USING(person_id) WHERE uid=tbl_projektarbeit.student_uid)
as bezeichnung
FROM
lehre.tbl_projektbetreuer
JOIN lehre.tbl_projektarbeit USING(projektarbeit_id)
JOIN lehre.tbl_lehreinheit USING(lehreinheit_id)
WHERE
tbl_projektbetreuer.person_id=?
AND vertrag_id IS NULL
@@ -625,13 +619,14 @@ SELECT
null::integer as pruefung_id,
projektarbeit_id,
(tbl_projektbetreuer.stunden * tbl_projektbetreuer.stundensatz) as betrag,
tbl_projektarbeit.studiensemester_kurzbz,
tbl_lehreinheit.studiensemester_kurzbz,
tbl_projektbetreuer.betreuerart_kurzbz,
(SELECT nachname || ' ' || vorname FROM public.tbl_person JOIN public.tbl_benutzer USING(person_id) WHERE uid=tbl_projektarbeit.student_uid)
as bezeichnung, vertrag_id
FROM
lehre.tbl_projektbetreuer
JOIN lehre.tbl_projektarbeit USING(projektarbeit_id)
JOIN lehre.tbl_lehreinheit USING(lehreinheit_id)
WHERE
tbl_projektbetreuer.person_id=?
AND vertrag_id = ?
@@ -11,73 +11,4 @@ class Mobilitaet_model extends DB_Model
$this->dbTable = 'bis.tbl_mobilitaet';
$this->pk = 'mobilitaet_id';
}
public function getMobilityZusatzForUids($uids) {
$qry = "SELECT distinct on(nachname, vorname, public.tbl_benutzer.person_id) uid,
tbl_mitarbeiter.mitarbeiter_uid,
tbl_note.lkt_ueberschreibbar, tbl_note.anmerkung,
tbl_mobilitaet.mobilitaetstyp_kurzbz,
(CASE WHEN bis.tbl_mobilitaet.studiensemester_kurzbz = vw_student_lehrveranstaltung.studiensemester_kurzbz THEN 1 ELSE 0 END) as doubledegree,
public.tbl_prestudent.gsstudientyp_kurzbz as ddtype,
(SELECT status_kurzbz FROM public.tbl_prestudentstatus
WHERE prestudent_id=tbl_student.prestudent_id
ORDER BY datum DESC, insertamum DESC, ext_id DESC LIMIT 1) as studienstatus
FROM
campus.vw_student_lehrveranstaltung
JOIN public.tbl_benutzer USING(uid)
JOIN public.tbl_person USING(person_id)
LEFT JOIN public.tbl_student ON(uid=student_uid)
LEFT JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid)
LEFT JOIN public.tbl_studentlehrverband USING(student_uid,studiensemester_kurzbz)
LEFT JOIN lehre.tbl_zeugnisnote on(vw_student_lehrveranstaltung.lehrveranstaltung_id=tbl_zeugnisnote.lehrveranstaltung_id
AND tbl_zeugnisnote.student_uid=tbl_student.student_uid
AND tbl_zeugnisnote.studiensemester_kurzbz=tbl_studentlehrverband.studiensemester_kurzbz)
LEFT JOIN lehre.tbl_note USING (note)
LEFT JOIN bis.tbl_bisio ON(uid=tbl_bisio.student_uid)
LEFT JOIN public.tbl_studiengang ON(tbl_student.studiengang_kz=tbl_studiengang.studiengang_kz)
LEFT JOIN bis.tbl_mobilitaet USING(prestudent_id)
LEFT JOIN public.tbl_prestudent USING(prestudent_id)
WHERE uid IN ?";
return $this->execReadOnlyQuery($qry, [$uids]);
}
public function formatZusatz($entry, $erhalter_kz) {
$zusatz = '';
if (isset($entry->studienstatus) && $entry->studienstatus === 'Incoming') {
$zusatz = '(i)';
}
if (isset($entry->lkt_ueberschreibbar) && $entry->lkt_ueberschreibbar === false) {
$zusatz .= ' (' . ($entry->anmerkung ?? '') . ')';
}
if (isset($entry->mitarbeiter_uid) && $entry->mitarbeiter_uid !== null) {
$zusatz .= ' (ma)';
}
if (isset($entry->stg_kz_student) && $entry->stg_kz_student == $erhalter_kz) {
$zusatz .= ' (a.o.)';
}
if (
isset($entry->mobilitaetstyp_kurzbz) && $entry->mobilitaetstyp_kurzbz &&
isset($entry->doubledegree) && $entry->doubledegree === 1
) {
$zusatz .= ' (d.d.';
$ddtype = $entry->ddtype ?? null;
if ($ddtype == 'Intern') {
$zusatz .= 'i.)';
} elseif ($ddtype == 'Extern') {
$zusatz .= 'o.)';
} else {
$zusatz .= ')';
}
}
return $zusatz;
}
}
+35 -52
View File
@@ -20,16 +20,14 @@ class News_model extends DB_Model
public function getAll($limit = null)
{
$this->addJoin("campus.tbl_content","content_id");
return $this->execReadOnlyQuery('
SELECT *, TO_CHAR(campus.tbl_news.datum, ?) as datumformatted
FROM campus.tbl_news
JOIN campus.tbl_content content ON content.content_id = campus.tbl_news.content_id
WHERE
WHERE
--text IS NOT NULL AND
datum <= NOW() AND (datum_bis >= NOW()::date OR datum_bis IS NULL) AND
(NOW()-datum) < interval \'' . MAXNEWSALTER . ' days\'
ORDER BY datum DESC, campus.tbl_news.updateamum DESC
datum <= NOW() AND (datum_bis IS NULL OR datum_bis >= now()::date)
ORDER BY datum DESC
LIMIT ' . $this->escape($limit)
, ['DD/MM/YYYY']);
}
@@ -50,28 +48,31 @@ class News_model extends DB_Model
* @param integer | null $semester
* @param string $fachbereich_kurzbz
* @param boolean $sichtbar
* @param integer $maxalter
* @param integer $page
* @param integer $page_size
* @param boolean $active
* @param boolean $all
* @param boolean $mischen
*
* TODO(chris): this is not a good function -> the params are all over the place
*
*/
protected function prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz = null, $sichtbar = true, $page = 1, $page_size = 10, $active = true, $mischen = true, $filterForDegreePrograms = false, $allowedDegreePrograms = [])
protected function prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz = null, $sichtbar = true, $maxalter = 0, $page = 1, $page_size = 10, $all = false, $mischen = true)
{
$this->addSelect(["*", "COUNT(*) OVER() AS row_count"]);
$this->addOrder('datum', 'DESC');
$this->addOrder('tbl_news.updateamum', 'DESC');
$studiengang_kz = trim($studiengang_kz);
$fachbereich_kurzbz = trim($fachbereich_kurzbz);
$where = [];
if ($active) {
$where[] = "(datum <= NOW()::date AND (datum_bis >= NOW()::date OR (datum_bis IS NULL AND (NOW()-datum) < interval '" . MAXNEWSALTER . " days')))";
if (trim($maxalter) != '0') {
$where[] = "(now()-datum) < interval " . $this->db->escape($maxalter) . " days";
}
if (!$all) {
$where[] = "datum <= now()";
$where[] = "(datum_bis >= now()::date OR datum_bis IS NULL)";
}
if ($fachbereich_kurzbz != '*') {
if ($fachbereich_kurzbz == '') {
@@ -81,54 +82,27 @@ class News_model extends DB_Model
}
}
if ($studiengang_kz == '0') {
$where[] = "studiengang_kz = " . $this->db->escape($studiengang_kz);
$sgAndSemesterCondition = [];
if ($semester === NULL)
$where[] = "semester IS NULL";
elseif ($semester === 0)
$where[] = "semester = 0";
} elseif ($studiengang_kz != '') {
$add = $mischen === true ? " OR (studiengang_kz = 0 AND semester IS NULL)" : "";
$where[] = "((studiengang_kz = " . $this->db->escape($studiengang_kz) . " AND semester = " . $this->db->escape($semester) . ") OR (studiengang_kz = " . $this->db->escape($studiengang_kz) . " AND semester = 0) OR (studiengang_kz = 0 AND semester = " . $this->db->escape($semester) . ")" . $add . ")";
if ($studiengang_kz !== '') {
$sgAndSemesterCondition[] = 'studiengang_kz = ' . $this->db->escape($studiengang_kz);
}
if ($semester !== null && $semester !== 0) {
$sgAndSemesterCondition[] = 'semester = ' . $this->db->escape($semester);
}
$targetedSgAndSemesterCondition = [];
if (!empty($sgAndSemesterCondition)) {
$targetedSgAndSemesterCondition[] = '(' . implode(' AND ', $sgAndSemesterCondition) . ')';
}
if ($mischen === true) {
$targetedSgAndSemesterCondition[] = '(studiengang_kz = 0 AND (semester = 0 OR semester IS NULL))';
if ($semester !== null && $semester !== 0) {
$targetedSgAndSemesterCondition[] = '(studiengang_kz = 0 AND semester = ' . $this->db->escape($semester) . ')';
}
}
$finalSgAndSemesterCondition = implode(' OR ', $targetedSgAndSemesterCondition);
if ($finalSgAndSemesterCondition !== '') {
$where[] = "(" . $finalSgAndSemesterCondition . ")";
}
$this->addJoin('campus.tbl_contentsprache cs', 'content_id');
if (is_bool($sichtbar) || $sichtbar === 'true' || $sichtbar === 'false') {
$isSichtbar = filter_var($sichtbar, FILTER_VALIDATE_BOOLEAN);
$where[] = "cs.sichtbar = " . ($isSichtbar ? "true" : "false");
}
$where[] = "cs.sichtbar = " . ($sichtbar ? "true" : "false");
$where[] = "cs.sprache = (CASE WHEN EXISTS(SELECT 1 FROM campus.tbl_contentsprache cs2 WHERE cs2.content_id=" . $this->dbTable . ".content_id AND sprache=" . $this->db->escape($sprache) . ") THEN " . $this->db->escape($sprache) . " ELSE " . $this->db->escape(DEFAULT_LANGUAGE) . " END)";
$where[] = "cs.version = (SELECT MAX(version) FROM campus.tbl_contentsprache cs3 WHERE cs3.content_id=" . $this->dbTable . ".content_id AND cs3.sprache = (CASE WHEN EXISTS(SELECT 1 FROM campus.tbl_contentsprache cs2 WHERE cs2.content_id=" . $this->dbTable . ".content_id AND sprache=" . $this->db->escape($sprache) . ") THEN " . $this->db->escape($sprache) . " ELSE " . $this->db->escape(DEFAULT_LANGUAGE) . " END))";
if ($filterForDegreePrograms) {
if (empty($allowedDegreePrograms)) {
$where[] = "1=0";
} else {
$where[] = "studiengang_kz IN (" . implode(',', array_map([$this->db, 'escape'], $allowedDegreePrograms)) . ")";
}
}
$where = implode(" AND ", $where);
@@ -136,16 +110,25 @@ class News_model extends DB_Model
}
public function getNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz = null, $sichtbar = true, $page = 1, $page_size = 10, $active = true, $mischen = true, $filterForDegreePrograms = false, $allowedDegreePrograms = [])
public function getNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz = null, $sichtbar = true, $maxalter = 0, $page = 1, $page_size = 10, $all = false, $mischen = true)
{
$this->prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $page, $page_size, $active, $mischen, $filterForDegreePrograms, $allowedDegreePrograms);
$this->prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $page_size, $all, $mischen);
// getting the number of rows of the query and adding pagination to the query result
$num_rows = $this->getNumRows(true);
$this->addPagination($page, $page_size, $num_rows);
// preparing the query again because every call to get_compiled_select or cour_all_results will add the from clause to the query
$this->prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $page, $page_size, $active, $mischen, $filterForDegreePrograms, $allowedDegreePrograms);
$this->prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $page_size, $all, $mischen);
return $this->load();
}
public function countNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz = null, $sichtbar = true, $maxalter = 0, $page = 1, $page_size = 10, $all = false, $mischen = true)
{
$this->prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $page_size, $all, $mischen);
return $this->getNumRows();
}
}
@@ -88,30 +88,6 @@ class Prestudent_model extends DB_Model
return $this->execQuery($query, $parametersArray);
}
/**
* Gets the Studiengang and current Ausbildungssemester for every
* Prestudent belonging to the same person as the student.
*
* @param string $student_uid
* @return stdClass
*/
public function getStudiengaengAndAusbildungssemesterByStudentUid($student_uid)
{
$query = 'SELECT p.studiengang_kz,
(
SELECT ps.ausbildungssemester
FROM public.tbl_prestudentstatus ps
WHERE ps.prestudent_id = p.prestudent_id
ORDER BY ps.datum DESC, ps.insertamum DESC, ps.ext_id DESC
LIMIT 1
) AS ausbildungssemester
FROM public.tbl_student s
JOIN public.tbl_prestudent p USING (prestudent_id)
WHERE s.student_uid = ?';
return $this->execQuery($query, array($student_uid));
}
/**
* updateAufnahmegruppe
*/
@@ -177,7 +177,7 @@ class Prestudentstatus_model extends DB_Model
* @param prestudent_id ID of the Prestudent.
* @param $status_kurzbz kurzbz of the status.
* @param $ausbildungssemester ausbildungssemester of the status.
* @param $studiensemester_kurzbz studiensemester of the status.
* @param $studiensemester_kurzbz studiensemster of the status.
*
* @return result object with all the status entries
*/
@@ -100,14 +100,12 @@ class Abschlusspruefung_model extends DB_Model
if (isError($abschlussarbeit))
return $abschlussarbeit;
if (hasData($abschlussarbeit))
{
$abschlussarbeit = getData($abschlussarbeit)[0];
$abschlusspruefungdata->projektarbeit_studiengangstyp_name = $abschlussarbeit->projekttyp_kurzbz;
$abschlusspruefungdata->abschlussarbeit_titel = $abschlussarbeit->titel;
$abschlusspruefungdata->abschlussarbeit_note = $abschlussarbeit->note;
$abschlusspruefungdata->abschlussarbeit_sprache = $abschlussarbeit->sprache_bezeichnung;
}
}
}
@@ -52,53 +52,4 @@ class LePruefung_model extends DB_Model
'student_uid' => $student_uid
]);
}
public function getPruefungenByLvStudiensemester($lv_id, $sem_kurzbz) {
$qry = "SELECT lehre.tbl_pruefung.*, tbl_lehrveranstaltung.bezeichnung as lehrveranstaltung_bezeichnung, tbl_lehrveranstaltung.lehrveranstaltung_id,
tbl_note.bezeichnung as note_bezeichnung, tbl_pruefungstyp.beschreibung as typ_beschreibung, tbl_lehreinheit.studiensemester_kurzbz as studiensemester_kurzbz
FROM lehre.tbl_pruefung, lehre.tbl_lehreinheit, lehre.tbl_lehrveranstaltung, lehre.tbl_note, lehre.tbl_pruefungstyp
WHERE lehre.tbl_pruefung.lehreinheit_id=tbl_lehreinheit.lehreinheit_id
AND tbl_lehreinheit.lehrveranstaltung_id=tbl_lehrveranstaltung.lehrveranstaltung_id
AND lehre.tbl_pruefung.note = tbl_note.note
AND lehre.tbl_pruefung.pruefungstyp_kurzbz=tbl_pruefungstyp.pruefungstyp_kurzbz
AND tbl_lehrveranstaltung.lehrveranstaltung_id = ?
AND tbl_lehreinheit.studiensemester_kurzbz = ?
ORDER BY datum DESC;";
return $this->execReadOnlyQuery($qry, array($lv_id, $sem_kurzbz));
}
public function getPruefungenByUidTypLvStudiensemester($uid, $typ = null, $lv_id = null, $sem_kurzbz = null) {
$params = [$uid];
$qry = "SELECT tbl_pruefung.*, tbl_lehrveranstaltung.bezeichnung as lehrveranstaltung_bezeichnung, tbl_lehrveranstaltung.lehrveranstaltung_id,
tbl_note.bezeichnung as note_bezeichnung, tbl_pruefungstyp.beschreibung as typ_beschreibung, tbl_lehreinheit.studiensemester_kurzbz as studiensemester_kurzbz
FROM lehre.tbl_pruefung, lehre.tbl_lehreinheit, lehre.tbl_lehrveranstaltung, lehre.tbl_note, lehre.tbl_pruefungstyp
WHERE student_uid= ?
AND tbl_pruefung.lehreinheit_id=tbl_lehreinheit.lehreinheit_id
AND tbl_lehreinheit.lehrveranstaltung_id=tbl_lehrveranstaltung.lehrveranstaltung_id
AND tbl_pruefung.note = tbl_note.note
AND tbl_pruefung.pruefungstyp_kurzbz=tbl_pruefungstyp.pruefungstyp_kurzbz";
if ($typ != null)
{
$qry .= " AND tbl_pruefungstyp.pruefungstyp_kurzbz = ?";
$params[] = $typ;
}
if ($lv_id != null)
{
$qry .= " AND tbl_lehrveranstaltung.lehrveranstaltung_id = ?";
$params[] = $lv_id;
}
if ($sem_kurzbz != null)
{
$qry .= " AND tbl_lehreinheit.studiensemester_kurzbz = ?";
$params[] = $sem_kurzbz;
}
$qry .= " ORDER BY datum DESC";
return $this->execReadOnlyQuery($qry, $params);
}
}
@@ -340,20 +340,6 @@ EOSQL;
}
public function getByLeStudiensemester($lehreinheit_id, $studiensemester_kurzbz)
{
$qry = "WITH lehreinheiten AS (
SELECT *
FROM lehre.tbl_lehreinheit
WHERE lehreinheit_id = ?
AND studiensemester_kurzbz = ?
)," . $this->_getLeCTE();
$params = array($lehreinheit_id, $studiensemester_kurzbz);
return $this->execReadOnlyQuery($qry, $params);
}
public function getByLvidStudiensemester($lv_id, $studiensemester_kurzbz, $mitarbeiter_uid = null, $fachbereich_kurzbz = null)
{
$qry = "WITH lehreinheiten AS (
@@ -361,7 +347,35 @@ EOSQL;
FROM lehre.tbl_lehreinheit
WHERE lehrveranstaltung_id = ?
AND studiensemester_kurzbz = ?
)," . $this->_getLeCTE();
),
". $this->_getGruppenCTE() . ",
". $this->_getLektorenCTE() . ",
". $this->_getFachbereichCTE() . ",
". $this->_getTagsCTE() . "
SELECT lehreinheiten.*,
lehreinheiten.lehrform_kurzbz as lv_lehrform_kurzbz,
tbl_lehrveranstaltung.kurzbz as lv_kurzbz,
tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung,
COALESCE(tag_data_agg.tags, '[]'::json) AS tags,
gruppen.gruppen,
mitarbeiter.lektoren,
mitarbeiter.le_planstunden,
mitarbeiter.vorname,
mitarbeiter.nachname,
mitarbeiter.semesterstunden,
fachbereich.bezeichnung as fachbereich,
UPPER(CONCAT(tbl_studiengang.typ,tbl_studiengang.kurzbz)) as studiengang,
semester
FROM lehreinheiten
LEFT JOIN lehre.tbl_lehrveranstaltung ON tbl_lehrveranstaltung.lehrveranstaltung_id = lehreinheiten.lehrfach_id
LEFT JOIN public.tbl_studiengang USING(studiengang_kz)
LEFT JOIN tag_data_agg ON tag_data_agg.lehreinheit_id = lehreinheiten.lehreinheit_id
LEFT JOIN mitarbeiter ON lehreinheiten.lehreinheit_id = mitarbeiter.lehreinheit_id
LEFT JOIN fachbereich ON lehreinheiten.lehreinheit_id = fachbereich.lehreinheit_id
LEFT JOIN gruppen ON lehreinheiten.lehreinheit_id = gruppen.lehreinheit_id
WHERE true
";
$params = array($lv_id, $studiensemester_kurzbz);
@@ -381,83 +395,9 @@ EOSQL;
return $this->execReadOnlyQuery($qry, $params);
}
public function getOffeneStunden($lehreinheit_ids)
private function getLVTmp($stg_kz = null)
{
if (!is_array($lehreinheit_ids))
$lehreinheit_ids = [$lehreinheit_ids];
if (empty($lehreinheit_ids))
return success([]);
$db = new DB_Model();
$placeholders = implode(',', array_fill(0, count($lehreinheit_ids), '?'));
$qry = "WITH eventdauer AS (
SELECT
tbl_kalender_lehreinheit.lehreinheit_id,
tbl_kalender.von,
tbl_kalender.bis,
tbl_kalender.kalender_id
FROM lehre.tbl_lehreinheit
JOIN lehre.tbl_kalender_lehreinheit USING(lehreinheit_id)
JOIN lehre.tbl_kalender USING(kalender_id)
WHERE tbl_lehreinheit.lehreinheit_id IN ($placeholders)
AND NOT EXISTS (SELECT 1 FROM lehre.tbl_kalender nachfolger
WHERE nachfolger.vorgaenger_kalender_id = tbl_kalender.kalender_id)
AND tbl_kalender.status_kurzbz NOT IN ('deleted', 'todelete', 'archived')
GROUP BY tbl_kalender_lehreinheit.lehreinheit_id, tbl_kalender.von, tbl_kalender.bis, tbl_kalender.kalender_id
),
raster AS (
SELECT
eventdauer.lehreinheit_id,
eventdauer.kalender_id,
eventdauer.von,
eventdauer.bis,
vonstunde.stunde AS vonstunde_nr,
bisstunde.stunde AS bisstunde_nr
FROM eventdauer
LEFT JOIN lehre.tbl_stunde vonstunde ON eventdauer.von::time = vonstunde.beginn
LEFT JOIN lehre.tbl_stunde bisstunde ON eventdauer.bis::time = bisstunde.ende
),
unterrichtsdauer AS (
SELECT
raster.lehreinheit_id,
raster.kalender_id,
sum(EXTRACT(EPOCH FROM (LEAST(stunde.ende, raster.bis::time) - GREATEST(stunde.beginn, raster.von::time))) / 60) AS minuten
FROM raster JOIN lehre.tbl_stunde stunde ON stunde.beginn < raster.bis::time AND stunde.ende > raster.von::time
WHERE raster.vonstunde_nr IS NULL OR raster.bisstunde_nr IS NULL
GROUP BY raster.lehreinheit_id, raster.kalender_id
),
verplantestunden AS (
SELECT raster.lehreinheit_id, raster.kalender_id,
CASE
WHEN raster.vonstunde_nr IS NOT NULL AND raster.bisstunde_nr IS NOT NULL
THEN (raster.bisstunde_nr - raster.vonstunde_nr + 1)
ELSE coalesce(unterrichtsdauer.minuten, 0) / 45
END AS verplantestunde
FROM raster LEFT JOIN unterrichtsdauer ON unterrichtsdauer.lehreinheit_id = raster.lehreinheit_id AND unterrichtsdauer.kalender_id = raster.kalender_id
),
verplant_gesamt AS (
SELECT lehreinheit_id, SUM(verplantestunde) AS verplant
FROM verplantestunden
GROUP BY lehreinheit_id
)
SELECT
lema.lehreinheit_id,
lema.mitarbeiter_uid,
lema.planstunden,
ROUND(coalesce(verplant_gesamt.verplant, 0), 2) AS verplant,
ROUND((lema.planstunden - coalesce(verplant_gesamt.verplant, 0)), 2) AS offenestunden
FROM lehre.tbl_lehreinheitmitarbeiter lema
LEFT JOIN verplant_gesamt ON verplant_gesamt.lehreinheit_id = lema.lehreinheit_id
WHERE lema.lehreinheit_id IN ($placeholders)";
return $db->execReadOnlyQuery($qry, array_merge($lehreinheit_ids, $lehreinheit_ids));
}
private function getLVTmp()
{
return "SELECT DISTINCT ON(lehrveranstaltung_id) *,
$qry = "SELECT DISTINCT ON(lehrveranstaltung_id) *,
'' as stundenblockung,
'' as lehreinheit_id,
'' as wochenrythmus,
@@ -468,33 +408,24 @@ EOSQL;
'' as studienplan_beeichnung,
UPPER(CONCAT(vw_lehreinheit.stg_typ, vw_lehreinheit.stg_kurzbz)) as studiengang
FROM campus.vw_lehreinheit
WHERE studiensemester_kurzbz = ? ";
WHERE mitarbeiter_uid = ?
AND studiensemester_kurzbz = ?";
if (!is_null($stg_kz)) {
$qry .= " AND lv_studiengang_kz = ?";
}
return $qry;
}
public function getLvsById($lehrveranstaltung_id, $studiensemester_kurzbz)
{
$where = ' AND lehrveranstaltung_id = ?';
$qry = "WITH lvs AS (" . $this->getLVTmp() . $where .")
SELECT lvs.*
FROM lvs
";
$params = array($studiensemester_kurzbz, $lehrveranstaltung_id);
return $this->execReadOnlyQuery($qry, $params);
}
public function getLvsByEmployee($mitarbeiter_uid, $studiensemester_kurzbz, $stg_kz = null)
{
$where = ' AND mitarbeiter_uid = ?';
if ($stg_kz != null)
$where .= " AND lv_studiengang_kz = ?";
$qry = "WITH lvs AS (" . $this->getLVTmp() . $where .")
$qry = "WITH lvs AS (" . $this->getLVTmp($stg_kz) . ")
SELECT lvs.*
FROM lvs";
$params = array($studiensemester_kurzbz, $mitarbeiter_uid);
FROM lvs
";
$params = array($mitarbeiter_uid, $studiensemester_kurzbz);
if (!is_null($stg_kz))
{
$params[] = $stg_kz;
@@ -701,36 +632,6 @@ EOSQL;
return success('Contract successfully updated.');
}
private function _getLeCTE()
{
return $this->_getGruppenCTE() . ",
". $this->_getLektorenCTE() . ",
". $this->_getFachbereichCTE() . ",
". $this->_getTagsCTE() . "
SELECT lehreinheiten.*,
lehreinheiten.lehrform_kurzbz as lv_lehrform_kurzbz,
tbl_lehrveranstaltung.kurzbz as lv_kurzbz,
tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung,
COALESCE(tag_data_agg.tags, '[]'::json) AS tags,
gruppen.gruppen,
mitarbeiter.lektoren,
mitarbeiter.le_planstunden,
mitarbeiter.vorname,
mitarbeiter.nachname,
mitarbeiter.semesterstunden,
fachbereich.bezeichnung as fachbereich,
UPPER(CONCAT(tbl_studiengang.typ,tbl_studiengang.kurzbz)) as studiengang,
semester
FROM lehreinheiten
LEFT JOIN lehre.tbl_lehrveranstaltung ON tbl_lehrveranstaltung.lehrveranstaltung_id = lehreinheiten.lehrfach_id
LEFT JOIN public.tbl_studiengang USING(studiengang_kz)
LEFT JOIN tag_data_agg ON tag_data_agg.lehreinheit_id = lehreinheiten.lehreinheit_id
LEFT JOIN mitarbeiter ON lehreinheiten.lehreinheit_id = mitarbeiter.lehreinheit_id
LEFT JOIN fachbereich ON lehreinheiten.lehreinheit_id = fachbereich.lehreinheit_id
LEFT JOIN gruppen ON lehreinheiten.lehreinheit_id = gruppen.lehreinheit_id
WHERE true";
}
private function _getGruppenCTE()
{
return "gruppen AS (
@@ -840,69 +741,4 @@ EOSQL;
)";
}
public function getAllLehreinheitenForLvaAndMaUid($lva_id, $ma_uid, $sem_kurzbz)
{
$query = "SELECT DISTINCT tbl_lehreinheitmitarbeiter.lehreinheit_id, tbl_lehreinheit.lehrveranstaltung_id, tbl_lehreinheit.lehrform_kurzbz,
tbl_lehreinheitmitarbeiter.mitarbeiter_uid,
tbl_lehreinheitgruppe.semester,
tbl_lehreinheitgruppe.verband,
tbl_lehreinheitgruppe.gruppe,
tbl_lehreinheitgruppe.gruppe_kurzbz,
tbl_lehrveranstaltung.kurzbz,
tbl_studiengang.kurzbzlang,
(SELECT COUNT(DISTINCT datum) FROM campus.vw_stundenplan WHERE lehreinheit_id = lehre.tbl_lehreinheit.lehreinheit_id) as termincount,
(SELECT COUNT(*) FROM campus.vw_student_lehrveranstaltung WHERE lehreinheit_id = lehre.tbl_lehreinheit.lehreinheit_id) as studentcount
FROM lehre.tbl_lehreinheit JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id)
JOIN lehre.tbl_lehreinheitgruppe USING(lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN public.tbl_studiengang ON (tbl_lehreinheitgruppe.studiengang_kz = tbl_studiengang.studiengang_kz)
WHERE lehrveranstaltung_id = ? AND studiensemester_kurzbz = ? AND mitarbeiter_uid = ?
ORDER BY tbl_lehreinheitgruppe.gruppe_kurzbz";
return $this->execQuery($query, [$lva_id, $sem_kurzbz, $ma_uid]);
}
public function getLehrenheitenBySemester($uid, $semester)
{
$query = "SELECT
tbl_lehreinheit.lehreinheit_id,
lehrfach.kurzbz as lehrfach,
tbl_lehreinheit.lehrform_kurzbz as lehrform,
tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung,
(SELECT kurzbz FROM public.tbl_mitarbeiter
WHERE mitarbeiter_uid=tbl_lehreinheitmitarbeiter.mitarbeiter_uid) as lektor,
UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as stg_kurzbz,
tbl_lehrveranstaltung.semester as lv_semester,
tbl_lehreinheit.raumtyp,
tbl_lehreinheit.raumtypalternativ,
tbl_lehreinheit.stundenblockung,
tbl_lehreinheit.wochenrythmus,
tbl_lehreinheitmitarbeiter.semesterstunden as semesterstunden,
tbl_lehreinheit.start_kw,
lvangebot.anmeldefenster_start,
lvangebot.anmeldefenster_ende,
tbl_lehrveranstaltung.lehrveranstaltung_id
FROM
lehre.tbl_lehreinheit JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN public.tbl_studiengang USING(studiengang_kz)
JOIN lehre.tbl_lehrveranstaltung as lehrfach ON(tbl_lehreinheit.lehrfach_id=lehrfach.lehrveranstaltung_id)
LEFT JOIN lehre.tbl_lvangebot as lvangebot ON(tbl_lehrveranstaltung.lehrveranstaltung_id=lvangebot.lehrveranstaltung_id)
WHERE
tbl_lehreinheit.studiensemester_kurzbz = '$semester'
AND mitarbeiter_uid = '$uid'
ORDER BY stg_kurzbz,lv_semester,lv_bezeichnung";
return $this->execReadOnlyQuery($query);
}
public function getGroupsByLehreinheit($lehreinheitId)
{
$query = "SELECT *
FROM lehre.tbl_lehreinheitgruppe
WHERE lehreinheit_id='$lehreinheitId'";
return $this->execReadOnlyQuery($query);
}
}
@@ -85,18 +85,9 @@ class Lehreinheitmitarbeiter_model extends DB_Model
public function getLektorenByLe($lehreinheit_id)
{
$this->addSelect('tbl_person.vorname, tbl_person.nachname, tbl_lehreinheitmitarbeiter.*, stundenplan.verplant,
COALESCE(insertvonperson.vorname || \' \' || insertvonperson.nachname, tbl_lehreinheitmitarbeiter.insertvon) as insertvon,
COALESCE(updatevonperson.vorname || \' \' || updatevonperson.nachname, tbl_lehreinheitmitarbeiter.updatevon) as updatevon');
$this->addSelect('vorname, nachname, tbl_lehreinheitmitarbeiter.*, stundenplan.verplant');
$this->addJoin('tbl_benutzer', 'uid = mitarbeiter_uid');
$this->addJoin('tbl_person', 'person_id');
$this->addJoin('tbl_benutzer insertvonbenutzer', 'insertvonbenutzer.uid = tbl_lehreinheitmitarbeiter.insertvon', 'LEFT');
$this->addJoin('tbl_person insertvonperson', 'insertvonperson.person_id = insertvonbenutzer.person_id', 'LEFT');
$this->addJoin('tbl_benutzer updatevonbenutzer', 'updatevonbenutzer.uid = tbl_lehreinheitmitarbeiter.updatevon', 'LEFT');
$this->addJoin('tbl_person updatevonperson', 'updatevonperson.person_id = updatevonbenutzer.person_id', 'LEFT');
$this->addJoin('(
SELECT 1 as verplant, lehreinheit_id, mitarbeiter_uid
@@ -317,7 +317,7 @@ class Lehrveranstaltung_model extends DB_Model
tbl_bisio.bisio_id, tbl_bisio.von, tbl_bisio.bis, tbl_student.studiengang_kz AS stg_kz_student,
tbl_zeugnisnote.note, tbl_mitarbeiter.mitarbeiter_uid, tbl_person.matr_nr, tbl_benutzer.uid,
UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as kuerzel, tbl_studiengang.orgform_kurzbz, vw_student_lehrveranstaltung.semester, vw_student_lehrveranstaltung.studiensemester_kurzbz, vw_student_lehrveranstaltung.bezeichnung,
tbl_student.prestudent_id, campus.vw_student_lehrveranstaltung.lehreinheit_id
tbl_student.prestudent_id
FROM
campus.vw_student_lehrveranstaltung
JOIN public.tbl_benutzer USING(uid)
@@ -1263,39 +1263,6 @@ class Lehrveranstaltung_model extends DB_Model
";
}
/**
* Gets lehrveranstaltungen of Studienplan of a certain lva_id set
* used if a bigger set of lva id is already available and it needs to be checked against a certain studienplan aswell
* @param $studienplan_id ID des Studienplans
* @param $lva_ids LVA_ID welche abgegleicht werden sollen
* @return array|null
*/
public function getLvsByStudienplanByLvaIDs($studienplan_id, $lva_ids)
{
$params = array($studienplan_id, $lva_ids);
$qry = "SELECT tbl_lehrveranstaltung.*,
tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id,
tbl_studienplan_lehrveranstaltung.semester as stpllv_semester,
tbl_studienplan_lehrveranstaltung.pflicht as stpllv_pflicht,
tbl_studienplan_lehrveranstaltung.koordinator as stpllv_koordinator,
tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id_parent,
tbl_studienplan_lehrveranstaltung.sort stpllv_sort,
tbl_studienplan_lehrveranstaltung.curriculum,
tbl_studienplan_lehrveranstaltung.export,
tbl_studienplan_lehrveranstaltung.genehmigung
FROM lehre.tbl_lehrveranstaltung
JOIN lehre.tbl_studienplan_lehrveranstaltung
USING(lehrveranstaltung_id)
WHERE tbl_studienplan_lehrveranstaltung.studienplan_id = ?
AND tbl_studienplan_lehrveranstaltung.lehrveranstaltung_id IN ?
";
$qry .= " ORDER BY stpllv_sort, semester, sort";
return $this->execQuery($qry, $params);
}
public function getAllOe($lv_id)
{
$qry = "SELECT DISTINCT oe_kurzbz
@@ -1379,114 +1346,4 @@ class Lehrveranstaltung_model extends DB_Model
return $this->execQuery($qry, $params);
}
public function getLvForLektorInSemester($sem_kurzbz, $uid) {
$qry = "SELECT DISTINCT (tbl_lehrveranstaltung.lehrveranstaltung_id),
UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as stg_kurzbz,
tbl_studiengang.studiengang_kz,
tbl_lehrveranstaltung.semester as lv_semester,
tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung,
(SELECT kurzbz FROM public.tbl_mitarbeiter
WHERE mitarbeiter_uid=tbl_lehreinheitmitarbeiter.mitarbeiter_uid) as lektor,
lehre.tbl_lehrveranstaltung.orgform_kurzbz as orgform
FROM
lehre.tbl_lehreinheit JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN public.tbl_studiengang USING(studiengang_kz)
JOIN lehre.tbl_lehrveranstaltung as lehrfach ON(tbl_lehreinheit.lehrfach_id=lehrfach.lehrveranstaltung_id)
WHERE
tbl_lehreinheit.studiensemester_kurzbz = ?
AND mitarbeiter_uid = ?
ORDER BY stg_kurzbz,lv_semester,lv_bezeichnung";
return $this->execReadOnlyQuery($qry, array($sem_kurzbz, $uid));
}
// used for cis4 mylv mitarbeiter
public function getLvsByMitarbeiterInSemester($mitarbeiter_uid, $sem_kurzbz) {
$qry = "SELECT * FROM (
SELECT DISTINCT ON (lehre.tbl_lehrveranstaltung.lehrveranstaltung_id)
public.tbl_studiengang.studiengang_kz,
lehre.tbl_lehrveranstaltung.semester,
public.tbl_studiengang.bezeichnung as sg_bezeichnung,
public.tbl_studiengang.english as sg_bezeichnung_eng,
UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as studiengang_kuerzel,
lehre.tbl_lehrveranstaltung.lehrveranstaltung_id,
lehre.tbl_lehrveranstaltung.bezeichnung,
lehre.tbl_lehrveranstaltung.bezeichnung_english as bezeichnung_eng,
lehre.tbl_lehrveranstaltung.farbe,
lehre.tbl_lehrveranstaltung.lvinfo,
lehre.tbl_lehrveranstaltung.benotung,
lehre.tbl_lehrveranstaltung.orgform_kurzbz,
lehre.tbl_lehrveranstaltung.sprache,
lehre.tbl_lehrveranstaltung.ects,
lehre.tbl_lehrveranstaltung.incoming
FROM
lehre.tbl_lehreinheit JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN public.tbl_studiengang USING(studiengang_kz)
JOIN lehre.tbl_lehrveranstaltung as lehrfach ON(tbl_lehreinheit.lehrfach_id=lehrfach.lehrveranstaltung_id)
WHERE
tbl_lehreinheit.studiensemester_kurzbz = ?
AND mitarbeiter_uid = ?) as distincted_by_lva_id
JOIN (
SELECT lehrveranstaltung_id, TRUNC(SUM(lehre.tbl_lehreinheitmitarbeiter.semesterstunden)) as semesterstunden
FROM lehre.tbl_lehreinheit
JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
WHERE tbl_lehreinheit.studiensemester_kurzbz = ?
AND mitarbeiter_uid = ?
GROUP BY lehrveranstaltung_id
) semesterstundenAggregatedSubquery USING(lehrveranstaltung_id)
ORDER BY studiengang_kuerzel, semester, bezeichnung";
return $this->execReadOnlyQuery($qry, [$sem_kurzbz, $mitarbeiter_uid, $sem_kurzbz, $mitarbeiter_uid]);
}
/**
* All Lehrveranstaltungen of a Studiengang offered in a Studiensemester.
*/
public function getLvForStudiengangInSemester($sem_kurzbz, $studiengang_kz) {
$qry = "SELECT DISTINCT (tbl_lehrveranstaltung.lehrveranstaltung_id),
UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as stg_kurzbz,
tbl_studiengang.studiengang_kz,
tbl_lehrveranstaltung.semester as lv_semester,
tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung,
tbl_lehrveranstaltung.orgform_kurzbz as orgform
FROM
lehre.tbl_lehrveranstaltung JOIN public.tbl_studiengang USING(studiengang_kz)
WHERE
tbl_lehrveranstaltung.studiengang_kz = ?
AND tbl_lehrveranstaltung.aktiv = TRUE
AND EXISTS (
SELECT 1 FROM lehre.tbl_lehreinheit le
WHERE le.lehrveranstaltung_id = tbl_lehrveranstaltung.lehrveranstaltung_id
AND le.studiensemester_kurzbz = ?
)
ORDER BY stg_kurzbz,lv_semester,lv_bezeichnung";
return $this->execReadOnlyQuery($qry, array($studiengang_kz, $sem_kurzbz));
}
/**
* Number of Lehreinheit assignments the given mitarbeiter has for a Lehrveranstaltung (i.e. whether
* they teach it), optionally restricted to a Studiensemester. Returns a single row with a `teaches`
* count - check `teaches > 0`. Used to scope teacher access in the Benotungstool to their own LVs.
*/
public function getLektorIsTeachingLva($lva_id, $ma_uid, $studiensemester_kurzbz = null)
{
$params = array($lva_id, $ma_uid);
$query = "SELECT COUNT(*) AS teaches
FROM lehre.tbl_lehreinheitmitarbeiter
JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
WHERE lehrveranstaltung_id = ? AND mitarbeiter_uid = ?";
if ($studiensemester_kurzbz !== null && $studiensemester_kurzbz !== '') {
$query .= " AND tbl_lehreinheit.studiensemester_kurzbz = ?";
$params[] = $studiensemester_kurzbz;
}
return $this->execReadOnlyQuery($query, $params);
}
}
@@ -14,7 +14,7 @@ class Lvgesamtnote_model extends DB_Model
}
/**
* Laedt die Noten - lvgesamtnote (Vorschlag) JOIN tbl.note (zeugnisnote)
* Laedt die Noten
*
* @param integer $lehrveranstaltung_id
* @param string $student_uid
@@ -50,19 +50,4 @@ class Lvgesamtnote_model extends DB_Model
return $this->loadWhere($where);
}
public function getLvGesamtNoteVorschlag($lehrveranstaltung_id, $student_uid, $studiensemester_kurzbz)
{
$qry = "SELECT * FROM campus.tbl_lvgesamtnote
WHERE campus.tbl_lvgesamtnote.student_uid = ?
AND campus.tbl_lvgesamtnote.studiensemester_kurzbz = ?";
$params = [$student_uid, $studiensemester_kurzbz];
if ($lehrveranstaltung_id) {
$qry .= " AND campus.tbl_lvgesamtnote.lehrveranstaltung_id = ?";
$params[] = $lehrveranstaltung_id;
}
return $this->execReadOnlyQuery($qry, $params);
}
}
+1 -22
View File
@@ -11,33 +11,12 @@ class Note_model extends DB_Model
$this->dbTable = 'lehre.tbl_note';
$this->pk = 'note';
}
public function getAllActive() {
$qry ="SELECT *
FROM lehre.tbl_note
WHERE aktiv = true";
return $this->execReadOnlyQuery($qry);
}
// used to determine the primary key of note "entschuldigt" to avoid hardcoded magic numbers
// that might differ in a different installation of fhcomplete
public function getEntschuldigtNote() {
$qry ="SELECT *
FROM lehre.tbl_note
WHERE bezeichnung = 'entschuldigt'";
return $this->execReadOnlyQuery($qry);
}
// used to determine the primary key of note "noch nicht eingetragen" to avoid hardcoded magic numbers
// that might differ in a different installation of fhcomplete
public function getNochNichtEingetragenNote() {
$qry ="SELECT *
FROM lehre.tbl_note
WHERE bezeichnung = 'Noch nicht eingetragen'";
return $this->execReadOnlyQuery($qry);
}
}
@@ -13,7 +13,7 @@ class Notenschluesselaufteilung_model extends DB_Model
}
/**
* Gives the grade for the points of a course.
* Liefert die Note zu Punkten einer Lehrveranstaltung
*
* @param number $points
* @param integer $lehrveranstaltung_id
@@ -23,18 +23,9 @@ class Notenschluesselaufteilung_model extends DB_Model
*/
public function getNote($points, $lehrveranstaltung_id, $studiensemester_kurzbz)
{
// Without a valid points value you cannot derive a grade. Without this guard the query
// builder makes a bad statement from "punkte <=" => null ('punkte' < 'IS' 'NULL'). The
// request then fails with HTTP 500 instead of an answer that says "no grade".
if (!is_numeric($points))
return success(null);
$this->load->model('education/Notenschluesselzuordnung_model', 'NotenschluesselzuordnungModel');
$notenschluessel_kurzbz = $this->NotenschluesselzuordnungModel->getKurzbzForLv($lehrveranstaltung_id, $studiensemester_kurzbz);
if($notenschluessel_kurzbz == null)
return success(null);
$this->addSelect("note");
$this->addOrder("punkte", "DESC");
$this->addLimit(1);
+9 -172
View File
@@ -50,7 +50,8 @@ class Paabgabe_model extends DB_Model
JOIN lehre.tbl_projektbetreuer USING(projektarbeit_id)
JOIN public.tbl_benutzer bn_student ON(tbl_projektarbeit.student_uid=bn_student.uid)
JOIN public.tbl_person person_student ON(bn_student.person_id=person_student.person_id)
JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN lehre.tbl_lehreinheit ON(tbl_projektarbeit.lehreinheit_id=tbl_lehreinheit.lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung ON(tbl_lehreinheit.lehrveranstaltung_id=tbl_lehrveranstaltung.lehrveranstaltung_id)
JOIN public.tbl_studiengang ON(tbl_lehrveranstaltung.studiengang_kz=tbl_studiengang.studiengang_kz)
JOIN campus.tbl_paabgabetyp USING(paabgabetyp_kurzbz)
WHERE
@@ -60,172 +61,6 @@ class Paabgabe_model extends DB_Model
return $this->execReadOnlyQuery($qry, array($person_id));
}
/**
* Gets project submissions for search criteria.
* @param array $projekttyp_kurzbz_arr contains all relevant project types (e.g. Bachelor)
* @param int $studiengang_kz study program
* @param string $abgabetyp_kurzbz project submission type (e.g. end upload, intermediate submission)
* @param string $abgabedatum due date for hand-in
* @param string $personSearchString for searching by person, i.e. name, uid, person/prestudent id
* @param int $limit limiting max number of results if search criteria is not precise enough
* @return object
*/
public function getPaAbgaben(
$projekttyp_kurzbz_arr,
$studiengang_kz = null,
$abgabetyp_kurzbz = null,
$abgabedatum = null,
$personSearchString = null,
$limit = 1000
) {
$params = [];
$qry = "
SELECT
stg.bezeichnung AS stgbez, paabg.datum AS termin,
paabg.paabgabe_id, paabg.projektarbeit_id, paabg.paabgabetyp_kurzbz, paabg.abgabedatum,
abgabetyp.bezeichnung AS paabgabetyp_bezeichnung, ben.uid, pers.vorname, pers.nachname, pa.projekttyp_kurzbz, pa.titel,
UPPER(stg.typ || stg.kurzbz) AS studiengang_kuerzel,
(
/* show all relevant Studiengänge of person and wether it is an employee*/
SELECT
STRING_AGG(studiengang || ' ' || last_status, ' | ')
|| (CASE WHEN EXISTS (
SELECT 1 FROM public.tbl_mitarbeiter ma
JOIN public.tbl_benutzer ben ON ma.mitarbeiter_uid = ben.uid
WHERE person_id = prestudents.person_id
AND ben.aktiv
) THEN ' | Mitarbeiter' ELSE '' END)
FROM (
SELECT
DISTINCT person_id, prestudent_id, UPPER(stg.typ || stg.kurzbz) AS studiengang,
get_rolle_prestudent(ps.prestudent_id, null) AS last_status
FROM
public.tbl_prestudent ps
JOIN public.tbl_studiengang stg USING (studiengang_kz)
WHERE
person_id = pers.person_id
ORDER BY
prestudent_id DESC
) prestudents
WHERE
last_status IN ('Abgewiesener','Aufgenommener', 'Student', 'Incoming', 'Diplomand', 'Abbrecher', 'Unterbrecher', 'Absolvent')
GROUP BY
person_id
LIMIT 1;
) AS status
FROM
lehre.tbl_projektarbeit pa
JOIN campus.tbl_paabgabe paabg USING(projektarbeit_id)
JOIN campus.tbl_paabgabetyp abgabetyp USING(paabgabetyp_kurzbz)
LEFT JOIN public.tbl_benutzer ben ON(uid=student_uid)
LEFT JOIN public.tbl_person pers ON(ben.person_id=pers.person_id)
LEFT JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
LEFT JOIN public.tbl_studiengang stg USING(studiengang_kz)
WHERE
TRUE";
if (isset($projekttyp_kurzbz_arr) && !isEmptyArray($projekttyp_kurzbz_arr))
{
$qry .= " AND projekttyp_kurzbz IN ?";
$params[] = $projekttyp_kurzbz_arr;
}
if (isset($studiengang_kz) && is_numeric($studiengang_kz))
{
$qry .= " AND stg.studiengang_kz=?";
$params[] = $studiengang_kz;
}
if (isset($abgabetyp_kurzbz))
{
$qry .= " AND paabg.paabgabetyp_kurzbz=?";
$params[] = $abgabetyp_kurzbz;
}
if (isset($abgabedatum))
{
$qry .= " AND paabg.datum=?";
$params[] = $abgabedatum;
}
if (is_numeric($personSearchString))
{
$personSearchString = (int) $personSearchString;
$params = array_merge($params, [$personSearchString, $personSearchString]);
$qry .= " AND (
pers.person_id = ?
OR EXISTS (SELECT 1 FROM public.tbl_prestudent WHERE person_id = pers.person_id AND prestudent_id = ?)
)";
}
elseif (is_string($personSearchString))
{
// remove empty spaces and lowercase
$personSearchString = strtolower(str_replace(' ', '', $personSearchString));
$qry .= " AND (
LOWER(REPLACE(pers.nachname || pers.vorname || pers.nachname, ' ', '')) LIKE ".$this->db->escape('%'.$personSearchString.'%')."
OR ben.uid LIKE ".$this->db->escape('%'.$personSearchString.'%')."
)";
}
$qry .= " ORDER BY nachname";
if (isset($limit) && is_numeric($limit) && (!isset($studiengang_kz) || !is_numeric($studiengang_kz)) && !isset($abgabedatum))
{
$qry .= " LIMIT ?";
$params[] = $limit;
}
return $this->execReadOnlyQuery($qry, $params);
}
/**
* Gets due dates for projekt submission search criteria.
* @param array $projekttyp_kurzbz_arr contains all relevant project types (e.g. Bachelor)
* @param int $studiengang_kz study program
* @param string $abgabetyp_kurzbz project submission type (e.g. end upload, intermediate submission)
* @return object
*/
public function getTermine($projekttyp_kurzbz_arr, $studiengang_kz, $abgabetyp_kurzbz)
{
$params = [];
$qry = "
SELECT
DISTINCT tbl_paabgabe.datum as termin, to_char(tbl_paabgabe.datum, 'DD.MM.YYYY') as termin_anzeige
FROM
lehre.tbl_projektarbeit
JOIN campus.tbl_paabgabe USING(projektarbeit_id)
LEFT JOIN public.tbl_benutzer ON(uid=student_uid)
LEFT JOIN public.tbl_person ON(tbl_benutzer.person_id=tbl_person.person_id)
LEFT JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
LEFT JOIN public.tbl_studiengang USING(studiengang_kz)
WHERE
TRUE";
if (isset($projekttyp_kurzbz_arr) && !isEmptyArray($projekttyp_kurzbz_arr))
{
$qry .= " AND projekttyp_kurzbz IN ?";
$params[] = $projekttyp_kurzbz_arr;
}
if (isset($studiengang_kz) && is_numeric($studiengang_kz))
{
$qry .= " AND public.tbl_studiengang.studiengang_kz=?";
$params[] = $studiengang_kz;
}
if (isset($abgabetyp_kurzbz))
{
$qry .= " AND campus.tbl_paabgabe.paabgabetyp_kurzbz=?";
$params[] = $abgabetyp_kurzbz;
}
$qry .= " ORDER BY termin DESC";
return $this->execReadOnlyQuery($qry, $params);
}
public function findAbgabenNewOrUpdatedSince($interval, $relevantTypes)
{
@@ -233,13 +68,14 @@ class Paabgabe_model extends DB_Model
campus.tbl_paabgabe.insertvon, campus.tbl_paabgabe.insertamum, campus.tbl_paabgabe.updatevon, campus.tbl_paabgabe.updateamum,
campus.tbl_paabgabe.note, upload_allowed, beurteilungsnotiz, student_uid, tbl_projektarbeit.note, lehre.tbl_projektarbeit.titel,
UPPER(tbl_studiengang.typ) as stgtyp, UPPER(tbl_studiengang.kurzbz) as stgkz, public.tbl_studiengang.studiengang_kz,
public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_projektarbeit.studiensemester_kurzbz,
public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_lehreinheit.studiensemester_kurzbz,
public.tbl_person.anrede, public.tbl_person.titelpre, public.tbl_person.vorname, public.tbl_person.nachname, public.tbl_person.titelpost
FROM campus.tbl_paabgabe
JOIN campus.tbl_paabgabetyp USING (paabgabetyp_kurzbz)
JOIN lehre.tbl_projektarbeit USING (projektarbeit_id)
JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN public.tbl_studiengang ON(lehre.tbl_lehrveranstaltung.studiengang_kz = public.tbl_studiengang.studiengang_kz)
JOIN lehre.tbl_lehreinheit using(lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id)
JOIN public.tbl_studiengang on(lehre.tbl_lehrveranstaltung.studiengang_kz = public.tbl_studiengang.studiengang_kz)
JOIN public.tbl_benutzer ON (public.tbl_benutzer.uid = student_uid)
JOIN public.tbl_person USING (person_id)
@@ -257,7 +93,7 @@ class Paabgabe_model extends DB_Model
campus.tbl_paabgabe.insertvon, campus.tbl_paabgabe.insertamum, campus.tbl_paabgabe.updatevon, campus.tbl_paabgabe.updateamum,
campus.tbl_paabgabe.note, upload_allowed, beurteilungsnotiz, student_uid, tbl_projektarbeit.note, lehre.tbl_projektarbeit.titel,
UPPER(tbl_studiengang.typ) as stgtyp, UPPER(tbl_studiengang.kurzbz) as stgkz, public.tbl_studiengang.studiengang_kz,
public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_projektarbeit.studiensemester_kurzbz,
public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_lehreinheit.studiensemester_kurzbz,
lehre.tbl_projektbetreuer.betreuerart_kurzbz, lehre.tbl_projektbetreuer.person_id,
public.tbl_person.anrede, public.tbl_person.titelpre, public.tbl_person.vorname, public.tbl_person.nachname, public.tbl_person.titelpost
@@ -265,7 +101,8 @@ class Paabgabe_model extends DB_Model
JOIN campus.tbl_paabgabetyp USING (paabgabetyp_kurzbz)
JOIN lehre.tbl_projektarbeit USING (projektarbeit_id)
JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id)
JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN lehre.tbl_lehreinheit using(lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id)
JOIN public.tbl_studiengang on(lehre.tbl_lehrveranstaltung.studiengang_kz = public.tbl_studiengang.studiengang_kz)
JOIN public.tbl_benutzer ON (public.tbl_benutzer.uid = student_uid)
JOIN public.tbl_person ON (public.tbl_benutzer.person_id = public.tbl_person.person_id)
@@ -23,11 +23,9 @@ class Projektarbeit_model extends DB_Model
*/
public function getProjektarbeit($student_uid, $studiengang_kz = null, $studiensemester_kurzbz = null, $projekttyp = null, $final = null)
{
$sprache_index = "COALESCE((SELECT index FROM public.tbl_sprache WHERE sprache=" . $this->escape(getUserLanguage()) . " LIMIT 1), 1)";
$qry = "SELECT
pa.*, tbl_projekttyp.bezeichnung, tbl_lehrveranstaltung.lehrveranstaltung_id,
tbl_sprache.bezeichnung[".$sprache_index."] AS sprache_bezeichnung,
pa.studiensemester_kurzbz, pa.lehrveranstaltung_id,
pa.*, tbl_projekttyp.bezeichnung,
tbl_lehreinheit.studiensemester_kurzbz, tbl_lehrveranstaltung.lehrveranstaltung_id,
tbl_firma.name AS firma_name,
(
SELECT
@@ -43,9 +41,9 @@ class Projektarbeit_model extends DB_Model
FROM
lehre.tbl_projektarbeit pa
JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
LEFT JOIN public.tbl_firma USING (firma_id)
LEFT JOIN public.tbl_sprache ON pa.sprache = tbl_sprache.sprache
WHERE
pa.student_uid = ?";
@@ -59,7 +57,7 @@ class Projektarbeit_model extends DB_Model
if (isset($studiensemester_kurzbz))
{
$qry .= ' AND tbl_projektarbeit.studiensemester_kurzbz=?';
$qry .= ' AND tbl_lehreinheit.studiensemester_kurzbz=?';
$params[] = $studiensemester_kurzbz;
}
@@ -136,7 +134,7 @@ class Projektarbeit_model extends DB_Model
projektarbeit_id,
lehre.tbl_projekttyp.bezeichnung as projekttypbezeichnung,
lehre.tbl_projekttyp.projekttyp_kurzbz as projekttypkurzbz,
lehre.tbl_projektarbeit.studiensemester_kurzbz,
lehre.tbl_lehreinheit.studiensemester_kurzbz,
lehre.tbl_lehrveranstaltung.studiengang_kz,
public.tbl_studiengang.kurzbzlang,
lehre.tbl_projektarbeit.note as note,
@@ -159,6 +157,7 @@ class Projektarbeit_model extends DB_Model
LEFT JOIN public.tbl_benutzer USING(person_id)
LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
LEFT JOIN lehre.tbl_betreuerart USING(betreuerart_kurzbz)
LEFT JOIN lehre.tbl_lehreinheit USING(lehreinheit_id)
LEFT JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
LEFT JOIN public.tbl_mitarbeiter ON(public.tbl_mitarbeiter.mitarbeiter_uid = public.tbl_benutzer.uid)
LEFT JOIN public.tbl_studiengang USING(studiengang_kz)
@@ -367,7 +366,7 @@ class Projektarbeit_model extends DB_Model
tbl_studiengang.typ, tbl_studiengang.kurzbz,
tbl_projektarbeit.projekttyp_kurzbz, tbl_projekttyp.bezeichnung,
tbl_projektarbeit.titel, tbl_projektarbeit.projektarbeit_id, tbl_projektarbeit.note,
student_benutzer.uid, tbl_student.matrikelnr, tbl_projektarbeit.studiensemester_kurzbz, public.tbl_student.student_uid,
student_benutzer.uid, tbl_student.matrikelnr, tbl_lehreinheit.studiensemester_kurzbz, public.tbl_student.student_uid,
lehre.tbl_projektarbeit.sprache,
lehre.tbl_projektarbeit.seitenanzahl,
@@ -431,6 +430,7 @@ class Projektarbeit_model extends DB_Model
LEFT JOIN public.tbl_benutzer student_benutzer ON student_benutzer.uid = lehre.tbl_projektarbeit.student_uid
LEFT JOIN public.tbl_person student_person ON student_benutzer.person_id = student_person.person_id
LEFT JOIN public.tbl_student ON student_benutzer.uid = public.tbl_student.student_uid
LEFT JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
LEFT JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
LEFT JOIN public.tbl_studiengang ON public.tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
@@ -503,7 +503,7 @@ class Projektarbeit_model extends DB_Model
student_person.vorname AS student_vorname,
student_person.nachname AS student_nachname,
public.tbl_student.matrikelnr,
tbl_projektarbeit.studiensemester_kurzbz,
tbl_lehreinheit.studiensemester_kurzbz,
betreuer_benutzer.uid AS betreuer_benutzer_uid,
betreuer_person.titelpre AS betreuer_titelpre,
betreuer_person.vorname AS betreuer_vorname,
@@ -565,6 +565,7 @@ class Projektarbeit_model extends DB_Model
LEFT JOIN public.tbl_benutzer student_benutzer ON student_benutzer.uid = lehre.tbl_projektarbeit.student_uid
LEFT JOIN public.tbl_person student_person ON student_benutzer.person_id = student_person.person_id
LEFT JOIN public.tbl_student ON student_benutzer.uid = public.tbl_student.student_uid
LEFT JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
LEFT JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
LEFT JOIN public.tbl_studiengang ON public.tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
@@ -632,7 +633,7 @@ class Projektarbeit_model extends DB_Model
student_person.vorname AS student_vorname,
student_person.nachname AS student_nachname,
public.tbl_student.matrikelnr,
tbl_projektarbeit.studiensemester_kurzbz,
tbl_lehreinheit.studiensemester_kurzbz,
betreuer_benutzer.uid AS betreuer_benutzer_uid,
betreuer_person.titelpre AS betreuer_titelpre,
betreuer_person.vorname AS betreuer_vorname,
@@ -694,6 +695,7 @@ class Projektarbeit_model extends DB_Model
LEFT JOIN public.tbl_benutzer student_benutzer ON student_benutzer.uid = lehre.tbl_projektarbeit.student_uid
LEFT JOIN public.tbl_person student_person ON student_benutzer.person_id = student_person.person_id
LEFT JOIN public.tbl_student ON student_benutzer.uid = public.tbl_student.student_uid
LEFT JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
LEFT JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
LEFT JOIN public.tbl_studiengang ON public.tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
@@ -306,5 +306,4 @@ class Pruefung_model extends DB_Model
return $this->loadWhereCommitteeExamsFailed();
}
}
@@ -515,75 +515,4 @@ class Studierendenantrag_model extends DB_Model
return hasData($this->load());
}
/**
* Loads all todos for a certain studiengangsleiter
*
* @param integer $stg_kz
*
* @return stdClass
*/
public function getOpenAntraegeForStgl($stg_kz)
{
$qry = "
SELECT
studierendenantrag_id,
prestudent_id,
typ,
person.nachname,
person.vorname,
ps.studiengang_kz
FROM campus.tbl_studierendenantrag a
JOIN public.tbl_prestudent ps USING (prestudent_id)
JOIN public.tbl_person person USING (person_id)
WHERE studiengang_kz in ?
AND (
(typ IN ('Abmeldung', 'AbmeldungStgl', 'Unterbrechung')
AND campus.get_status_studierendenantrag(a.studierendenantrag_id) = 'Erstellt')
OR
(typ = 'Wiederholung'
AND campus.get_status_studierendenantrag(a.studierendenantrag_id) = 'Lvszugewiesen')
)
ORDER BY typ;
";
$params = array($stg_kz);
return $this->execQuery($qry, $params);
}
/**
* Lists all open antraege for a certain stg
*
* @param Array $stg_kz
*
* @return stdClass
*/
public function getOpenAntraegeForAss($stg_kz)
{
$qry = "
SELECT
UPPER(stg.typ) || UPPER(stg.kurzbz) || ' ' || stg.bezeichnung AS studiengang,
COUNT(*) AS anzahl
FROM campus.tbl_studierendenantrag
JOIN public.tbl_prestudent p USING (prestudent_id)
JOIN public.tbl_studiengang stg ON p.studiengang_kz=stg.studiengang_kz
JOIN campus.tbl_studierendenantrag_status as s ON campus.get_status_id_studierendenantrag(campus.tbl_studierendenantrag.studierendenantrag_id) = studierendenantrag_status_id
JOIN campus.tbl_studierendenantrag_statustyp as st USING (studierendenantrag_statustyp_kurzbz)
WHERE (
s.studierendenantrag_statustyp_kurzbz NOT IN('Zurueckgezogen', 'Genehmigt', 'Abgelehnt', 'EinspruchAbgelehnt', 'Abgemeldet', 'Pause', 'EmailVersandt')
OR (
s.studierendenantrag_statustyp_kurzbz = 'Genehmigt'
AND tbl_studierendenantrag.typ = 'AbmeldungStgl'
)
)
AND p.studiengang_kz IN ?
GROUP BY studiengang
ORDER BY studiengang
"
;
$params = array($stg_kz);
return $this->execQuery($qry, $params);
}
}
@@ -653,42 +653,31 @@ class Studiengang_model extends DB_Model
}
/**
* Gets the Studiengang information. Without parameters it uses the Studiengang
* of the logged in Student.
*
* @param int|null $studiengang_kz
* @param int|null $semester used for the Jahrgangsvertretung
* @return stdClass
*/
public function getStudiengangInfoForNews($studiengang_kz = null, $semester = null)
public function getStudiengangInfoForNews()
{
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('crm/Student_model', 'StudentModel');
if (is_null($studiengang_kz))
{
$student = $this->StudentModel->loadWhere(['student_uid' => getAuthUID()]);
if (isError($student))
return error($student);
if (getData($student)) {
$student = current(getData($student));
$studiengang_kz = $student->studiengang_kz;
$semester = $student->semester;
}
$student = $this->StudentModel->loadWhere(['student_uid' => getAuthUID()]);
if (isError($student))
return error($student);
if (getData($student)) {
$student = current(getData($student));
$studiengang_kz = $student->studiengang_kz;
$semester = $student->semester;
}
// users without a Student record get no information instead of an error
if (is_null($studiengang_kz))
return success(null);
$stg_obj = $this->load($studiengang_kz);
if(isError($stg_obj))
return error($stg_obj);
if(!hasData($stg_obj))
return error('Studiengang nicht gefunden');
$stg_obj = current(getData($stg_obj));
if(getData($stg_obj))
{
$stg_obj = current(getData($stg_obj));
}
$stg_ltg = $this->getLeitungDetailed($stg_obj->studiengang_kz);
if (isError($stg_ltg))
@@ -897,14 +886,6 @@ class Studiengang_model extends DB_Model
return success($ass);
}
public function getDegreePrograms() {
$query = "SELECT *
FROM public.tbl_studiengang
ORDER BY public.tbl_studiengang.kurzbzlang";
return $this->execReadOnlyQuery($query);
}
private function addEmailProperty(&$benutzerfunktionen) {
if(count($benutzerfunktionen) && defined('DOMAIN'))
{
@@ -59,37 +59,6 @@ class Studienplan_model extends DB_Model
'tbl_studienplan_lehrveranstaltung.semester' => $semester
));
}
public function getStudienplanByLvaSemKurzbz($lehrveranstaltung_id, $studiensemester_kurzbz) {
$qry= "
SELECT
DISTINCT tbl_studienplan.*
FROM
lehre.tbl_studienplan
JOIN lehre.tbl_studienplan_lehrveranstaltung
USING(studienplan_id)
WHERE
tbl_studienplan_lehrveranstaltung.lehrveranstaltung_id IN (
SELECT
lv.lehrveranstaltung_id
FROM
lehre.tbl_lehrveranstaltung AS lv
LEFT JOIN lehre.tbl_lehrveranstaltung AS t ON t.lehrveranstaltung_id=lv.lehrveranstaltung_template_id
WHERE
lv.lehrtyp_kurzbz<>'tpl'
AND (lv.lehrveranstaltung_id= ? OR (lv.lehrveranstaltung_template_id= ? AND t.lehrtyp_kurzbz='tpl'))
)
AND EXISTS (
SELECT 1
FROM
lehre.tbl_studienplan_semester
WHERE studienplan_id=tbl_studienplan.studienplan_id
AND studiensemester_kurzbz= ?
AND semester = tbl_studienplan_lehrveranstaltung.semester)
ORDER BY bezeichnung";
return $this->execReadOnlyQuery($qry, array($lehrveranstaltung_id, $lehrveranstaltung_id, $studiensemester_kurzbz));
}
public function getStudienplanLehrveranstaltungForPrestudent($studienplan_id, $semester, $prestudent_id)
{
@@ -218,7 +218,7 @@ class Studiensemester_model extends DB_Model
*/
public function getByDate($date)
{
// gets the studiensemester of a date or the next closest previous studiensemester if a date is not within a studiensemester
// gets the studiensemster of a date or the next closest previous studiensemester if a date is not within a studiensemester
$query = "
SELECT studiensemester_kurzbz, start, ende
FROM public.tbl_studiensemester
@@ -292,29 +292,13 @@ class Studiensemester_model extends DB_Model
COALESCE(
(SELECT studiensemester_kurzbz FROM semester_interval_startdate),
(SELECT studiensemester_kurzbz FROM nearest_semester_interval_startdate)
) AS studiensemester_kurzbz,
COALESCE(
(SELECT start FROM semester_interval_startdate),
(SELECT start FROM nearest_semester_interval_startdate)
) as start,
COALESCE(
(SELECT ende FROM semester_interval_startdate),
(SELECT ende FROM nearest_semester_interval_startdate)
) as ende
) AS studiensemester_kurzbz
UNION
SELECT
COALESCE(
(SELECT studiensemester_kurzbz FROM semester_interval_enddate),
(SELECT studiensemester_kurzbz FROM nearest_semester_interval_enddate)
) AS studiensemester_kurzbz,
COALESCE(
(SELECT start FROM semester_interval_enddate),
(SELECT start FROM nearest_semester_interval_enddate)
) as start,
COALESCE(
(SELECT ende FROM semester_interval_enddate),
(SELECT ende FROM nearest_semester_interval_enddate)
) as ende
) AS studiensemester_kurzbz
EOSQL;
@@ -375,30 +359,6 @@ EOSQL;
return $this->loadWhere(['uid' => $student_uid, 'v.lehre' => true]);
}
public function getWhereMitarbeiterHasLvs($uid) {
// first order by year with last 2 letter from right,
// then order by WS/SS inside the years
// query it asc so the ordering magic in cis4 turns it around again
$qry = "WITH unique_semesters AS (
SELECT DISTINCT ON (studiensemester_kurzbz)
studiensemester_kurzbz,
start,
ende,
bezeichnung,
studienjahr_kurzbz
FROM lehre.tbl_lehreinheit
JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id)
JOIN public.tbl_studiensemester USING(studiensemester_kurzbz)
WHERE mitarbeiter_uid = ?
)
SELECT * FROM unique_semesters
ORDER BY
RIGHT(studiensemester_kurzbz, 2) ASC,
LEFT(studiensemester_kurzbz, 2) ASC;";
return $this->execReadOnlyQuery($qry, [$uid]);
}
public function getAktAndFutureSemester()
{
$query = 'SELECT studiensemester_kurzbz
@@ -319,40 +319,6 @@ class Benutzerfunktion_model extends DB_Model
return $record;
}
/**
* Get active Assistenz(en) of the user by UID.
* @param $uid
*/
public function getSTGAssByUID($uid)
{
$query = '
SELECT
uid,
oe_kurzbz,
studiengang_kz,
typ,
tbl_studiengang.bezeichnung
FROM
public.tbl_benutzerfunktion
JOIN public.tbl_studiengang USING (oe_kurzbz)
WHERE
funktion_kurzbz = \'ass\'
AND (datum_von IS NULL OR datum_von <= now())
AND (datum_bis IS NULL OR datum_bis >= now())
AND uid = ?
ORDER BY
oe_kurzbz
';
$parameters_array = array();
if (is_string($uid))
{
$parameters_array[] = $uid;
}
return $this->execQuery($query, $parameters_array);
}
function updateBenutzerfunktion($funktionJson)
{
$funktionJson['updatevon'] = getAuthUID();
@@ -11,4 +11,14 @@ class Freebusytyp_model extends DB_Model
$this->dbTable = 'campus.tbl_freebusytyp';
$this->pk = 'freebusytyp_kurzbz';
}
public function getAllFreeBusyTypes()
{
return $this->execReadOnlyQuery("SELECT * FROM " . $this->dbTable);
}
public function getActiveFreeBusyTypes()
{
return $this->execReadOnlyQuery("SELECT * FROM " . $this->dbTable . " WHERE is_active");
}
}
+3 -10
View File
@@ -98,7 +98,7 @@ class Notiz_model extends DB_Model
/**
* Add a Notiz for a given person
*/
public function addNotizForPerson($person_id, $titel, $text, $erledigt, $verfasser_uid, $insertvon = null)
public function addNotizForPerson($person_id, $titel, $text, $erledigt, $verfasser_uid)
{
// Loads model Notizzuordnung_model
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
@@ -106,15 +106,8 @@ class Notiz_model extends DB_Model
// Start DB transaction
$this->db->trans_start(false);
$result = $this->insert(
array(
'titel' => $titel,
'text' => $text,
'erledigt' => $erledigt,
'verfasser_uid' => $verfasser_uid,
'insertvon' => $insertvon ?? $verfasser_uid
)
);
$result = $this->insert(array('titel' => $titel, 'text' => $text, 'erledigt' => $erledigt, 'verfasser_uid' => $verfasser_uid,
"insertvon" => $verfasser_uid));
if (isSuccess($result))
{
@@ -0,0 +1,151 @@
<?php
class CoodleSurveyExternalParticipant_model extends DB_Model
{
private $_ci; // Code igniter instance
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'campus.tbl_coodle_survey_external_participants';
$this->pk = 'id';
$this->_ci =& get_instance();
}
public function getExternalParticipants($surveyId, $includeAccessKeys = false)
{
$selectedColumns = $includeAccessKeys ? "*" : "id, survey_id, name, email, selection";
$query = "SELECT $selectedColumns
FROM $this->dbTable
WHERE survey_id = $surveyId
";
return $this->execQuery($query);
}
public function getExternalParticipant($externalParticipantId, $includeAccessKey = false)
{
$selectedColumns = $includeAccessKey ? "*" : "id, survey_id, name, email, selection";
$query = "SELECT *
FROM $this->dbTable
WHERE id = $externalParticipantId
LIMIT 1
";
return $this->execQuery($query);
}
public function getExternalParticipantByAccessKey($surveyId, $accessKey)
{
$query = "SELECT *
FROM $this->dbTable
WHERE survey_id = $surveyId AND access_key = '$accessKey'
LIMIT 1
";
return $this->execQuery($query);
}
public function updateExternalParticipants($surveyId, $externalParticipants, $timeslots)
{
$participantsQuery = "SELECT *
FROM $this->dbTable
WHERE survey_id = $surveyId
";
$oldExternalParticipants = getData($this->execQuery($participantsQuery));
$oldExternalParticipantIds = array_map(
function ($oldExternalParticipant) {
return $oldExternalParticipant->id;
},
$oldExternalParticipants
);
$persistingExternalParticipants = array_filter(
$externalParticipants,
function ($externalParticipant) {
return isset($externalParticipant["id"]) && $externalParticipant["id"];
}
);
$persistingExternalParticipantIds = array_map(
function ($persistingExternalParticipant) {
return $persistingExternalParticipant["id"];
},
$persistingExternalParticipants
);
$redundantExternalParticipantIds = array_diff(
$oldExternalParticipantIds,
$persistingExternalParticipantIds
);
$newExternalParticipants = array_filter(
$externalParticipants,
function ($externalParticipant) {
return !isset($externalParticipant["id"]) || !$externalParticipant["id"];
}
);
if (count($redundantExternalParticipantIds)) {
$idsToBeDeleted = "(" . implode(", ", $redundantExternalParticipantIds) . ")";
$deleteQuery = "DELETE FROM $this->dbTable WHERE id IN $idsToBeDeleted";
$this->execQuery($deleteQuery);
}
if (count($newExternalParticipants)) {
$insertValues = array_map(
function ($newExternalParticipant) use ($surveyId) {
$name = $newExternalParticipant["name"];
$email = $newExternalParticipant["email"];
$accessKey = uniqid();
return "($surveyId, '$name', '$email', '$accessKey', NULL)";
},
$newExternalParticipants
);
$insertValues = implode(", ", $insertValues);
$insertQuery = "INSERT INTO $this->dbTable (survey_id, name, email, access_key, selection) VALUES $insertValues";
$this->execQuery($insertQuery);
}
$updatedExternalParticipants = getData($this->execQuery($participantsQuery));
$timeslotIds = array_map(
function ($timeslot) {
return $timeslot->id;
},
$timeslots
);
foreach ($updatedExternalParticipants as $externalParticipant) {
if (!$externalParticipant->selection)
continue;
$selection = json_decode($externalParticipant->selection, true);
if (!count($selection))
continue;
$obsoleteSelectedTimeslotIds = array_diff($selection, $timeslotIds);
if (!count($obsoleteSelectedTimeslotIds))
continue;
$updatedSelection = null;
if (count($obsoleteSelectedTimeslotIds) !== count($selection)) {
$updatedSelection = array_filter(
$selection,
function ($timeslotId) use ($obsoleteSelectedTimeslotIds) {
return !in_array($timeslotId, $obsoleteSelectedTimeslotIds);
}
);
}
$this->updateSelection($externalParticipant->id, $updatedSelection);
}
}
public function updateSelection($externalParticipantId, $selection)
{
$selection = $selection !== null ? "'" . json_encode($selection) . "'" : "NULL";
$selectionUpdateQuery = "UPDATE $this->dbTable SET selection = $selection WHERE id = $externalParticipantId";
$this->execQuery($selectionUpdateQuery);
}
}
@@ -0,0 +1,137 @@
<?php
class CoodleSurveyParticipant_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'campus.tbl_coodle_survey_participants';
}
public function getParticipants($surveyId)
{
$query = "
SELECT
surveyParticipant.participant_uid as uid,
surveyParticipant.selection as selection,
person.vorname || ' ' || person.nachname AS name
FROM $this->dbTable surveyParticipant
JOIN public.tbl_benutzer benutzer ON(benutzer.uid = surveyParticipant.participant_uid)
JOIN public.tbl_person person ON(person.person_id = benutzer.person_id)
WHERE survey_id = $surveyId
";
return $this->execQuery($query);
}
public function getParticipantEntriesByUid($uid)
{
$query = "SELECT * FROM $this->dbTable WHERE participant_uid = '$uid'";
return $this->execQuery($query);
}
public function getActiveParticipantEntriesByUid($uid)
{
$query = "SELECT
surveyParticipant.survey_id as survey_id,
surveyParticipant.participant_uid as participant_uid,
surveyParticipant.selection as selection
FROM $this->dbTable surveyParticipant
JOIN campus.tbl_coodle_surveys survey ON(survey.id = surveyParticipant.survey_id)
WHERE surveyParticipant.participant_uid = '$uid'
AND survey.completed_at IS NULL
AND survey.canceled_at IS NULL";
return $this->execQuery($query);
}
public function updateParticipants($surveyId, $participants, $timeslots)
{
$participantUids = array_map(function ($participant) {
return $participant["uid"];
}, $participants);
$existingParticipantsQuery = "SELECT * FROM " . $this->dbTable . " WHERE survey_id = " . $surveyId;
$existingParticipants = getData($this->execQuery($existingParticipantsQuery));
$existingParticipantUids = array_map(
function ($existingParticipant) {
return $existingParticipant->participant_uid;
},
$existingParticipants
);
$newParticipantUids = array_filter(
$participantUids,
function ($participantUid) use ($existingParticipantUids) {
return !in_array($participantUid, $existingParticipantUids);
}
);
$redundantParticipantUids = array_filter(
$existingParticipantUids,
function ($existingParticipantUid) use ($participantUids) {
return !in_array($existingParticipantUid, $participantUids);
}
);
if (count($newParticipantUids)) {
$insertQuery = "INSERT INTO $this->dbTable VALUES ";
$newParticipantInsertValues = array_map(
function ($newParticipantUid) use ($surveyId) {
return "('$surveyId', '$newParticipantUid', NULL)";
},
$newParticipantUids
);
$newParticipantInsertValues = implode(", ", $newParticipantInsertValues);
$insertQuery .= $newParticipantInsertValues;
$insertQuery .= ";";
$this->execQuery($insertQuery);
}
if (count($redundantParticipantUids)) {
$deleteQuery = "DELETE FROM $this->dbTable WHERE survey_id = $surveyId AND participant_uid IN ('" . implode("', '", $redundantParticipantUids) . "');";
$this->execQuery($deleteQuery);
}
$timeslotIds = array_map(
function ($timeslot) {
return $timeslot->id;
},
$timeslots
);
$updatedExistingParticipants = getData($this->execQuery($existingParticipantsQuery));
foreach ($updatedExistingParticipants as $participant) {
if (!$participant->selection)
continue;
$selection = json_decode($participant->selection, true);
if (!count($selection))
continue;
$obsoleteSelectedTimeslotIds = array_diff($selection, $timeslotIds);
if (!count($obsoleteSelectedTimeslotIds))
continue;
$updatedSelection = null;
if (count($obsoleteSelectedTimeslotIds) !== count($selection)) {
$updatedSelection = array_filter(
$selection,
function ($timeslotId) use ($obsoleteSelectedTimeslotIds) {
return !in_array($timeslotId, $obsoleteSelectedTimeslotIds);
}
);
}
$this->updateSelection($surveyId, $participant->participant_uid, $updatedSelection);
}
}
public function updateSelection($surveyId, $participantUid, $selection)
{
$selection = $selection !== null ? "'" . json_encode($selection) . "'" : "NULL";
$selectionUpdateQuery = "UPDATE $this->dbTable SET selection = $selection WHERE survey_id = $surveyId AND participant_uid = '$participantUid'";
$this->execQuery($selectionUpdateQuery);
}
}
@@ -0,0 +1,100 @@
<?php
class CoodleSurveyTimeslot_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'campus.tbl_coodle_survey_timeslots';
$this->pk = 'id';
}
public function getTimeslots($surveyId)
{
$query = "SELECT id, starts_at
FROM $this->dbTable
WHERE survey_id = $surveyId
";
return $this->execQuery($query);
}
public function getTimeslotsForMultipleSurveys($surveyIds)
{
if (!count($surveyIds)) return [];
$surveyIds = "(" . implode(", ", $surveyIds) . ")";
$query = "SELECT *
FROM $this->dbTable
WHERE survey_id IN $surveyIds
";
return $this->execQuery($query);
}
public function getTimeslot($timeslotId)
{
$query = "SELECT *
FROM $this->dbTable
WHERE id = $timeslotId
LIMIT 1
";
return $this->execQuery($query);
}
public function updateTimeslots($surveyId, $timeslots)
{
$newTimeslots = array_filter(
$timeslots,
function ($timeslot) {
return !$timeslot["id"];
}
);
$persistedTimeslots = array_filter(
$timeslots,
function ($timeslot) {
return $timeslot["id"];
}
);
$persistedTimeslotIds = array_map(
function ($persistedTimeslot) {
return $persistedTimeslot["id"];
},
$persistedTimeslots
);
$existingTimeslotsQuery = "SELECT id, starts_at
FROM $this->dbTable
WHERE survey_id = $surveyId
";
$existingTimeslots = getData($this->execQuery($existingTimeslotsQuery));
$existingTimeslotIds = array_map(
function ($existingTimeslot) {
return $existingTimeslot->id;
},
$existingTimeslots
);
$obsoleteTimeslotIds = array_diff($existingTimeslotIds, $persistedTimeslotIds);
if (count($obsoleteTimeslotIds)) {
$deleteQuery = "DELETE FROM $this->dbTable WHERE id IN ('" . implode("', '", $obsoleteTimeslotIds) . "');";
$this->execQuery($deleteQuery);
}
if (count($newTimeslots)) {
$insertQuery = "INSERT INTO $this->dbTable (survey_id, starts_at) VALUES ";
$newTimeslotInsertValues = array_map(
function ($newTimeslot) use ($surveyId) {
return "('$surveyId', '" . $newTimeslot["startsAt"] . "')";
},
$newTimeslots
);
$newTimeslotInsertValues = implode(", ", $newTimeslotInsertValues);
$insertQuery .= $newTimeslotInsertValues;
$insertQuery .= ";";
$this->execQuery($insertQuery);
}
}
}
@@ -0,0 +1,164 @@
<?php
class CoodleSurvey_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'campus.tbl_coodle_surveys';
$this->pk = 'id';
$this->load->model('ressource/CoodleSurveyParticipant_model', 'CoodleSurveyParticipantModel');
}
public function getSurvey($surveyId)
{
$query = "SELECT *
FROM $this->dbTable
WHERE id = $surveyId
LIMIT 1
";
return $this->execQuery($query);
}
public function getSurveys($surveyIds)
{
if (!count($surveyIds)) return [];
$surveyIds = "(" . implode(", ", $surveyIds) . ")";
$query = "SELECT *
FROM $this->dbTable
WHERE id IN $surveyIds
";
return $this->execQuery($query);
}
public function getActiveSurveys($uid)
{
$userParticipantEntries = getData($this->CoodleSurveyParticipantModel->getParticipantEntriesByUid($uid));
$surveyIdsWhereUserIsParticipant = array_map(
function ($userParticipantEntry) {
return $userParticipantEntry->survey_id;
},
$userParticipantEntries
);
$surveyIdsWhereUserIsParticipantValue = implode(", ", $surveyIdsWhereUserIsParticipant);
$query = "SELECT
survey.id as id,
survey.creator_uid as creator_uid,
survey.title as title,
survey.ends_at as ends_at,
survey.created_at as created_at,
person.vorname || ' ' || person.nachname AS creator_name
FROM $this->dbTable as survey
JOIN public.tbl_benutzer benutzer ON(benutzer.uid = survey.creator_uid)
JOIN public.tbl_person person ON(person.person_id = benutzer.person_id)
WHERE (";
if (strlen($surveyIdsWhereUserIsParticipantValue)) {
$query .= "id IN ($surveyIdsWhereUserIsParticipantValue) OR ";
}
$query .= "creator_uid = '$uid')
AND completed_at IS NULL
AND canceled_at IS NULL";
return $this->execQuery($query);
}
public function getInactiveSurveys($uid)
{
$userParticipantEntries = getData($this->CoodleSurveyParticipantModel->getParticipantEntriesByUid($uid));
$surveyIdsWhereUserIsParticipant = array_map(
function ($userParticipantEntry) {
return $userParticipantEntry->survey_id;
},
$userParticipantEntries
);
$surveyIdsWhereUserIsParticipantValue = implode(", ", $surveyIdsWhereUserIsParticipant);
$query = "SELECT
survey.id as id,
survey.creator_uid as creator_uid,
survey.title as title,
survey.created_at as created_at,
survey.completed_at as completed_at,
survey.canceled_at as canceled_at,
person.vorname || ' ' || person.nachname AS creator_name
FROM $this->dbTable as survey
JOIN public.tbl_benutzer benutzer ON(benutzer.uid = survey.creator_uid)
JOIN public.tbl_person person ON(person.person_id = benutzer.person_id)
WHERE (";
if (strlen($surveyIdsWhereUserIsParticipantValue)) {
$query .= "id IN ($surveyIdsWhereUserIsParticipantValue) OR ";
}
$query .= "creator_uid = '$uid')
AND (completed_at IS NOT NULL OR canceled_at IS NOT NULL)";
return $this->execQuery($query);
}
public function createSurvey($surveyData, $creatorUid)
{
$surveyCreationResult = $this->insert([
"creator_uid" => $creatorUid,
"title" => $surveyData["title"],
"description" => $surveyData["description"] ?? "",
"timeslot_duration" => $surveyData["timeslotDuration"],
"are_selections_anonymized" => !!$surveyData["areSelectionsAnonymized"],
"are_participants_anonymized" => !!$surveyData["areParticipantsAnonymized"],
"max_selections" => $surveyData["maxSelections"] ?? 1,
"selected_timeslot_id" => null,
"ends_at" => $surveyData["endsAt"],
"completed_at" => null,
"canceled_at" => null,
"created_at" => "NOW()",
"updated_at" => "NOW()",
]);
if (isError($surveyCreationResult)) {
return error('Something went wrong during survey creation!');
}
return $surveyCreationResult;
}
public function updateSurvey($surveyId, $surveyData)
{
$surveyUpdateResult = $this->update($surveyId, [
"title" => $surveyData["title"],
"description" => $surveyData["description"],
"timeslot_duration" => $surveyData["timeslotDuration"],
"are_selections_anonymized" => $surveyData["areSelectionsAnonymized"],
"are_participants_anonymized" => $surveyData["areParticipantsAnonymized"],
"max_selections" => $surveyData["maxSelections"],
"ends_at" => $surveyData["endsAt"],
"updated_at" => "NOW()",
]);
if (isError($surveyUpdateResult)) {
return error('Something went wrong during survey update!');
}
return $surveyUpdateResult;
}
public function cancelSurvey($surveyId)
{
$this->update($surveyId, [
"canceled_at" => "NOW()",
"updated_at" => "NOW()",
]);
}
public function completeSurvey($surveyId, $timeslotId)
{
$this->update($surveyId, [
"selected_timeslot_id" => $timeslotId,
"completed_at" => "NOW()",
"updated_at" => "NOW()",
]);
}
}
@@ -12,12 +12,6 @@ class Ort_model extends DB_Model
$this->pk = "ort_kurzbz";
}
public function getRoomInfo($ortKurzbz)
{
$this->addSelect("ort_kurzbz, ausstattung");
return $this->OrtModel->loadWhere(array("ort_kurzbz" => $ortKurzbz));
}
public function getAll($raumtyp_kurzbz)
{
$this->addOrder("ort_kurzbz");
@@ -24,7 +24,7 @@ class Reservierung_model extends DB_Model
$lvplan_reservierungen_query = "SELECT r.* , stund.beginn, stund.ende,
CASE
WHEN r.gruppe_kurzbz IS NOT NULL THEN r.gruppe_kurzbz
ELSE CONCAT(UPPER(studg.typ),UPPER(studg.kurzbz),'-',COALESCE(CAST(r.semester AS varchar),'/'),COALESCE(CAST(r.verband AS varchar),'/'),COALESCE(CAST(r.gruppe AS varchar),'/'))
ELSE CONCAT(UPPER(studg.typ),UPPER(studg.kurzbz),'-',COALESCE(CAST(r.semester AS varchar),'/'),COALESCE(CAST(r.verband AS varchar),'/'))
END as gruppen_kuerzel
FROM campus.vw_reservierung r
JOIN public.tbl_studiengang studg ON studg.studiengang_kz=r.studiengang_kz
@@ -39,7 +39,7 @@ class Reservierung_model extends DB_Model
$raum_reservierungen_query = "SELECT res.*, beginn, ende,
CASE
WHEN res.gruppe_kurzbz IS NOT NULL THEN res.gruppe_kurzbz
ELSE CONCAT(UPPER(studg.typ),UPPER(studg.kurzbz),'-',COALESCE(CAST(res.semester AS varchar),'/'),COALESCE(CAST(res.verband AS varchar),'/'),COALESCE(CAST(res.gruppe AS varchar),'/'))
ELSE CONCAT(UPPER(studg.typ),UPPER(studg.kurzbz),'-',COALESCE(CAST(res.semester AS varchar),'/'),COALESCE(CAST(res.verband AS varchar),'/'))
END as gruppen_kuerzel
FROM campus.vw_reservierung res
JOIN public.tbl_studiengang studg ON studg.studiengang_kz=res.studiengang_kz
@@ -50,12 +50,11 @@ class Reservierung_model extends DB_Model
$query_result = $this->execReadOnlyQuery("
SELECT
DISTINCT(insertvon),
'reservierung' as type, beginn, ende, datum, array_agg(DISTINCT reservierung_id) AS reservierung_id,
'reservierung' as type, beginn, ende, datum,
COALESCE(titel, beschreibung) as topic,
array_agg(DISTINCT mitarbeiter_kurzbz) as lektor,
array_agg(DISTINCT (gruppe,verband,semester,studiengang_kz,gruppen_kuerzel)) as gruppe,
array_agg(DISTINCT(uid)) as uids,
ort_kurzbz, 'FFFFFF' as farbe
FROM
@@ -63,7 +62,7 @@ class Reservierung_model extends DB_Model
" . $subquery . "
) AS subquery
GROUP BY datum, beginn, ende, ort_kurzbz, titel, beschreibung, insertvon
GROUP BY datum, beginn, ende, ort_kurzbz, titel, beschreibung
ORDER BY datum, beginn
", is_null($ort_kurzbz) ? [$uid ?? getAuthUID(), $uid ?? getAuthUID(), $start_date, $end_date] : [$ort_kurzbz, $start_date, $end_date]);
@@ -83,7 +82,7 @@ class Reservierung_model extends DB_Model
$raum_reservierungen_query = "SELECT res.*, beginn, ende,
CASE
WHEN res.gruppe_kurzbz IS NOT NULL THEN res.gruppe_kurzbz
ELSE CONCAT(UPPER(studg.typ),UPPER(studg.kurzbz),'-',COALESCE(CAST(res.semester AS varchar),'/'),COALESCE(CAST(res.verband AS varchar),'/'),COALESCE(CAST(res.gruppe AS varchar),'/'))
ELSE CONCAT(UPPER(studg.typ),UPPER(studg.kurzbz),'-',COALESCE(CAST(res.semester AS varchar),'/'),COALESCE(CAST(res.verband AS varchar),'/'))
END as gruppen_kuerzel
FROM campus.vw_reservierung res
JOIN public.tbl_studiengang studg ON studg.studiengang_kz=res.studiengang_kz
@@ -95,12 +94,11 @@ class Reservierung_model extends DB_Model
$query_result = $this->execReadOnlyQuery("
SELECT
DISTINCT(insertvon),
'reservierung' as type, beginn, ende, datum, array_agg(DISTINCT reservierung_id) AS reservierung_id,
'reservierung' as type, beginn, ende, datum,
COALESCE(titel, beschreibung) as topic,
array_agg(DISTINCT mitarbeiter_kurzbz) as lektor,
array_agg(DISTINCT (gruppe,verband,semester,studiengang_kz,gruppen_kuerzel)) as gruppe,
array_agg(DISTINCT(uid)) as uids,
ort_kurzbz, 'FFFFFF' as farbe
FROM
@@ -108,7 +106,7 @@ class Reservierung_model extends DB_Model
" . $subquery . "
) AS subquery
GROUP BY datum, beginn, ende, ort_kurzbz, titel, beschreibung, insertvon
GROUP BY datum, beginn, ende, ort_kurzbz, titel, beschreibung
ORDER BY datum, beginn
", [$uid ?? getAuthUID(), $start_date, $end_date]);
@@ -148,40 +146,4 @@ class Reservierung_model extends DB_Model
return $this->execReadOnlyQuery($qry, [$uid, $datum, $stunde]);
}
public function deleteReservation($reservierung_id) {
$uid = getAuthUID();
$result = $this->load($reservierung_id);
if (isError($result))
return $result;
if (!hasData($result))
return error('Reservierung nicht gefunden');
$row = $result->retval[0];
if ($row->uid !== $uid && $row->insertvon !== $uid)
return error('Keine Berechtigung');
return $this->delete($reservierung_id);
}
public function getMyReservation() {
$uid = getAuthUID();
$date = date("Y-m-d",time());
$qry = "SELECT vw_reservierung.*,
trim(COALESCE(vw_mitarbeiter.titelpre,'')||' '||COALESCE(vw_mitarbeiter.vorname,'')||' '||COALESCE(vw_mitarbeiter.nachname,'')||' '||COALESCE(vw_mitarbeiter.titelpost,'')) as reserviert_fuer,
trim(COALESCE(reserviert_von.titelpre,'')||' '||COALESCE(reserviert_von.vorname,'')||' '||COALESCE(reserviert_von.nachname,'')||' '||COALESCE(reserviert_von.titelpost,'')) as reserviert_von
FROM campus.vw_reservierung
JOIN campus.vw_mitarbeiter ON vw_reservierung.uid=vw_mitarbeiter.uid
LEFT JOIN campus.vw_mitarbeiter reserviert_von ON vw_reservierung.insertvon=reserviert_von.uid
WHERE datum >= ?
AND (vw_reservierung.uid= ? OR vw_reservierung.insertvon= ? )
ORDER BY datum, titel, ort_kurzbz, stunde";
return $this->execReadOnlyQuery($qry, [$date, $uid, $uid]);
}
}
+22 -281
View File
@@ -12,7 +12,11 @@ class Zeitsperre_model extends DB_Model
$this->pk = 'zeitsperre_id';
}
const BLOCKIERENDE_ZEITSPERREN = ['Krank','Urlaub','ZA','DienstV','PflegeU','DienstF','CovidSB','CovidKS'];
public function getZeitsperre($uid)
{
$query = "SELECT * from campus.tbl_zeitsperre WHERE mitarbeiter_uid = '$uid'";
return $this->execQuery($query);
}
/**
* Save or update Zeitsperre.
@@ -64,270 +68,6 @@ class Zeitsperre_model extends DB_Model
return $this->execQuery($qry);
}
/**
* get Zeitsperren of a user
*
* @param $uid mitarbeiteruid
* @param $bisgrenze @true show only entries of actual business year (1.9.- 31.8.)
*
* @return array
*/
public function getZeitsperrenUser($uid, $bisgrenze = true)
{
$qry = "
SELECT
tbl_zeitsperre.*, tbl_zeitsperretyp.*, tbl_erreichbarkeit.farbe AS erreichbarkeit_farbe,
tbl_erreichbarkeit.beschreibung AS erreichbarkeit_beschreibung,
CONCAT (ps.vorname, ' ', ps.nachname) as vertretung
FROM (campus.tbl_zeitsperre JOIN campus.tbl_zeitsperretyp USING (zeitsperretyp_kurzbz))
LEFT JOIN campus.tbl_erreichbarkeit USING (erreichbarkeit_kurzbz)
LEFT JOIN public.tbl_benutzer ON campus.tbl_zeitsperre.vertretung_uid = public.tbl_benutzer.uid
LEFT JOIN public.tbl_person ps USING (person_id)
WHERE mitarbeiter_uid= ?
";
if($bisgrenze)
{
$qry.="
AND (
(date_part('month',vondatum)>=9 AND date_part('year', vondatum)>='".(date('Y')-1)."')
OR
(date_part('month',vondatum)<9 AND date_part('year', vondatum)>='".(date('Y'))."')
)";
}
$qry.= " ORDER BY vondatum DESC";
return $this->execQuery($qry, array('mitarbeiter_uid' => $uid));
}
/**
* check a date for existing zeitsperre
*
* @param $uid mitarbeiteruid
* @param $datum datum to check
* @param $stunde stunde (default = null)
* @param bool $nurblockierend if only hr relevante zeitsperren have to be checked
*
* @return array
*/
public function getSperreByDate($uid, $datum, $stunde = null, $nurblockierend = false)
{
$parametersArray = [$datum, $datum];
$qry = "
SELECT
*
FROM
campus.tbl_zeitsperre
WHERE
vondatum <= ?
AND bisdatum>= ?";
if($nurblockierend)
{
$qry .= " AND zeitsperretyp_kurzbz IN ('"
. implode("','", self::BLOCKIERENDE_ZEITSPERREN)
. "')";
}
if(!is_null($stunde))
{
$parametersArray = array_merge(
$parametersArray,
[$datum, $stunde, $datum, $datum, $stunde, $datum]
);
$qry.=" AND
((vondatum= ? AND vonstunde<= ? OR vonstunde is null OR vondatum<> ?) AND
(bisdatum= ? AND bisstunde>= ? OR bisstunde is null OR bisdatum<> ?))";
}
array_push($parametersArray, $uid);
$qry .= "AND mitarbeiter_uid= ? ";
return $this->execQuery($qry, $parametersArray);
}
/**
* check a date for existing zeitsperre
*
* @param $uid mitarbeiteruid
* @param $vondatum datum in Format IS0
* @param $bisdatum datum in Format ISO
*
* @return array
*/
public function existsZeitaufzeichnung($uid, $vonDay, $bisDay)
{
try {
$from = new DateTime($vonDay);
$to = new DateTime($bisDay);
} catch (Exception $e) {
throw new Exception("Invalid date format");
}
//remove hour stamps
$from->setTime(0, 0, 0);
$to->setTime(0, 0, 0)->modify('+1 day');
$fromSql = $from->format('Y-m-d');
$toSql = $to->format('Y-m-d');
$params = [$uid, $fromSql, $toSql];
$qry = "
SELECT *
FROM campus.tbl_zeitaufzeichnung
WHERE uid = ?
AND start >= ?
AND ende < ? ";
$result = $this->execQuery($qry, $params);
return $result;
}
/**
* getZeitsperren of Mitarbeiter for the next days
* @ days: count of the intervall of the next days
* @return array
*/
public function getZeitsperrenForNextDays($days, $uid=null)
{
$von = date('Y-m-d');
$bis = date('Y-m-d', strtotime("+{$days} days"));
$paramsArray = [$von, $bis, $bis, $von];
if($uid)
$paramsArray[] = $uid;
$qry = "select
nachname,
vorname,
uid,
vondatum,
bisdatum,
vertretung_uid,
erreichbarkeit_kurzbz,
mv.kurzbz
from
campus.vw_mitarbeiter
join campus.tbl_zeitsperre on
(uid = mitarbeiter_uid)
left join public.tbl_mitarbeiter mv on campus.tbl_zeitsperre.vertretung_uid = mv.mitarbeiter_uid
where
((? <= bisdatum
and ? >= bisdatum)
or (?>= vondatum
and ? <= vondatum))";
if($uid)
$qry .= " and uid = ? ";
$qry .= "
order by nachname
";
$result = $this->execQuery($qry, $paramsArray);
return $result;
}
public function getMitarbeiterWithZeitsperren($von, $bis, $fix=false, $lector=false, $oe=null, $ass=false, $stg=false)
{
$paramsArray = [$von, $bis, $bis, $von];
if($oe)
{
$paramsArray[] = $oe;
}
if($stg)
{
$paramsArray[] = $stg;
}
$qry = "
SELECT
m.nachname,
m.vorname,
m.uid,
z.vondatum,
z.bisdatum,
z.vertretung_uid,
z.erreichbarkeit_kurzbz,
m.lektor,
m.fixangestellt,
mv.kurzbz
FROM campus.vw_mitarbeiter m
join public.tbl_benutzer bn on bn.uid = m.uid";
if($oe || $ass || $stg)
{
$qry .= " JOIN public.tbl_benutzerfunktion bf on bf.uid = bn.uid";
}
if($stg)
{
$qry .= " JOIN public.tbl_studiengang stg using (oe_kurzbz)";
}
$qry.= "
LEFT JOIN campus.tbl_zeitsperre z
ON m.uid = z.mitarbeiter_uid
AND (
(? <= z.bisdatum AND ? >= z.bisdatum)
OR
(? >= z.vondatum AND ? <= z.vondatum)
)
left join public.tbl_mitarbeiter mv on z.vertretung_uid = mv.mitarbeiter_uid
where bn.aktiv = true
";
if($fix) {
$qry.= " AND m.fixangestellt = true";
}
if($lector) {
$qry.= " AND m.lektor = true";
}
if ($oe)
{
$qry.= "
AND bf.funktion_kurzbz ='oezuordnung'
AND bf.oe_kurzbz= ?
AND (bf.datum_von is null or bf.datum_von <=now())
AND (bf.datum_bis is null or bf.datum_bis >= now())
";
}
if ($ass)
{
$qry.= "
AND bf.funktion_kurzbz ='ass'
AND (bf.datum_von is null or bf.datum_von <=now())
AND (bf.datum_bis is null or bf.datum_bis >= now())
";
}
if ($stg)
{
$qry.= "
AND stg.studiengang_kz = ?
";
}
$qry .= " order by nachname, vorname, uid";
$result = $this->execQuery($qry, $paramsArray);
return $result;
}
public function checkIfZeitsperreExists($uid, $datum, $stunde)
{
$this->db->select("*");
@@ -337,29 +77,30 @@ class Zeitsperre_model extends DB_Model
$this->db->group_start();
$this->db->where('vondatum <', $datum);
$this->db->or_group_start();
$this->db->where('vondatum', $datum);
$this->db->group_start();
$this->db->where('vonstunde <=', $stunde);
$this->db->or_where('vonstunde IS NULL', null, false);
$this->db->group_end();
$this->db->group_end();
$this->db->where('vondatum <', $datum);
$this->db->or_group_start();
$this->db->where('vondatum', $datum);
$this->db->group_start();
$this->db->where('vonstunde <=', $stunde);
$this->db->or_where('vonstunde IS NULL', null, false);
$this->db->group_end();
$this->db->group_end();
$this->db->group_end();
$this->db->group_start();
$this->db->where('bisdatum >', $datum);
$this->db->or_group_start();
$this->db->where('bisdatum', $datum);
$this->db->group_start();
$this->db->where('bisstunde >=', $stunde);
$this->db->or_where('bisstunde IS NULL', null, false);
$this->db->group_end();
$this->db->where('bisdatum >', $datum);
$this->db->or_group_start();
$this->db->where('bisdatum', $datum);
$this->db->group_start();
$this->db->where('bisstunde >=', $stunde);
$this->db->or_where('bisstunde IS NULL', null, false);
$this->db->group_end();
$this->db->group_end();
$this->db->group_end();
$this->db->group_end();
return $this->load();
}
}
@@ -11,20 +11,4 @@ class Zeitsperretyp_model extends DB_Model
$this->dbTable = 'campus.tbl_zeitsperretyp';
$this->pk = 'zeitsperretyp_kurzbz';
}
public function getTypenZeitsperren($excludedTypes = [])
{
$whereNotClause = "";
if (count($excludedTypes)) {
$excludedTypes = array_map(
function ($type) {
return "'$type'";
},
$excludedTypes
);
$excludedTypes = implode(", ", $excludedTypes);
$whereNotClause = "WHERE NOT zeitsperretyp_kurzbz IN ($excludedTypes)";
}
return $this->execQuery("SELECT * FROM $this->dbTable $whereNotClause ORDER BY beschreibung ASC");
}
}
@@ -10,7 +10,6 @@ $includesArray = array(
'primevue3' => true,
'skipID' => '#fhccontent',
'vuedatepicker11' => true,
'tinymce5' => true,
'customCSSs' => array(
'public/css/components/verticalsplit.css',
'public/css/components/searchbar/searchbar.css',
@@ -22,14 +21,9 @@ $includesArray = array(
'public/css/components/FilterComponent.css',
'public/css/components/Profil.css',
'public/css/components/FormUnderline.css',
'public/css/components/inViewTooltip.css',
'public/css/components/abgabetool/abgabe.css',
'public/css/Cis4/Cms.css',
'public/css/Cis4/Studium.css',
'public/css/components/vue-datepicker.css',
'public/css/Cis4/Benotungstool.css',
'public/css/components/Zeitsperrenma.css', //70747
'public/css/Cis4/Zeitsperren.css', //77941
'public/css/Cis4/Studium.css'
),
'customJSs' => array(
'vendor/npm-asset/primevue/accordion/accordion.min.js',
@@ -43,15 +37,11 @@ $includesArray = array(
'vendor/npm-asset/primevue/timeline/timeline.min.js',
'vendor/npm-asset/primevue/inplace/inplace.min.js',
'vendor/npm-asset/primevue/message/message.min.js',
'vendor/npm-asset/primevue/divider/divider.min.js',
'vendor/npm-asset/primevue/password/password.js',
'vendor/npm-asset/primevue/multiselect/multiselect.js',
'vendor/npm-asset/primevue/tieredmenu/tieredmenu.js',
'vendor/moment/luxonjs/luxon.min.js'
),
'customJSModules' => array(
'public/js/apps/Cis/Cis.js',
'vendor/olifolkerd/tabulator5/src/js/modules/ColumnCalcs/ColumnCalcs.js'
),
);
@@ -59,8 +49,6 @@ $includesArray = array(
$this->load->view('templates/CISVUE-Header', $includesArray);
?>
<div id="fhccontent" class="h-100" route=<?php echo $route ?>>
<router-view
:permissions="<?= htmlspecialchars(json_encode($permissions ?? [])); ?>"
></router-view>
<router-view></router-view>
</div>
<?php $this->load->view('templates/CISVUE-Footer', $includesArray); ?>
+2 -2
View File
@@ -12,13 +12,13 @@ $includesArray = array(
'tinymce5' => true,
'phrases' => array(
'global',
'ui'
'ui',
),
'customCSSs' => [
'public/css/components/vue-datepicker.css',
'public/css/components/primevue.css',
'public/css/Vertragsverwaltung.css',
'public/css/components/Detailheader.css',
'public/css/components/Detailheader.css'
],
'customJSs' => [
#'vendor/npm-asset/primevue/tree/tree.min.js',
@@ -1,5 +1,7 @@
<?php
$includesArray = array(
$this->load->view(
'templates/FHC-Header',
array(
'title' => 'Lehrauftrag bestellen',
'jquery3' => true,
'jqueryui1' => true,
@@ -10,15 +12,8 @@ $includesArray = array(
'dialoglib' => true,
'navigationwidget' => true,
'addons' => true,
)
);
$this->load->view(
'templates/FHC-Header',
$includesArray
);
?>
<?php echo $this->widgetlib->widget('NavigationWidget'); ?>
@@ -38,12 +33,4 @@ $this->load->view(
</div>
</div>
<?php
$this->load->view(
'templates/FHC-Footer',
$includesArray
);
?>
<?php $this->load->view('templates/FHC-Footer'); ?>
@@ -1,6 +1,7 @@
<?php
$includesArray = array(
$this->load->view(
'templates/FHC-Header',
array(
'title' => 'Lehrauftrag bestellen',
'jquery3' => true,
'bootstrap3' => true,
@@ -8,13 +9,8 @@ $includesArray = array(
'sbadmintemplate3' => true,
'ajaxlib' => true,
'navigationwidget' => true,
)
);
$this->load->view(
'templates/FHC-Header',
$includesArray
);
?>
<?php echo $this->widgetlib->widget('NavigationWidget'); ?>
@@ -38,11 +34,4 @@ $this->load->view(
</div>
</div>
<?php
$this->load->view(
'templates/FHC-Footer',
$includesArray
);
?>
<?php $this->load->view('templates/FHC-Footer'); ?>
@@ -1,101 +1,89 @@
<?php
$includesArray = array(
'title' => 'Lehrauftrag annehmen',
'jquery3' => true,
'jqueryui1' => true,
'jquerycheckboxes1' => true,
'bootstrap5' => true,
'fontawesome6' => true,
'sbadmintemplate' => false,
'tabulator5' => true,
'tabulator5JQuery' => true,
'cis'=>true,
'momentjs2' => true,
'ajaxlib' => true,
'dialoglib' => true,
'tablewidget' => true,
'phrases' => array(
'global' => array(
'lehrauftraegeAnnehmen',
'dokumentePDF',
'PDFLehrauftraegeFH',
'PDFLehrauftraegeLehrgaenge'
),
'ui' => array(
'anzeigen',
'alleAnzeigen',
'nurBestellteAnzeigen',
'nurErteilteAnzeigen',
'nurAngenommeneAnzeigen',
'nurStornierteAnzeigen',
'hilfeZuDieserSeite',
'alleAuswaehlen',
'alleAbwaehlen',
'ausgewaehlteZeilen',
'hilfe',
'tabelleneinstellungen',
'keineDatenVorhanden',
'spaltenEinstellen',
'bestelltVon',
'erteiltVon',
'angenommenVon',
'storniertVon',
'lehrauftragInBearbeitung',
'wartetAufErteilung',
'wartetAufErneuteErteilung',
'letzterStatusBestellt',
'letzterStatusErteilt',
'letzterStatusAngenommen',
'vertragWurdeStorniert',
$this->load->view(
'templates/FHC-Header',
array(
'title' => 'Lehrauftrag annehmen',
'jquery3' => true,
'jqueryui1' => true,
'jquerycheckboxes1' => true,
'bootstrap5' => true,
'fontawesome6' => true,
'sbadmintemplate' => false,
'tabulator5' => true,
'tabulator5JQuery' => true,
'cis'=>true,
'momentjs2' => true,
'ajaxlib' => true,
'dialoglib' => true,
'tablewidget' => true,
'phrases' => array(
'global' => array(
'lehrauftraegeAnnehmen',
'dokumentePDF',
'PDFLehrauftraegeFH',
'PDFLehrauftraegeLehrgaenge'
),
'ui' => array(
'anzeigen',
'alleAnzeigen',
'nurBestellteAnzeigen',
'nurErteilteAnzeigen',
'nurAngenommeneAnzeigen',
'nurStornierteAnzeigen',
'hilfeZuDieserSeite',
'alleAuswaehlen',
'alleAbwaehlen',
'ausgewaehlteZeilen',
'hilfe',
'tabelleneinstellungen',
'keineDatenVorhanden',
'spaltenEinstellen',
'bestelltVon',
'erteiltVon',
'angenommenVon',
'storniertVon',
'lehrauftragInBearbeitung',
'wartetAufErteilung',
'wartetAufErneuteErteilung',
'letzterStatusBestellt',
'letzterStatusErteilt',
'letzterStatusAngenommen',
'vertragWurdeStorniert',
),
'password' => array('password'),
'dms' => array('informationsblattExterneLehrende'),
'table' => array(
'spaltenEinAusblenden',
'spaltenEinAusblendenMitKlickOeffnen',
'spaltenEinAusblendenAufEinstellungenKlicken',
'spaltenEinAusblendenMitKlickAktivieren',
'spaltenEinAusblendenMitKlickSchliessen',
'spaltenbreiteVeraendern',
'spaltenbreiteVeraendernText',
'spaltenbreiteVeraendernInfotext',
'zeilenAuswaehlen',
'zeilenAuswaehlenEinzeln',
'zeilenAuswaehlenBereich',
'zeilenAuswaehlenAlle'
),
'password' => array('password'),
'dms' => array('informationsblattExterneLehrende'),
'table' => array(
'spaltenEinAusblenden',
'spaltenEinAusblendenMitKlickOeffnen',
'spaltenEinAusblendenAufEinstellungenKlicken',
'spaltenEinAusblendenMitKlickAktivieren',
'spaltenEinAusblendenMitKlickSchliessen',
'spaltenbreiteVeraendern',
'spaltenbreiteVeraendernText',
'spaltenbreiteVeraendernInfotext',
'zeilenAuswaehlen',
'zeilenAuswaehlenEinzeln',
'zeilenAuswaehlenBereich',
'zeilenAuswaehlenAlle'
'lehre' => array(
'lehrauftraegeAnnehmen',
'lehrauftraegeAnnehmenText',
'lehrauftraegeAnnehmenKlickStatusicon',
'lehrauftraegeAnnehmenLehrauftraegeWaehlen',
'lehrauftraegeAnnehmenMitKlickAnnehmen',
'lehrauftraegeNichtAuswaehlbar',
'lehrauftraegeNichtAuswaehlbarTextBeiAnnahme',
'filterAlleBeiAnnahme',
'filterErteiltBeiAnnahme',
'filterAngenommen'
)
),
'lehre' => array(
'lehrauftraegeAnnehmen',
'lehrauftraegeAnnehmenText',
'lehrauftraegeAnnehmenKlickStatusicon',
'lehrauftraegeAnnehmenLehrauftraegeWaehlen',
'lehrauftraegeAnnehmenMitKlickAnnehmen',
'lehrauftraegeNichtAuswaehlbar',
'lehrauftraegeNichtAuswaehlbarTextBeiAnnahme',
'filterAlleBeiAnnahme',
'filterErteiltBeiAnnahme',
'filterAngenommen'
)
),
'customJSs' => array(
'public/js/bootstrapper.js',
'public/js/lehre/lehrauftrag/acceptLehrauftrag.js'
'customJSs' => array(
'public/js/bootstrapper.js',
'public/js/lehre/lehrauftrag/acceptLehrauftrag.js')
)
);
if (defined("CIS4")) {
$this->load->view(
'templates/CISVUE-Header',
$includesArray
);
} else {
$this->load->view(
'templates/FHC-Header',
$includesArray
);
}
?>
@@ -242,17 +230,5 @@ if (defined("CIS4")) {
</div><!-- end page-wrapper -->
<br>
<?php
if (defined("CIS4")) {
$this->load->view(
'templates/CISVUE-Footer',
$includesArray
);
} else {
$this->load->view(
'templates/FHC-Footer',
$includesArray
);
}
?>
<?php $this->load->view('templates/FHC-Footer'); ?>
@@ -232,8 +232,8 @@ FROM
SELECT
pa.lehreinheit_id,
lv.lehrveranstaltung_id,
pa.projektarbeit_id::text AS "projektarbeit_id",
pa.studiensemester_kurzbz,
pa.projektarbeit_id::text AS "projektarbeit_id",
le.studiensemester_kurzbz,
stg.studiengang_kz,
upper(stg.typ || stg.kurzbz) AS "stg_typ_kurzbz",
lv.orgform_kurzbz,
@@ -268,7 +268,8 @@ FROM
FROM
lehre.tbl_projektbetreuer pb
JOIN lehre.tbl_projektarbeit pa USING (projektarbeit_id)
JOIN lehre.tbl_lehrveranstaltung lv ON (pa.lehrveranstaltung_id = lv.lehrveranstaltung_id)
JOIN lehre.tbl_lehreinheit le USING (lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id)
JOIN PUBLIC.tbl_organisationseinheit oe USING (oe_kurzbz)
JOIN PUBLIC.tbl_person person USING (person_id)
LEFT JOIN lehre.tbl_vertrag vertrag USING (vertrag_id)
@@ -279,7 +280,7 @@ FROM
/* filter projektbetreuuer */
pb.person_id = \'' . $PERSON_ID . '\'
/* filter studiensemester */
AND pa.studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\'
AND le.studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\'
/* filter active lehrveranstaltungen */
AND lv.aktiv = TRUE
/* filter active organisationseinheiten */
@@ -1,101 +1,98 @@
<?php
$includesArray = array(
'title' => 'Lehrauftrag erteilen',
'jquery3' => true,
'jqueryui1' => true,
'jquerycheckboxes1' => true,
'bootstrap3' => true,
'fontawesome6' => true,
'sbadmintemplate3' => true,
'tabulator5' => true,
'tabulator5JQuery' => true,
'momentjs2' => true,
'ajaxlib' => true,
'dialoglib' => true,
'tablewidget' => true,
'navigationwidget' => true,
'phrases' => array(
'global' => array(
'lehrauftraegeErteilen',
'mehrHilfe',
'weitereInformationenUnter'
),
'ui' => array(
'anzeigen',
'alleAnzeigen',
'nurNeueAnzeigen',
'nurBestellteAnzeigen',
'nurErteilteAnzeigen',
'nurAngenommeneAnzeigen',
'nurGeaenderteAnzeigen',
'nurDummiesAnzeigen',
'hilfeZuDieserSeite',
'alleAuswaehlen',
'alleAbwaehlen',
'ausgewaehlteZeilen',
'hilfe',
'tabelleneinstellungen',
'keineDatenVorhanden',
'spaltenEinstellen',
'bestelltVon',
'erteiltVon',
'angenommenVon',
'stundenStundensatzGeaendert',
'neuerLehrauftragOhneLektorVerplant',
'wartetAufBestellung',
'wartetAufErneuteBestellung',
'neuerLehrauftragWartetAufBestellung',
'letzterStatusBestellt',
'letzterStatusErteilt',
'letzterStatusAngenommen',
),
'table' => array(
'spaltenEinAusblenden',
'spaltenEinAusblendenMitKlickOeffnen',
'spaltenEinAusblendenAufEinstellungenKlicken',
'spaltenEinAusblendenMitKlickAktivieren',
'spaltenEinAusblendenMitKlickSchliessen',
'spaltenbreiteVeraendern',
'spaltenbreiteVeraendernText',
'spaltenbreiteVeraendernInfotext',
'zeilenAuswaehlen',
'zeilenAuswaehlenEinzeln',
'zeilenAuswaehlenBereich',
'zeilenAuswaehlenAlle'
),
'lehre' => array(
'lehrauftragStandardBestellprozess',
'lehrauftragStandardBestellprozessBestellen',
'lehrauftragStandardBestellprozessErteilen',
'lehrauftragStandardBestellprozessAnnehmen',
'lehrauftraegeErteilen',
'lehrauftraegeErteilenText',
'lehrauftraegeErteilenKlickStatusicon',
'lehrauftraegeErteilenLehrauftraegeWaehlen',
'lehrauftraegeErteilenMitKlickErteilen',
'geaenderteLehrauftraege',
'geaenderteLehrauftraegeTextBeiErteilung',
'lehrauftraegeNichtAuswaehlbar',
'lehrauftraegeNichtAuswaehlbarTextBeiErteilung',
'filterAlle',
'filterNeu',
'filterBestellt',
'filterErteilt',
'filterAngenommen',
'filterGeaendert',
'filterDummies'
)
),
'customJSs' => array(
'public/js/bootstrapper.js',
'public/js/lehre/lehrauftrag/approveLehrauftrag.js'
)
);
$this->load->view(
'templates/FHC-Header',
$includesArray
'templates/FHC-Header',
array(
'title' => 'Lehrauftrag erteilen',
'jquery3' => true,
'jqueryui1' => true,
'jquerycheckboxes1' => true,
'bootstrap3' => true,
'fontawesome6' => true,
'sbadmintemplate3' => true,
'tabulator5' => true,
'tabulator5JQuery' => true,
'momentjs2' => true,
'ajaxlib' => true,
'dialoglib' => true,
'tablewidget' => true,
'navigationwidget' => true,
'phrases' => array(
'global' => array(
'lehrauftraegeErteilen',
'mehrHilfe',
'weitereInformationenUnter'
),
'ui' => array(
'anzeigen',
'alleAnzeigen',
'nurNeueAnzeigen',
'nurBestellteAnzeigen',
'nurErteilteAnzeigen',
'nurAngenommeneAnzeigen',
'nurGeaenderteAnzeigen',
'nurDummiesAnzeigen',
'hilfeZuDieserSeite',
'alleAuswaehlen',
'alleAbwaehlen',
'ausgewaehlteZeilen',
'hilfe',
'tabelleneinstellungen',
'keineDatenVorhanden',
'spaltenEinstellen',
'bestelltVon',
'erteiltVon',
'angenommenVon',
'stundenStundensatzGeaendert',
'neuerLehrauftragOhneLektorVerplant',
'wartetAufBestellung',
'wartetAufErneuteBestellung',
'neuerLehrauftragWartetAufBestellung',
'letzterStatusBestellt',
'letzterStatusErteilt',
'letzterStatusAngenommen',
),
'table' => array(
'spaltenEinAusblenden',
'spaltenEinAusblendenMitKlickOeffnen',
'spaltenEinAusblendenAufEinstellungenKlicken',
'spaltenEinAusblendenMitKlickAktivieren',
'spaltenEinAusblendenMitKlickSchliessen',
'spaltenbreiteVeraendern',
'spaltenbreiteVeraendernText',
'spaltenbreiteVeraendernInfotext',
'zeilenAuswaehlen',
'zeilenAuswaehlenEinzeln',
'zeilenAuswaehlenBereich',
'zeilenAuswaehlenAlle'
),
'lehre' => array(
'lehrauftragStandardBestellprozess',
'lehrauftragStandardBestellprozessBestellen',
'lehrauftragStandardBestellprozessErteilen',
'lehrauftragStandardBestellprozessAnnehmen',
'lehrauftraegeErteilen',
'lehrauftraegeErteilenText',
'lehrauftraegeErteilenKlickStatusicon',
'lehrauftraegeErteilenLehrauftraegeWaehlen',
'lehrauftraegeErteilenMitKlickErteilen',
'geaenderteLehrauftraege',
'geaenderteLehrauftraegeTextBeiErteilung',
'lehrauftraegeNichtAuswaehlbar',
'lehrauftraegeNichtAuswaehlbarTextBeiErteilung',
'filterAlle',
'filterNeu',
'filterBestellt',
'filterErteilt',
'filterAngenommen',
'filterGeaendert',
'filterDummies'
)
),
'customJSs' => array(
'public/js/bootstrapper.js',
'public/js/lehre/lehrauftrag/approveLehrauftrag.js'
)
)
);
?>
@@ -211,13 +208,5 @@ $this->load->view(
</div><!-- end page-wrapper -->
<br>
<?php
$this->load->view(
'templates/FHC-Footer',
$includesArray
);
?>
<?php $this->load->view('templates/FHC-Footer'); ?>

Some files were not shown because too many files have changed in this diff Show More