Compare commits

..

1028 Commits

Author SHA1 Message Date
Johann Hoffmann 735bd8dd0a add tabulator6 option; added Filter function "scrollToLastActive" for tabulator setups losing scroll when changing fhc-tabs; 2025-01-28 14:46:33 +01:00
Andreas Österreicher 1489706027 Merge branch 'Monika70-Export' 2025-01-16 13:22:51 +01:00
Andreas Österreicher 103df5afe5 Merge branch 'Export' of https://github.com/Monika70/FHC-Core into Monika70-Export 2025-01-16 13:21:14 +01:00
Andreas Österreicher ba2b41f63a Merge branch 'feature-55289/pep_fine_tuning' 2025-01-16 13:12:26 +01:00
ma0048 f381ef229e - index tbl_lehrveranstaltung_faktor_lvid hinzugefuegt
- sortierung gleichgezogen
2025-01-16 10:38:01 +01:00
Szabo Mónika f1234c0b99 Update studentenexportextended.xls.php
Zusätzliche Spalte Person_id hinzufügen
2025-01-15 14:37:06 +01:00
Harald Bamberger fd67974d55 fix typo 2025-01-15 13:35:58 +01:00
Harald Bamberger a1a9e96bc0 permission basis/gehaelter 2025-01-15 13:34:16 +01:00
Andreas Österreicher aab0f339ab Merge branch 'feature-55316/international_skills_credits_entfernen_neue_massnahmen' 2025-01-15 13:06:04 +01:00
Harald Bamberger d4bb06c4f6 Merge branch 'feature-54920/DB_Model_encrypted_columns_spaltenname_enthaelt_anderen_spaltennamen' 2025-01-15 09:20:54 +01:00
Harald Bamberger 0770ec2bd8 Merge branch 'master' into feature-54920/DB_Model_encrypted_columns_spaltenname_enthaelt_anderen_spaltennamen 2025-01-15 09:03:41 +01:00
ma0048 50aca4a545 - umbenennung auf internatinal credits 2025-01-14 11:00:26 +01:00
Harald Bamberger 46914e8a65 bugfix wenn mehrere karenzen im abgefragten zeitraum vorhanden sind 2025-01-07 14:38:08 +01:00
Andreas Österreicher a802e67faf Merge branch 'pep_deploy' 2024-12-16 13:57:15 +01:00
Andreas Österreicher 2c91756a36 Added missing APP PEP to checksystem 2024-12-16 13:29:55 +01:00
Harald Bamberger 0d2882d8aa Merge branch 'feature-25999/SearchbarStudent' 2024-12-13 12:11:12 +01:00
Harald Bamberger f62108f1d4 change concatenation of verband, use contact email in Stv search result, use dummy image when viewing anothers profile and foto is null or foto_sperre is not false 2024-12-13 12:09:16 +01:00
ma0048 746f8ab35a Merge branch 'feature-54822/filtercomponent_custom_headerfilter' into pep_deploy 2024-12-13 11:51:11 +01:00
ma0048 70b44c2202 Merge branch 'feature-40717/pep_faktor' into pep_deploy
# Conflicts:
#	public/js/components/filter/Filter.js
#	system/dbupdate_3.4.php
#	system/phrasesupdate.php
2024-12-13 11:50:53 +01:00
ma0048 c0d2474ad2 -dbupdate gegencheck eingebaut
- delete restrict auf cascade geändert
2024-12-13 11:42:00 +01:00
Harald Bamberger 5a174e554a use studentStv in Studentenverwaltung config, add aktiv to student and studentStv result, use studentStv in searchbar component, add searchbar_inaktiv css class, use aktiv to render inactive studentStv results with css class searchbar_inaktiv 2024-12-13 11:25:02 +01:00
ma0048 3451741327 - ON DELETE RESTRICT auf ON DELETE CASCADE bei bei den notizen
- sql angepast
2024-12-13 11:03:46 +01:00
SimonGschnell a3840d4c77 update(Searchbar/Student):shows dummy image if the student has foto_spere true 2024-12-13 10:47:34 +01:00
SimonGschnell 9a1777d1aa fix(_student searchfunction):fixes the sql logic for non active students 2024-12-12 15:35:56 +01:00
Harald Bamberger 4a86a48969 Merge branch 'master' into feature-25999/SearchbarStudent 2024-12-12 15:27:08 +01:00
Andreas Österreicher 1f01c55d71 LVPlan Feedback Link auf Startseite entfernt 2024-12-12 15:06:02 +01:00
Harald Bamberger 80222b7186 Merge branch 'master' into feature-25999/SearchbarStudent 2024-12-12 14:55:41 +01:00
Harald Bamberger d0266e7ef0 add vuejs3_dev to composer.json and ci javascript config file to switch between vuejs dev and prod version, alter FHC-Footer to use new config 2024-12-12 14:49:15 +01:00
Harald Bamberger 3039fd2a1e Merge branch 'master' into feature-25999/SearchbarStudent 2024-12-12 13:57:03 +01:00
ma0048 5b3ffcfc9a - faktor berechtigung angepasst 2024-12-12 12:37:24 +01:00
Andreas Österreicher 03d8205722 Merge branch 'feature-46905/LV_plan_feedback_Link_aendern' 2024-12-12 11:30:00 +01:00
SimonGschnell df8d4de50b fix(SearchbarLib/_student): the cis search does not include students that are not aktiv and has a seperate search function for the student search for the Cis and the studentverwaltung 2024-12-12 09:42:38 +01:00
Harald Bamberger 9af3f1ec0f Merge branch 'feature-25999/LvMenuFix' 2024-12-11 17:50:03 +01:00
SimonGschnell 85d59f18be refactor(searchbar/Student): studiengang/verband/email are queried for the display in the searchbar component 2024-12-11 15:30:41 +01:00
ma0048 6a1e518da1 - defaultheaderfilter function in eigenes file verschoben 2024-12-11 13:44:19 +01:00
ma0048 8127091e2e - tags werden im fas nicht angezeigt
- class für tags hinzugefuegt
- prop confirmLimit hinzugefuegt
2024-12-11 13:25:38 +01:00
SimonGschnell a357001648 feature(Searchbar/StudentenSuche): adds student to the searchbar options and adds shadow to the searchbar 2024-12-11 12:34:58 +01:00
Harald Bamberger bfc6e86f05 Merge branch 'master' into feature-54920/DB_Model_encrypted_columns_spaltenname_enthaelt_anderen_spaltennamen 2024-12-11 11:54:23 +01:00
Harald Bamberger 3c8bb37a36 Merge branch 'master' into feature-54920/DB_Model_encrypted_columns_spaltenname_enthaelt_anderen_spaltennamen 2024-12-11 11:52:50 +01:00
SimonGschnell 2567db7725 fix(LvMenu.js): fixes layout of MenuPunkt if multiple moodle links are available 2024-12-11 11:28:40 +01:00
Andreas Österreicher 034e1397e8 Merge branch 'feature-52814/infocenter_infocentermitarbeiter_spalte_beim_loeschen_des_dokuments' 2024-12-11 08:36:27 +01:00
Andreas Österreicher 35ded7950f Merge branch 'feature-46974/neuer_filter_ueber_ueberfaellige_buchungen' 2024-12-11 08:00:54 +01:00
Andreas Österreicher a6a74cd1e0 Merge branch 'feature-40413/testtool_sperren_bei_namen_mit_hochkomma' 2024-12-11 07:52:27 +01:00
Andreas Österreicher bae48fa175 Merge branch 'master' into feature-40413/testtool_sperren_bei_namen_mit_hochkomma 2024-12-11 07:13:20 +01:00
Andreas Österreicher 94f4761163 Merge branch 'bug-54917/Gruppenmanagement_Berechtigung' 2024-12-11 07:07:44 +01:00
Alexei Karpenko cc99d2b378 Gruppenmanagement: added checks so only Gruppenmanager can edit groups 2024-12-10 12:03:58 +01:00
Andreas Österreicher 07ee3e1f4e Import der Leistungsstipendien angepasst. Neue Spaltenreihenfolge, Keine
automatische Gegenbuchung, Import der Bankdaten
2024-12-06 12:50:58 +01:00
Harald Bamberger 3cea79cb28 Merge branch 'feature-25999/C4_cleanup_rc' 2024-12-04 12:44:08 +01:00
Harald Bamberger e159dc44dc Merge branch 'master' into feature-25999/C4_cleanup_rc 2024-12-04 12:43:06 +01:00
Andreas Österreicher 055cea2002 Termin3 entfernt aus Default Checksystem 2024-12-04 11:25:49 +01:00
Harald Bamberger f105bdb36a revert FhcApi.js to current master 2024-12-04 11:09:37 +01:00
Harald Bamberger 1b445005af remove addMeta debug info 2024-12-04 09:28:59 +01:00
Harald Bamberger 2fee03ebcc remove sprachen menu from main nav 2024-12-04 09:17:15 +01:00
Harald Bamberger d30ba24d2f add config cis_send_profil_update_mails, use it in profil update controllers 2024-12-04 09:15:44 +01:00
ma0048 631010821b - check bei projectstunden ob stunden eingetragen sind 2024-12-03 17:08:03 +01:00
ma0048 b34a7bfabc - custom filter tabulator 2024-12-03 16:13:48 +01:00
ma0048 6a1af1b2dd - fuer lehre tab planungsstatus hinzugefuegt
- config fuer planungsstatus
- tags ohne notiz setzen
2024-12-03 15:31:32 +01:00
Harald Bamberger 6f69046b71 use regex with word boundaries to be more specific when replacing 2024-12-03 13:44:24 +01:00
ma0048 19b56ff252 - tags
- phrases
- stundensatzbydatum
- filter nur count
2024-12-03 12:36:54 +01:00
Harald Bamberger af2f3348b4 Merge branch 'master' into feature-25999/C4_cleanup 2024-12-03 07:37:22 +01:00
Johann Hoffmann 41ad440cd4 update newsWidget template & css, fixed carousel css transition; 2024-12-02 16:41:42 +01:00
ma0048 1a1ed49f8b - styling für neuen tag
- hover effekt
- tagicon statt plus
2024-12-02 13:09:38 +01:00
Johann Hoffmann bf5e8e9c0e Merge branch 'feature-25999/C4_cleanup' into feature-25999/C4_anwesenheiten_widget 2024-12-02 10:57:40 +01:00
Andreas Österreicher e63234e7bc Gegencheck und Anwesenheit App eingefügt 2024-12-02 10:09:09 +01:00
Johann Hoffmann 1ca0f35d29 news widget template carousel with menu update; 2024-11-29 15:24:33 +01:00
SimonGschnell 1336860ecd feature(Dashboard Transitions): uses Vue's built-in Transition component to add transitions to the widget config elements 2024-11-29 13:23:51 +01:00
Harald Bamberger 278e5d8abd Merge branch 'master' into feature-25999/C4_cleanup 2024-11-29 13:04:08 +01:00
SimonGschnell 95e59007cc refactor(Settings/NavUser Collapsibles): closes the collapsibles if the user clicks outside of the elements 2024-11-29 12:29:59 +01:00
SimonGschnell 857d4d7282 refactor(Calendar indicator):adds Vue transition to the Calendar indicator through Vue's built-in component 2024-11-29 11:50:27 +01:00
Harald Bamberger 7a7c91b67b readd lines of code that were lost during merging 2024-11-29 11:19:57 +01:00
SimonGschnell 9cf6036926 refactor(Paginatino.js): makes the pagionation component responsive on mobile displays 2024-11-29 10:57:14 +01:00
Andreas Österreicher 11eae29dab Merge branch 'feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp' 2024-11-28 14:04:50 +01:00
Andreas Österreicher 0f476b4e46 Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp 2024-11-28 14:02:41 +01:00
Andreas Österreicher 677d6e97d6 Config zur Steuerung für welche Studiengaenge die Digit. Anwesenheiten
sichtbar sein sollen (Testbetrieb)
2024-11-28 13:38:25 +01:00
SimonGschnell 021a140dd3 refactor(LvInfo.js): also adds a Profil View link to the lektor name 2024-11-28 13:09:41 +01:00
SimonGschnell 4f8ca679fb fix(Calendar/Week/Day/Page.js): removes the calendar indicator when moving the mouse outside of the calendar 2024-11-28 12:52:24 +01:00
SimonGschnell 9dfa8d13a6 feature(Mylv/Info.js): adds Profil view links to the Lektoren in MyLv Info and fixes the dupplicate lektoren names 2024-11-28 12:46:23 +01:00
SimonGschnell 71c39edd66 fix(Cis/Sprachen.js): fixes classes of the Sprachen component inside of the Nav Menu when toggled 2024-11-28 10:53:00 +01:00
Johann Hoffmann 1346466f79 Merge branch 'master' into feature-25999/C4_anwesenheiten_widget 2024-11-28 10:43:57 +01:00
Johann Hoffmann beb40cfcc9 Merge branch 'feature-25999/C4_cleanup' into feature-25999/C4_anwesenheiten_widget 2024-11-28 10:22:57 +01:00
Andreas Österreicher 0a4d8bb1f6 Falsch verschachtelte Phrase korrigiert 2024-11-28 08:43:25 +01:00
Johann Hoffmann 39f1f825a5 fhcApi extendable & reactive; provide reactive viewdata from dashboard to widgets by inject/provide reworked news xslt in db; css change since overflow-auto is in xslt now; WIP anw widget; 2024-11-27 16:30:54 +01:00
SimonGschnell 6e1943928a feature(Cms/Content_types/Raum_contentmittitel.js): wraps the h1 title of the content with a link to the Reservierungen of that room 2024-11-27 15:04:56 +01:00
Andreas Österreicher 490a658e6d Merge branch 'feature-8482/Pruefungsprotokoll_zur_Einsicht_exportieren' 2024-11-27 13:45:30 +01:00
Andreas Österreicher fd91a4cb85 Merge branch 'master' into feature-8482/Pruefungsprotokoll_zur_Einsicht_exportieren 2024-11-27 13:44:24 +01:00
SimonGschnell 800d7ba005 refactor(Cis.css fhc-entry styles): switches the background-colors of the fhc-entry class between selected and not selected 2024-11-27 13:04:52 +01:00
SimonGschnell 89539d59fd refactor(components/Cis/Sprachen.js): refactors the Sprachen component with different styles and stores the user_langauge in the global properties of the Vue application by managing a reactive state in the phrasen plugin 2024-11-27 11:50:19 +01:00
Johann Hoffmann 1ba857b524 only show digi anw in cis_menu_lv when corresponding lva is from BIF/257 for testphase 2024-11-26 17:12:11 +01:00
SimonGschnell 0ebc6e820c refactor(Calendar/Page/Event style): change the margins of an event, so that the border of the event is visible 2024-11-26 16:27:48 +01:00
SimonGschnell 24740d055e feature(Sprache/Phrasen aendern): creates a Cis Sprachen component that lists all available Sprachen from the database and lets the user change the currently active language and persist it in the database 2024-11-26 16:26:29 +01:00
Johann Hoffmann c02c1e9955 hinweis "testphase -> keine benotung" phrase 2024-11-26 15:59:42 +01:00
Andreas Österreicher c32f65bc1e Reihungstestangetreten Check aus BIS-Bewerbermeldung entfernt 2024-11-26 12:49:21 +01:00
SimonGschnell 82f1a70de5 fix(Calender/Day/Page.js): ausgewaehlte Event wird resetet wenn man den darauffolgenden oder vorherigen Tag auswaehlt 2024-11-26 09:25:24 +01:00
SimonGschnell 8983af4aef refactor(Stundenplan_model/getStundenplanQuery):removes wrong comments 2024-11-25 19:59:39 +01:00
Harald Bamberger 290da9f2c0 Merge branch 'master' into feature-25999/C4_cleanup 2024-11-25 17:09:53 +01:00
Harald Bamberger 7fe3a7c8f5 Merge branch 'feature-25999/C4_cleanup_rc' 2024-11-25 16:33:27 +01:00
Harald Bamberger 766bec887a check if constant CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN is defined 2024-11-25 16:29:41 +01:00
SimonGschnell 90bdb68175 fix(Stundenplan_model/getStundenplanQuery):changes how the OR sql statments are added to the query 2024-11-25 15:24:36 +01:00
Harald Bamberger 0bec551174 lowercase search in searchfunction fhcapifactory path 2024-11-25 14:24:04 +01:00
Harald Bamberger f90f5154a0 remove searchdummy function and dummyapi 2024-11-25 13:57:25 +01:00
Harald Bamberger 2ed24ca60f remove unneeded controllers, views and vuejs apps 2024-11-25 13:48:33 +01:00
SimonGschnell 699595e891 refactor(DashboardWidget/Stundenplan.js):adds the template for the MonthPage when the Month of the calendar is visible 2024-11-25 13:34:36 +01:00
SimonGschnell 43fbd1d8f1 refactor(Calendar/Day/Page.js): moves the content to the parent, so that different views can display different content 2024-11-25 13:28:55 +01:00
SimonGschnell 36c129fcaf reafactor(Calendar/Day/Page.js-Calendar/Week/Page.js): refactors styles of elements for easier readability 2024-11-25 11:41:22 +01:00
Harald Bamberger df0ed6715c add renderif to default room action if no content id is defined 2024-11-25 11:31:13 +01:00
Harald Bamberger 6f1e61fa00 move contentid of cis4 menu root to ci config, remove unused controller components CisVue, modify CISVUE-Header to use config for cis4 menu root content id 2024-11-22 15:16:27 +01:00
SimonGschnell 1297a8a23a reafactor(Calendar/Day/Page.js): refactors styles of elements for easier readability 2024-11-22 15:02:42 +01:00
Harald Bamberger 8e51071997 readd v-bind item removing it breaks dashboard customize view instead of plus signs a ghost widget is shown 2024-11-22 14:50:16 +01:00
Johann Hoffmann ecab3ea4d9 remove hardcoded h1 tag, keep the title h1 tag; more cleanup; 2024-11-22 11:43:05 +01:00
Andreas Österreicher 14169fafd0 Wording korrigiert 2024-11-22 11:42:24 +01:00
Johann Hoffmann e2b42de6b3 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-11-22 10:27:12 +01:00
Johann Hoffmann f4d16af68e change eye watering cms css from green background & white font to white background and black font - as it should be 2024-11-22 10:26:47 +01:00
SimonGschnell ab15a8675c Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-11-22 10:25:22 +01:00
SimonGschnell 20abd6aa05 fix(LvMenu): makes non available menu punkte disabled and non interactable 2024-11-22 10:25:02 +01:00
Johann Hoffmann 4bd4301873 more template cleanup profil 2024-11-22 10:15:31 +01:00
Andreas Österreicher fa3d36e99e Added check if Constant CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN is
available at all
2024-11-22 08:46:42 +01:00
Johann Hoffmann 16cfb0a3eb template cleanup profil 2024-11-21 17:32:34 +01:00
Johann Hoffmann 1a6b30588d MyLvApp & Components template & property definition cleanup 2024-11-21 16:11:02 +01:00
Harald Bamberger fc5ea9f4db remove unused xmlns:fo add xsl:output method html 2024-11-21 15:59:42 +01:00
Johann Hoffmann 61728f3044 dashboard & widgets: template cleanup; property definiton cleanup; delete unwrapInjectedRef -> resolved since vue3.3; 2024-11-21 15:43:35 +01:00
Johann Hoffmann a349a179d0 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-11-21 15:22:09 +01:00
Johann Hoffmann d400f34e0f missing phrasen 2024-11-21 15:21:33 +01:00
Harald Bamberger cdc9e08cd0 cleanup C4 dbupdates 2024-11-21 15:14:13 +01:00
Harald Bamberger 8eb7d18ff9 remove C4 Menu from checksystem 2024-11-21 14:04:35 +01:00
Johann Hoffmann 920bd845f8 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-11-21 13:28:10 +01:00
Johann Hoffmann 933ca20e65 tabulator in cms content -> sanitize table header contructs breaking tabulator; 2024-11-21 13:27:39 +01:00
SimonGschnell 763d038b4c fix(api/v1/Stundenplan/getStundenplan): fetches groups and studentlehrverbaende based on the date interval of the current and previous semesters 2024-11-21 12:19:22 +01:00
Harald Bamberger 6946028d76 Merge branch 'master' into feature-25999/C4_cleanup 2024-11-21 11:39:50 +01:00
kindlm 222f31c464 Merge remote-tracking branch 'origin/master' 2024-11-20 16:01:07 +01:00
kindlm 155e8da35a Ampel Übersicht tablesorter with filter + date-sort bugfix 2024-11-20 16:00:57 +01:00
Johann Hoffmann a5dd639404 stundenplan header offset class conditionally depending on fhc-calendar widget property 2024-11-20 11:14:55 +01:00
SimonGschnell 7466e414f8 Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-11-20 10:36:04 +01:00
SimonGschnell 3896aa73ea fix(Raum_information Calendar): passt die RaumInformations Seite auf die Aenderungen des Calenders an 2024-11-20 10:35:51 +01:00
Harald Bamberger f6319aa845 add new searchoptions to display search results correct again 2024-11-20 09:29:43 +01:00
Harald Bamberger 9420e22b2a optimise scrolling behavior of search results and responsive layout of search results 2024-11-19 18:13:15 +01:00
Johann Hoffmann 778149880f Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-11-19 17:46:32 +01:00
Johann Hoffmann 2c98438096 add cis4link to widget setup; show link icon in dashboard item header; remove links from widget contents; 2024-11-19 17:46:11 +01:00
Harald Bamberger a2bdca5551 fix typo 2024-11-19 17:44:44 +01:00
Harald Bamberger 05c52e41eb search only for active orgunits and rooms, also search room description 2024-11-19 17:33:57 +01:00
Johann Hoffmann 00406c50a5 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-11-19 17:09:58 +01:00
Johann Hoffmann 5e9e08d65e calendar scrollbar css fix; 2024-11-19 17:08:39 +01:00
Johann Hoffmann d8af18673c always show card header of widgets as in editMode but enable certain tools only when actually in editMode. editMode is active for dashboard not for section; less paddings overall in dashboard; deleted Section headers and put cog besides personal greeting; reformatted name var for greeting into generic viewData property; 2024-11-19 17:07:05 +01:00
Harald Bamberger c32046002d add buffer to height calculation 2024-11-19 16:24:36 +01:00
Harald Bamberger df054a7088 Merge branch 'feature-25999/C4_cleanup_rc' into feature-25999/C4_cleanup 2024-11-19 16:18:45 +01:00
Harald Bamberger 4e4e8a0a5c improve responsive layout of search results 2024-11-19 16:16:46 +01:00
Johann Hoffmann ad7b43f8a8 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-11-19 13:35:30 +01:00
Johann Hoffmann f82c669475 provide/inject editModeIsActive from section.js -> currently used in bookmark widget to move redundant config modal into actual widget when said mode is on; 2024-11-19 13:35:06 +01:00
SimonGschnell d2466b032a Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-11-19 12:51:50 +01:00
SimonGschnell 8d01995722 refactor(Studenplan Query):queries all studiensemester from start_date to end_date and matches the gruppen and studentlehrverbaende to the associated studiensemester in the query 2024-11-19 12:51:12 +01:00
Johann Hoffmann 3cb9e5b4f8 stpl widget title & show no LVA found on empty days; limit news widget content img max-width by css class; 2024-11-19 12:38:32 +01:00
SimonGschnell 5d5b2e5bc4 fix(FHCAPI_Controller): adjusts the php doc types of parameters 2024-11-19 11:35:20 +01:00
Johann Hoffmann 4cb3521361 Merge branch 'feature-53416/stundenplan_eine_lva' into feature-25999/C4_cleanup 2024-11-19 10:36:34 +01:00
Johann Hoffmann 46ef02b54d deactivate drag mode when widget config modal is opened 2024-11-19 10:33:39 +01:00
Harald Bamberger 9c6509b32a Merge branch 'feature-25999/C4_cleanup_tablewidget' into feature-25999/C4_cleanup 2024-11-19 10:18:26 +01:00
Harald Bamberger d6bdad27b2 move room specific stuff to searchconfig, add renderif method to be able to render actions conditionally via config, remove additional prop selectedtypes 2024-11-19 10:17:10 +01:00
SimonGschnell 4aed321b5e refactor(Calendar Tagesansicht): changes how the logic for opening a modal or showing the lvMenu next to the calendar is handled 2024-11-19 10:11:49 +01:00
Harald Bamberger 06dab52461 Merge branch 'feature-25999/C4_cleanup_tablewidget' into feature-25999/C4_cleanup 2024-11-19 08:48:06 +01:00
Harald Bamberger 6fc7fd7788 Merge branch 'feature-25999/C4_cleanup' into feature-25999/C4_cleanup_tablewidget 2024-11-19 08:44:24 +01:00
Harald Bamberger 13e77c8154 Merge branch 'master' into feature-25999/C4_cleanup 2024-11-19 08:43:05 +01:00
Johann Hoffmann b6a5e9b845 load stsemArray from Prestudentstati for select options; 2024-11-18 16:09:16 +01:00
Harald Bamberger ad31e73212 reset Tabulator fontsize, combine page headings 2024-11-18 11:59:40 +01:00
Harald Bamberger 5596c12af9 use deleteRow instead of getRow and delete to avoid console log error 2024-11-18 11:53:17 +01:00
Harald Bamberger e044641600 use deleteRow instead of getRow and delete to avoid console log error 2024-11-18 11:50:51 +01:00
Harald Bamberger 65c9d5a84c adminZeitverfuegbarkeiten reset tabulator fontsize 2024-11-18 10:47:08 +01:00
Harald Bamberger 545a9c31e4 tablewidget footer buttons add missing btn css class 2024-11-18 10:29:28 +01:00
Harald Bamberger 2b98a35f59 bs5 accordion-button class added 2024-11-18 10:20:13 +01:00
SimonGschnell 96ec9aa8aa fix(Calender Style): changes the hover style for fhc-entries to have a brighter color than the selectedEvent itself 2024-11-18 09:32:49 +01:00
Harald Bamberger 1b8980a0e2 add css classe with bs3 legacy colors for bg-success and bg-warning and use them in acceptLehrauftrag cis page 2024-11-15 15:58:26 +01:00
Harald Bamberger 1e5d7e01af reset font-size for tabulator on vilesci page 2024-11-15 15:57:00 +01:00
Harald Bamberger 78f216f9ad fix syntax error 2024-11-15 15:55:42 +01:00
Harald Bamberger 16cba022e2 add css class to be able to reset tabulator fontsize to 14px for vilesci pages, set active and focus class for filter buttons to new combined button, add css rules to make tooltips on cells in unselectable rows work again 2024-11-15 15:21:46 +01:00
Harald Bamberger 488847984e change property downloadTitle to titleDownload for Tabulator 5, call tabulator redraw at the end of tableInit callback to ensure renderStart callbacks are run 2024-11-15 15:19:09 +01:00
Harald Bamberger daf432fe8d port changes made for BS3 => BS5 to version of current master to get rid of many whitespace and code formating changes and only have functional changes 2024-11-15 15:14:15 +01:00
Johann Hoffmann 3146f0795f Merge branch 'feature-53416/stundenplan_eine_lva' into feature-25999/C4_cleanup 2024-11-15 14:12:00 +01:00
Johann Hoffmann 87657a18f1 apply max width only to sanitized p blocks, not column default 2024-11-15 14:10:47 +01:00
Johann Hoffmann 6e8aea7feb Merge branch 'feature-53416/stundenplan_eine_lva' into feature-25999/C4_cleanup 2024-11-15 14:04:53 +01:00
Johann Hoffmann d9f33a279d apply html sanitization on legacy cms tables intended to be rendered with tabulator 5; clears nested tables, reformats rext nodes and unordered lists to fit into tabulator cells; 2024-11-15 14:02:05 +01:00
SimonGschnell fdcef8bdab feature(Calendar): keeps track of the selected Event in a shared state and highlights the selected Event over different calendar views 2024-11-15 12:52:24 +01:00
SimonGschnell 65d0e89f06 refactor(Stundenplan events css): moves the class definitions of the events to the slot templates and adds little animations 2024-11-15 11:48:55 +01:00
SimonGschnell 45fca04029 feature(Calendar Tagesansicht):based on the window with decides wether to display the lvMenu in a Modal or next to the calendar 2024-11-15 11:18:15 +01:00
SimonGschnell ef21936975 fix(Calendar scroll):ensures the calendar scroll watcher always triggers by also passing the current focusDate of the Calendar 2024-11-15 09:52:40 +01:00
Harald Bamberger 6b828179b0 revert lehrveranstaltung.class.php lehreinheit.class.php to current master since additional functions were ported to codeigniter models and are no longer used 2024-11-14 16:13:11 +01:00
SimonGschnell ebedb30c29 refactor(Stundenplan Tagesansicht):dynamically loads the lvMenu of the first Lv of the day and hightlights the selected LV of the day 2024-11-14 14:40:18 +01:00
Johann Hoffmann 8da27a5c77 stpl widget shows selected day + next 7 days 2024-11-14 13:12:56 +01:00
SimonGschnell 681fb18222 fix(Stundenplan): readds the loadEvents and deletes the template error 2024-11-14 11:15:02 +01:00
SimonGschnell f159d6e2a7 fix(Grid CSS): remove unused css rules and css classes 2024-11-14 11:07:58 +01:00
Johann Hoffmann 3fff0c5325 Merge branch 'feature-53416/stundenplan_eine_lva' into feature-25999/C4_cleanup 2024-11-13 18:59:33 +01:00
Johann Hoffmann 160294bea4 removed grey section background and added fading thing seperator line for every section after the first 2024-11-13 18:39:19 +01:00
Johann Hoffmann a682d6e5ae overflow-y scroll changed to overflow-y auto -> avoid unnecessary scrollbars 2024-11-13 18:14:58 +01:00
Johann Hoffmann 9042f9b83b change fh logo visibility breakpoint class md -> sm; editable flag in profile based on looking at own profile or being an admin; scrollbar calc in profil app; 2024-11-13 17:27:50 +01:00
Johann Hoffmann cad2756613 Merge branch 'feature-53416/stundenplan_eine_lva' into feature-25999/C4_cleanup 2024-11-13 15:21:33 +01:00
Johann Hoffmann 2fd39a9d18 defined active color variable for lvl 2 buttons and use in css class fhc-active for language Buttons. It is yet another shade of grey. 2024-11-13 15:19:42 +01:00
SimonGschnell 329a418be3 Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-11-13 14:53:49 +01:00
SimonGschnell e3cbbfa365 feature(Calendar Tagesansicht): LvInfo und LvMenu wird neben der Tagesansicht angezeigt wenn man eine Lv auswaehlt 2024-11-13 14:52:46 +01:00
Johann Hoffmann c85790b637 Merge branch 'feature-53416/stundenplan_eine_lva' into feature-25999/C4_cleanup 2024-11-13 14:14:34 +01:00
Johann Hoffmann 5d524c5fda fix dashboard alert css by adding primevue3 in $includeArray in Dashboard view file 2024-11-13 14:14:11 +01:00
Johann Hoffmann 6613b0ea40 remove console.log 2024-11-13 14:08:58 +01:00
Johann Hoffmann a94d8d8fa5 calendar minimized only using slot; showing whole week in stundeplan widget tagesansicht grouped by day; everything in past has 0.5 opacity 2024-11-13 13:57:37 +01:00
Andreas Österreicher 3c966e00ba Merge branch 'feature-47976/KU_Linz_Statistik_Austria_Export_BPK' 2024-11-13 12:11:35 +01:00
Johann Hoffmann e43a890aff Merge branch 'feature-25999/C4_cleanup' into feature-53416/stundenplan_eine_lva
# Conflicts:
#	public/js/apps/Cis/Stundenplan.js
#	public/js/components/DashboardWidget/Stundenplan.js
2024-11-13 11:17:43 +01:00
SimonGschnell 59f8f91af9 feature(Calendar Tagesansicht): Calender wird ausgegraut wenn keine LVs an diesen Tag vorhanden sind 2024-11-13 11:00:08 +01:00
Johann Hoffmann b0cd599999 WIP stundenplan widget tagesansicht 2024-11-13 10:41:50 +01:00
SimonGschnell c244b3ad1b fix(Stundenplan): template error 2024-11-12 12:55:14 +01:00
ma0048 6b04dff4a3 - start tab tags hinzugefuegt 2024-11-12 11:47:16 +01:00
Harald Bamberger f265e20dce Merge branch 'feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp' into feature-25999/C4_cleanup 2024-11-12 11:21:16 +01:00
Harald Bamberger c691d155c9 remove dependecy to legacy phrases from LvMenu controller, add legacy phrases needed in LvMenu controller 2024-11-12 11:05:13 +01:00
SimonGschnell 3046c29ae2 fix(Calendar): does not display events on the calendar when sliding the carusel to avoid showing overlapping events 2024-11-12 09:57:10 +01:00
SimonGschnell 6cf7a8e35e fix(Calendar scroll): extends the id of the scroll anchor to include hour/day/week and changes the logic to search for the anchor depend on the week or day view 2024-11-12 09:48:03 +01:00
SimonGschnell 35691b39c4 fix(Calendar scroll): fixes the scroll feature for the Calendar 2024-11-11 16:15:14 +01:00
Johann Hoffmann 85bec1e0e3 section spacing; dashboard widgets section backgrounds; set scrollbar width css variable via new helper in FhcApp (Dashboard); WIP stundenplan alle Termine einer LV -> c4 link in bfi addon adapted; 2024-11-11 15:49:03 +01:00
SimonGschnell 094a3ed56a feature(Calendar): scrolls to the first event of the day if the prop scrollTime is passed to Calendar component 2024-11-11 15:46:09 +01:00
SimonGschnell bd1ce9fa63 refactor(Calendar Header): refactors view buttons in the calendar header 2024-11-11 14:57:34 +01:00
SimonGschnell bd54399cfd fix(Calendar Header): adds responsiveness to the calendar header and the view button group next to the header 2024-11-11 14:57:28 +01:00
SimonGschnell b7e89ab557 fix(Stundenplan hour lines): fixes the hour lines from disapearing on smaller viewports by using a box-shadow instead 2024-11-11 11:27:23 +01:00
SimonGschnell 0e49dfaba0 refactor(Calendar day view): changes the classes for fhc-calendar-day-page so that the width is divided in calendar and content 2024-11-11 10:40:58 +01:00
Johann Hoffmann 96335a7979 moved email template to fhtw addon; einheiten column visibility default false since pausen are not represented; backend code cleanup; phrase fix; 2024-11-11 09:56:43 +01:00
ma0048 355652cdb1 - added sql for tags 2024-11-11 07:51:52 +01:00
ma0048 45bc65d32a - Tags testversion
- header tooltips
- lehre spalte markieren wenn altes semester
- legende-tab hinzugefuegt
2024-11-11 07:33:49 +01:00
SimonGschnell ca7ded38d2 refactor(Stundenplan indicator): uses a 5 minute interval for the Stundenplan indicator 2024-11-08 16:08:08 +01:00
SimonGschnell f304e79ee0 feature(Stundenplan): adds Tagesansicht for the Stundenplan 2024-11-08 15:18:10 +01:00
SimonGschnell 68042c1c77 Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-11-08 14:14:54 +01:00
SimonGschnell b9690988e5 refactor(Stundenplan): uses named slots for week-view template 2024-11-08 10:53:02 +01:00
Harald Bamberger 1691c75a84 replace dependencies on legacy code with ci model functions 2024-11-07 19:18:08 +01:00
SimonGschnell f4176b86ee refactor(js helpers): moves ObjectUtils from composables to the js helpers folder and changes its import statements 2024-11-07 15:00:25 +01:00
SimonGschnell da70c77a2b feature(DateHelpers.js): creates a js helper file to create, handle and manipulate js dates 2024-11-07 15:00:18 +01:00
SimonGschnell 6732063e6a Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-11-07 13:15:08 +01:00
SimonGschnell b65d17e7ae refactor(LvModal): uses the right format for the date and adds padding to date numbers which are single digits 2024-11-07 13:14:40 +01:00
Andreas Österreicher f68d18f0a8 Stundenplan Bugfix to also load Entries of Semester and Verband 2024-11-07 10:25:42 +01:00
SimonGschnell 4f2992fbe2 fix(Cis profil menu): fixes the layout of the collapsible in the mobile view 2024-11-07 10:21:39 +01:00
Harald Bamberger 2b516d40c9 remove controllers, views and libraries for CisHtml since not used 2024-11-05 17:46:42 +01:00
Harald Bamberger 39cedfe6a0 remove controllers, views and libraries for CisHmvc since not used 2024-11-05 16:48:30 +01:00
SimonGschnell 8316290b31 fix(Cis Navbar Collapsibles): closes other colapsibles when opening another 2024-11-05 15:54:26 +01:00
SimonGschnell 7653bc3e29 fix(Menu User Dropdown): rearranges html elements to make dropdown scroll 2024-11-05 12:03:44 +01:00
SimonGschnell 37dffbba19 fix(Dashboard widget Url): adds validation method for both input fields and fixes confirm delete dialog 2024-11-05 11:32:02 +01:00
Harald Bamberger a9fe52d3c6 Merge branch 'feature-25999/C4_cleanup_merge_anrechnungen_bs5' into feature-25999/C4_cleanup 2024-11-05 07:59:21 +01:00
Harald Bamberger 20e0e2e910 Merge branch 'feature-25999/C4_cleanup' into feature-25999/C4_cleanup_merge_anrechnungen_bs5 2024-11-04 15:59:14 +01:00
Andreas Österreicher 835adca419 Debugging option entfernt 2024-11-04 15:42:47 +01:00
Harald Bamberger 50880c696b use getAuthUID function instead of get_uid, use new permission basis/cis and switch to Auth_Controller where possible 2024-11-04 15:41:02 +01:00
Harald Bamberger a65e94bc8a fix phrases variable name because of switch from mixin to plugin 2024-11-04 15:38:04 +01:00
Harald Bamberger 20715d6ef5 add permission basis/cis 2024-11-04 15:36:46 +01:00
Harald Bamberger c31cef349c add phrases from legacy code for news extra aside content 2024-11-04 15:35:35 +01:00
SimonGschnell 50a67a8e88 feature(Dashboard Bookmark): checks whether the link is a valid URL, displays fhcAlert otherwise 2024-11-04 14:37:09 +01:00
SimonGschnell eafbdcfffe refactor(Cis Menu): changes method name and checks if the CIS4_MENU_ENTRY constant is defined 2024-11-04 13:39:13 +01:00
ma0048 9c637b8575 - added model 2024-11-04 12:20:52 +01:00
SimonGschnell 86ee48888a fix(Cis Menu): adds Zahlungen to Mein Studium 2024-11-04 12:09:26 +01:00
SimonGschnell 9e45394deb fix(Cis MyLv): uses the moodle course bezeichnung for multiple moodle links 2024-11-04 12:09:12 +01:00
SimonGschnell ad068ffe5f different property name for the different moodle courses names 2024-11-04 09:07:35 +01:00
Harald Bamberger 93ac45308f Merge branch 'feature-36185/requestAnrechnung_bootstrap3_zu_bootstrap5' into feature-25999/C4_cleanup 2024-10-31 16:00:12 +01:00
SimonGschnell 34c6c63c74 Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-10-31 14:24:19 +01:00
SimonGschnell f820a0148a adapts the LV view to incorporate a dropdown if a lehrveranstaltung has multiple moodle links 2024-10-31 14:22:46 +01:00
Harald Bamberger e78c2e1bf7 Merge branch 'master' into feature-25999/C4_cleanup 2024-10-30 17:19:01 +01:00
Harald Bamberger d4f3fbfc79 Merge branch 'master' into feature-36185/requestAnrechnung_bootstrap3_zu_bootstrap5 2024-10-30 16:45:07 +01:00
SimonGschnell c5b81c22f9 adds the target for the lv menu in the studenplan modal and also replaces the tablesorter tables with tabulator5 in other content views 2024-10-30 11:31:39 +01:00
SimonGschnell 837cc191bf adds another link regex for the link string '../cms/content?content_id=...' and adds the library content to the CIS4 Menu content 2024-10-30 10:49:27 +01:00
Alexei Karpenko 9b4fb2ac2c bpk job: enabled getting vBPKs with new API version 0.8 2024-10-29 16:28:17 +01:00
SimonGschnell 6b991c514e refactors the room actions in the searchbar 2024-10-29 15:49:56 +01:00
SimonGschnell bdfea1763d adds gaps to the LvMenu 2024-10-29 15:38:10 +01:00
SimonGschnell 587a193a6b refactors the LvMenu Modal 2024-10-29 15:18:53 +01:00
Johann Hoffmann ec9e73180d primevue custom tooltip directive zIndex config retrieval fix; studentByLva tabulator height calc abort if no dataTable rendered; phrases fix; 2024-10-29 15:13:00 +01:00
SimonGschnell ff367339ea makes MyLv more responsive 2024-10-29 14:31:20 +01:00
Harald Bamberger ae80c3415d betraege im Gehaltsbestandteil als string mit . als komma konvertieren, um zu verhindern, dass locale spezifische Betraege in der verschluesselten DB Spalte gespeichert werden 2024-10-29 10:37:00 +01:00
Harald Bamberger 1e55b13546 force use of insertamum column from antrag table 2024-10-28 15:58:20 +01:00
SimonGschnell b9ccafe9db uses the cis.php file for the anrechnungen url 2024-10-28 15:57:33 +01:00
SimonGschnell 5f078a76c6 renders the right header (cis or fhtw) conditionally based on the CIS4 constant 2024-10-28 14:54:26 +01:00
SimonGschnell 3eb2100b3d Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-10-28 14:16:07 +01:00
SimonGschnell fbf0417269 only adds the Events file from addons which are actually active and refactors the Lv Information into its own component 2024-10-28 14:15:45 +01:00
SimonGschnell b801401d2b only shows the Week modus of the calendar if it is not a widget and opens the MyLV links as new tabs instead of showing them in the modal 2024-10-28 13:25:41 +01:00
Johann Hoffmann 46c4a30408 css fix & header file import remove 2024-10-28 11:36:49 +01:00
Johann Hoffmann 6fc5714fdf removed language flags; anw phrasen added; added names to apps for easier devtools debugging; 2024-10-25 16:34:57 +02:00
Johann Hoffmann 74cf0ad173 use vue header & tooltip translations 2024-10-25 15:58:37 +02:00
Johann Hoffmann e387671e09 added set language feature; phrasen plugin with optional reload if non responsive phrasen are used; stundenplan header mode & buttons reworked 2024-10-24 17:46:42 +02:00
Johann Hoffmann 32137479e9 activate email to assistenz on upload; redraw table in case of tabulator scroll bug; navigation.php $root var for Cis4 preperation 2024-10-24 15:07:08 +02:00
ma0048 e89beb610d - infocentermitarbeiter spalte deleted by user wird ignoriert 2024-10-23 13:33:50 +02:00
Johann Hoffmann 805ed20a18 Merge branch 'feature-52360/C4_fh_logo_remove_and_extend_searchbar_mobile' into feature-52734/C4_moodle_link_stpl_widget_stpl_mylva 2024-10-22 17:52:57 +02:00
Harald Bamberger c763e332d8 Merge branch 'feature-52735/C4_stundenplan_query_fix' into feature-25999/C4_cleanup 2024-10-21 17:16:21 +02:00
Johann Hoffmann f3851da10d add bootstrap class to only show fh logo in header on medium and greater displays; adjusted nav-user-btn css under mobile breakpoint to just take space of contained img and let searchbar flex growth apply to leftover width; 2024-10-21 16:02:54 +02:00
Johann Hoffmann 2e3bc855aa Merge branch 'feature-25999/C4_cleanup' into feature-52735/C4_stundenplan_query_fix 2024-10-21 13:51:21 +02:00
Johann Hoffmann 728e2f9b3a fix getStundenplanQuery query building if benutzer gruppen are empty; 2024-10-21 13:48:32 +02:00
Harald Bamberger 690080035a fix umlauts in variable name 2024-10-21 13:05:47 +02:00
Johann Hoffmann d8c4c6506a Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp 2024-10-21 10:21:42 +02:00
Harald Bamberger 9cd59a1250 add header version switch depending on CIS4 defined 2024-10-18 17:16:12 +02:00
Harald Bamberger 289c99a5a1 fix another 2 file permissions erroneously commited as a21a292da6 2024-10-18 17:03:40 +02:00
Harald Bamberger cf77a60b35 remove application/controllers/components/Antrag/* since not present in master any more 2024-10-18 16:57:03 +02:00
Harald Bamberger 0775fae67d remove unnecessary comment 2024-10-18 16:49:52 +02:00
Harald Bamberger 071b0c72dc Merge branch 'master' into feature-25999/C4_cleanup 2024-10-18 15:45:42 +02:00
Harald Bamberger 44b81d9dff Merge branch 'feature-25999/C4' into feature-25999/C4_cleanup 2024-10-18 15:44:39 +02:00
Johann Hoffmann 7ce426abc2 tooltip css fix; added missing phrase; 2024-10-18 15:14:13 +02:00
SimonGschnell 8ba370d3a7 makes the active menu punkt bold instead of underlined 2024-10-18 11:58:14 +02:00
SimonGschnell 59df85b05e adds Zeugnisse und Documents unter dem Mein Studium Menu Punkt 2024-10-18 11:55:20 +02:00
SimonGschnell 909b9f5f5a Merge branch 'feature-25999/C4' of github.com:FH-Complete/FHC-Core into feature-25999/C4 2024-10-18 11:19:18 +02:00
SimonGschnell 236c4bbdfc adds placeholders to the empty dashboard fields, that can be used to add new widgets to the dashboard 2024-10-18 11:18:36 +02:00
Harald Bamberger c80e943b3b readd erroneously deleted folder addons/template commited as 56080f6681 2024-10-17 15:55:05 +02:00
Harald Bamberger d4494836b1 fix file permissions erroneously commited as a21a292da6 2024-10-17 15:34:00 +02:00
Johann Hoffmann a04b2725f9 csv download lektor table as is; cis_menu_lv link hidden behind berechtigungen check; every tabulator now calculates remaining height by accessing window.visibleViewport.height and tabulator dataset element in order to get virtual DOM behaviour for faster rendering and better UX; filter component now emits uuid on created() lifecycle; 2024-10-17 15:04:03 +02:00
Harald Bamberger 0ab1ec1fc8 Merge branch 'master' into feature-25999/C4 2024-10-17 14:49:43 +02:00
SimonGschnell e475fe568e adds the dashboard menu punkt and adds greeting to the dashboard view 2024-10-17 09:58:28 +02:00
Harald Bamberger 14aa98c223 Merge branch 'master' into feature-25999/C4 2024-10-15 10:46:17 +02:00
Harald Bamberger e2cee7ffa3 Merge branch 'master' into feature-25999/C4 2024-10-15 10:44:56 +02:00
SimonGschnell 9ed08fb40c default value for hasConfig is false and the emit update for the URL dashboard widget and only loads the config component if the dashboard widget actually has a config 2024-10-14 13:36:31 +02:00
Alexei Karpenko 2893f2ec5a bugfix lvplan feedback link stpl_detail: correct html 2024-10-14 13:21:19 +02:00
SimonGschnell b0e96fbab1 replaces the emits to injections to avoid repassing the emits between intermediate parent elements 2024-10-14 11:42:30 +02:00
SimonGschnell 0528f3b262 checks the size of the arrays before using the current method and does not allow mitarbeiter to access the student stundenplan 2024-10-14 11:32:23 +02:00
SimonGschnell 462857080b makes the parent menu point active if the child menu points gets closed 2024-10-14 11:06:48 +02:00
Johann Hoffmann c67e78d135 phrasen rewording; formatter change; fix save changed anwesenheiten StudentByLvaComponent.js; 2024-10-14 10:42:49 +02:00
SimonGschnell 4f9591fc3b fix the z-index of the week stundenplan header 2024-10-14 10:36:46 +02:00
SimonGschnell c444e27d0d adds more styling and fixes little bug in the currentHour Stundenplan indicator 2024-10-14 10:34:01 +02:00
SimonGschnell ed1d4b1a50 regex replaces old content links with new CIS4 controller links and adopts the Menu Entry links to not refresh the page when closing the Menu point 2024-10-14 10:17:20 +02:00
SimonGschnell 9fd02460ce doesnt refresh the page when the menu entry gets closed, does redirect if the menu entry gets opened 2024-10-14 09:48:54 +02:00
Alexei Karpenko 1c61217891 lvplan: changed feedback phrase and Link 2024-10-13 13:34:07 +02:00
SimonGschnell f9e72832c9 adds time inidication on stundenplan on mouse position 2024-10-11 12:33:06 +02:00
SimonGschnell 5359539a09 makes Stundenplan query BLAZINGLY fast 2024-10-10 20:59:55 +02:00
SimonGschnell d2ed82cb37 calculates the total amout of hours with an array filter instead of statically inserting all hours 2024-10-10 13:27:26 +02:00
SimonGschnell f3fa2fa2dd adds the hour gutter for the stundenplan with absolute positioned divs instead of a linear gradient 2024-10-10 13:12:01 +02:00
SimonGschnell bf8085f642 starts the stundenplan from hour 7 instead of hour 0 2024-10-10 11:24:26 +02:00
Johann Hoffmann 9be5dc3f73 phrasen; tooltips; 2024-10-10 09:47:40 +02:00
SimonGschnell 4d50d4380b little bug fix 2024-10-08 13:54:58 +02:00
SimonGschnell 45ff067379 makes the url match to the Menu entries better 2024-10-08 13:47:48 +02:00
SimonGschnell ebebf8af6d changes calendar mode to button-group instead of select 2024-10-08 13:29:43 +02:00
SimonGschnell 79c8edc6cf makes the calendar week mode header align and highlights the week or day in the Month view depenedent if there is a week view available 2024-10-08 13:20:06 +02:00
Johann Hoffmann 008bbedd98 phrase 2024-10-07 16:22:27 +02:00
SimonGschnell e75872adaa lets the user change the view of the calendar in the header with a select and highlights the date fields to change the view of the current calendar 2024-10-07 14:49:02 +02:00
SimonGschnell 25a64cbcae fixes cis4 Menu for longest matching urls 2024-10-04 12:04:54 +02:00
Johann Hoffmann ef0e3f3a66 Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp 2024-10-03 11:24:48 +02:00
Johann Hoffmann ed6eb18c4d fetch termine from vw_stundenplan, not tbl_stundenplan; LE_ID DD chagned to refs (WIP MA_UID DD & Termin DD); removed console.logs(); fhcAlert fix; now find closest termin with absolute value of timeDiff; 2024-10-02 18:04:30 +02:00
SimonGschnell 8042f3ae0b makes the menu point active with the url matches 2024-10-02 14:22:34 +02:00
SimonGschnell e8f38bfcf6 sets the events to null before fetching the new events to reactivate the loading spinner 2024-10-02 13:28:18 +02:00
SimonGschnell 7f9352b820 prototyp fuer die Stundenplan query fuer Studierende 2024-10-02 13:25:39 +02:00
SimonGschnell c461480d1d stundenplanQuery optimization 2024-10-02 10:35:58 +02:00
SimonGschnell 567dd816be better descriptions for the cis4_root_menu sql queries 2024-10-01 13:54:53 +02:00
SimonGschnell 76facc40b9 changes the layout for the LvMenu to a flex instead of a grid 2024-10-01 12:14:34 +02:00
Johann Hoffmann ce058df3a5 Student Component Performance Fix (dont subquery person and anwesenheiten_user table on every anw_user row, just do the entschuldigung offen/abgelehnt logic in client before rendering); entschuldigung tab route; pagination on student entschuldigung page aswell; added config for einheiten länge to calculate/show; mitarbeiter selection in case of admin & lektor in same account behaving as expected; added index creation to initial sql scripts; 2024-09-30 17:25:51 +02:00
SimonGschnell 23b7d18906 gives the content_childs of the CIS4_ROOT the correct ordering 2024-09-30 14:24:48 +02:00
SimonGschnell fa8aec2c2e adds the MyLv and the Stundenplan Menupunkt to the sql inserts and changes the content for the Dokumente redirect 2024-09-30 14:13:00 +02:00
SimonGschnell 6f0f3890f9 doesnt show the footer in the editProfil modal when opening a ProfilUpdate 2024-09-30 13:43:26 +02:00
SimonGschnell 8f617c6222 fixes littel bug with the edit-profil modal in the StudentProfil 2024-09-30 13:20:14 +02:00
SimonGschnell f38b0cf78f changes all the Headers from the CISHTML-Header to the CISVUE-Header 2024-09-30 11:58:20 +02:00
SimonGschnell 964f6c689c removes debugging prints 2024-09-30 11:44:31 +02:00
SimonGschnell 4a5a019841 loads the menu for the CISVUE-Header in the server side and not in the client side 2024-09-30 11:33:55 +02:00
SimonGschnell 24a2b4ba2f fixes the bug where the Menu is still selected in the LvModal after clicking on the back button 2024-09-30 11:20:20 +02:00
SimonGschnell 8c6f9d1bc4 loads the menu for the CISVUE-Header in the server side instead of the client side 2024-09-30 11:14:34 +02:00
SimonGschnell 0e385e8628 makes the menu of the CISVUE-Header also sticky now 2024-09-30 10:30:11 +02:00
SimonGschnell bbed90c814 moves the searchbar from the mobile view to the top of the header 2024-09-30 10:26:23 +02:00
SimonGschnell c0596c08c5 changes the header for the Dashboard to the CISVUE-Header and passes the selectedTypes props to fix the CISVUE Header search 2024-09-30 09:43:26 +02:00
SimonGschnell d1070656ac CIS4 MENU sql update COMPLETE 2024-09-27 13:38:29 +02:00
SimonGschnell 23badc3404 CIS4 MENU sql update WIP 2024-09-27 12:20:37 +02:00
ma0048 0f708f4934 - added app pep
- phrases
- added error
- added model
2024-09-27 11:23:54 +02:00
SimonGschnell 73a2bf59f3 resolves buggs with the checkActiveUrl method 2024-09-27 10:44:09 +02:00
SimonGschnell bc6bc930fe moves the news titel to the component and adds css classes for darker dropdown buttons for the different menu levels 2024-09-26 12:05:44 +02:00
SimonGschnell b174818ed2 updates the active state of the menu based on the changed url 2024-09-25 15:02:35 +02:00
SimonGschnell b0a78658cf also makes the menu points active which redirect to an url hash 2024-09-25 13:35:41 +02:00
SimonGschnell a1fade0489 fixes the recursive function to find a child content_id 2024-09-25 12:25:19 +02:00
SimonGschnell 951d5bb2c7 all the parents of an active child are also active 2024-09-25 10:46:09 +02:00
SimonGschnell 3c050438b3 makes the dropdown button of the menu points darker to make them more visible 2024-09-25 09:26:08 +02:00
SimonGschnell 7ed7ce1bb9 active Menu Entry logic for CISVUE 2024-09-24 14:57:41 +02:00
SimonGschnell 470192aabd fixes some bugs in the View/Entry.php for the Menu 2024-09-23 15:14:31 +02:00
SimonGschnell 45d350a76e changes the header for the news and puts the LV title in the card header / removes the lines of the lehrveranstaltungs optionenen 2024-09-23 13:24:58 +02:00
SimonGschnell 98c85f1241 little changes to the view for the content 2024-09-20 14:20:44 +02:00
Johann Hoffmann a2e4704223 developing new components in lektor ui for ux improvements; anw function now explicitely in extension schema 2024-09-20 13:12:50 +02:00
SimonGschnell 9343d1ee0c refactor Content_types template 2024-09-20 11:26:08 +02:00
SimonGschnell ca4865011d adds missing parameters to the getContent function 2024-09-20 11:21:59 +02:00
SimonGschnell 693313a23b renames/reuses lv-modal and fixes bugs associated with the modal 2024-09-19 09:35:36 +02:00
SimonGschnell b9fd95741d moves the CalendarModal into the Stundenplan component instead of the Calendar component and changes the start_time and end_time computed properties 2024-09-18 14:40:58 +02:00
SimonGschnell 5877411db8 also loads the stundenplan data when the component is created 2024-09-18 13:52:49 +02:00
SimonGschnell f7b3af4939 makes the studiengang_semester reactive using computed when providing the value 2024-09-18 13:17:14 +02:00
SimonGschnell 164fc4b132 converts the dropdown of the lehrveranstaltungs optionen into a list inside the lv card 2024-09-18 12:52:55 +02:00
SimonGschnell 910a467fcc changes the stundenplan widget to use the new api endpoints that query the stundenplan events 2024-09-18 11:44:47 +02:00
SimonGschnell 6edc411a95 adds the LvMenu as dropdown options to the MyLV 2024-09-17 12:34:47 +02:00
SimonGschnell 5ca639101c fixes Month display of LVs 2024-09-17 11:39:39 +02:00
SimonGschnell d931aad11c solves reactive data problem in CalendarModal 2024-09-17 09:41:17 +02:00
SimonGschnell 61e6ad063a solves Telefon displaying as null for some benutzer 2024-09-17 09:28:11 +02:00
SimonGschnell e1c395146b refactors the LvMenu into its own component and removes debugging prints 2024-09-16 14:55:26 +02:00
SimonGschnell 4836ed8de0 adds LvMenu to the CalendarModel WIP 2024-09-13 13:44:53 +02:00
SimonGschnell b30156a65f catches errors better in Profil 2024-09-13 12:42:57 +02:00
SimonGschnell 88c38c9228 fixes ProfilUpdate bugs 2024-09-13 12:37:13 +02:00
SimonGschnell cf1cb44afa refactors old ProfilUpdate controller functions 2024-09-13 12:27:07 +02:00
SimonGschnell 2b9406b172 resolves zustellnungs value bug and removes debugging prints 2024-09-13 11:15:46 +02:00
SimonGschnell 29fac520f3 component was setting the topic false when trying to delete a kontakt or an adresse 2024-09-12 12:04:42 +02:00
SimonGschnell 1208c6829c when an error happenes to editProfil Modal will also be closed then 2024-09-12 11:53:13 +02:00
SimonGschnell 1de8c00990 fixes an error where the payload i treated like an object but is an associative array in the controller 2024-09-12 11:45:54 +02:00
SimonGschnell e247621f95 fixes the profilBearbeiten phrase and does update the topic correctly when adding a new kontakt/addresse in the profil 2024-09-12 10:47:31 +02:00
SimonGschnell cfea7e10f2 adds the reservierungen overview action for the search result with a room object and removes debugging prints 2024-09-11 14:51:52 +02:00
SimonGschnell 6cf3896d49 fixes Calendar.js 2024-09-11 14:38:00 +02:00
SimonGschnell cf4105dcb3 Merge branch 'feature-25999/C4_copy' into feature-25999/C4 2024-09-11 14:07:25 +02:00
SimonGschnell b79a3bd5e9 Merge branch 'master' into feature-25999/C4 2024-09-11 14:06:49 +02:00
SimonGschnell 04aaefd5d8 refetches the Stundenplan events also for the Stundenplan and not only for the roomplan 2024-09-11 14:00:53 +02:00
SimonGschnell aef267186f removes typo and debugging print from Calendar.js 2024-09-11 13:56:39 +02:00
SimonGschnell d80761d952 Merge branch 'feature-39912/Room_planning_calendar' into feature-25999/C4_copy 2024-09-11 13:54:45 +02:00
SimonGschnell 8860d9a598 adds quick fix for the query builder error that comes up when fetching content 2024-09-11 11:26:04 +02:00
SimonGschnell f2a57f85a8 fixes the errors with the stundenplan/reservierungen data query 2024-09-11 10:19:46 +02:00
SimonGschnell ac35ba3e27 puts the logic that adds the object informtion to the json reponse in the controllers instead of the models 2024-09-11 09:50:04 +02:00
SimonGschnell 1de658ace6 fixes the query for the reservierungen in the stundenplan and in the raum informations 2024-09-11 09:32:28 +02:00
SimonGschnell 715b8075b8 reworks the query for the reservierungen stundenplan/room 2024-09-10 12:30:40 +02:00
Johann Hoffmann 79d23a4557 Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp
# Conflicts:
#	public/js/components/Form/Upload/Dms.js
2024-09-10 11:25:19 +02:00
SimonGschnell 7b110aaf50 adds the needed phrase to the api/frontend/v1/Cms Controller 2024-09-09 14:16:37 +02:00
SimonGschnell 7a63301f08 puts profil settings ul outside of the sticky container 2024-09-09 13:49:38 +02:00
Harald Bamberger 5f50d9f0ec Merge branch 'feature-40311/Stundenplan_widget' into feature-25999/C4 2024-09-09 13:26:03 +02:00
SimonGschnell 26a0521379 fixes fhcapi 2024-09-09 13:12:11 +02:00
Harald Bamberger 996a49105b Merge branch 'feature-40309/Cis_News_widget' into feature-25999/C4 2024-09-09 13:03:47 +02:00
Harald Bamberger ff51d3964f Merge branch 'feature-40842/DashboardAmpeln' into feature-25999/C4 2024-09-09 12:56:55 +02:00
Harald Bamberger c2c30b86a1 Merge branch 'feature-40841/SearchBarChanges' into feature-25999/C4 2024-09-09 12:02:09 +02:00
Harald Bamberger 97b34d98fb Merge branch 'feature-41133/side_menu_sticky' into feature-25999/C4 2024-09-09 11:51:34 +02:00
Harald Bamberger 1f4628720a Merge branch 'feature-39911/Suche_um_raeume_erweitern' into feature-25999/C4 2024-09-09 11:50:27 +02:00
Harald Bamberger a8141e5dac Merge branch 'master' into feature-25999/C4 2024-09-09 11:45:10 +02:00
Johann Hoffmann 33122a0708 WIP performance testing & UI upgrades 2024-09-09 10:49:21 +02:00
SimonGschnell ec8b3ccb6f adds the organisations bezeichnung through a subquery to the lehrveranstaltungs events 2024-09-06 13:11:22 +02:00
SimonGschnell 122673d291 gets rid of the stunden dependency and uses the beginn and ende property of the queried events 2024-09-06 11:20:20 +02:00
SimonGschnell 8376e8b92d bundles the room_events and the reservierungen api calls together with Promise.allSettled 2024-09-06 11:02:14 +02:00
SimonGschnell f9b69fe08c changes how the reservierungen are fetched from the database to have the same information as the room events 2024-09-05 14:57:57 +02:00
SimonGschnell e33162d20e changes the structure of the JSON data from the stundenplan 2024-09-04 14:59:56 +02:00
SimonGschnell 87f82b7f5d also adds the stundenplan information as object in the response of the endpoint 2024-09-03 12:07:13 +02:00
SimonGschnell f19c1b4eaf adds the lector and the gruppe as objects to the endpoint result instead of just strings 2024-09-02 14:47:40 +02:00
SimonGschnell 8c5ca521ac adopts the side menu for the desktop and mobile view 2024-09-02 10:42:01 +02:00
ma0048 7dc7816123 - fas neuer filter ueberfaellige buchungen 2024-08-30 08:21:35 +02:00
SimonGschnell 3a466e8e0f puts nav-toggle and nav-menu-items in a sticky container 2024-08-13 15:27:51 +02:00
SimonGschnell 8bc8c67f8d better comments 2024-08-13 15:10:23 +02:00
SimonGschnell 36bd1795ed makes the cis4 side menu sticky 2024-08-13 15:04:44 +02:00
SimonGschnell cce58fdc31 removes debugging prints 2024-08-12 14:24:37 +02:00
Johann Hoffmann 8232224b21 LvMenu.php added codeigniter phrasen object to params; Using ci_phrases in Events.php for cis4 menu; 2024-08-12 14:20:42 +02:00
SimonGschnell 73dd89e5af adds phrasen library to LvMenu 2024-08-12 14:09:21 +02:00
SimonGschnell d7abc41137 adds digitaleAnwesenheiten menu point 2024-08-09 13:32:00 +02:00
ma0048 6f0575304c - ent/sperren mit hochkomma bug fixed 2024-08-09 11:54:01 +02:00
SimonGschnell ba2c450bd2 uses the codeigniter querybuilder to construct the active ampeln query 2024-08-07 15:43:20 +02:00
SimonGschnell 3f86961bda adds parameter to ampeln deadline/overdue phrase 2024-08-07 15:21:22 +02:00
cgfhtw 05e0d219f4 Codequality 2024-08-07 14:32:44 +02:00
cgfhtw 8b590dc58a optimizing Ampel Widget 2024-08-07 14:23:35 +02:00
SimonGschnell a6bef31862 corrects filter styling problem 2024-08-07 12:00:24 +02:00
cgfhtw e7a29dc21a Identation 2024-08-07 11:56:00 +02:00
SimonGschnell ceb8eb9671 corrects the way how to active ampeln check whether an ampel was bestaetigt or not and adds the Ampel_Benutzer_Bestaetigt_model 2024-08-07 11:52:50 +02:00
SimonGschnell 47a4b63172 changes the zustellungs warning for the Profil Adressen/Kontakte 2024-08-07 09:53:37 +02:00
SimonGschnell 46a0706057 updates roomEvents on change:range / groups the results of a studenplan query 2024-08-06 14:29:24 +02:00
SimonGschnell f0db878623 changes the headers from the news template from h5 to h2 but adds the bootstrap h5 class 2024-08-05 11:48:57 +02:00
SimonGschnell e44c1bccb3 adds shorthands with getDataOrTerminateWithError and adds also form_validation 2024-08-05 09:17:04 +02:00
SimonGschnell b350c9da56 refactors the news controller 2024-08-02 14:46:22 +02:00
SimonGschnell c5f57a0689 adds the bestaetigt property of the ampel when fetching all the active ampeln 2024-08-02 12:52:21 +02:00
SimonGschnell 3bb87ef8d3 corrects the translation of the ampel queries 2024-08-02 11:44:58 +02:00
SimonGschnell 4811f223b9 corrects little typo 2024-08-02 11:01:32 +02:00
SimonGschnell e6ba291549 adds the translation of the beschreibung and the buttontext in the Ampel_model and not in the Ampel controller 2024-08-02 11:00:11 +02:00
SimonGschnell 9e1bd2b64d adds form_validation 2024-08-02 10:36:34 +02:00
chfhtw fb6bca0ffb Merge pull request #46 from FH-Complete/feature-41134/bookmark_dashboardWidget
Feature 41134/bookmark dashboard widget
2024-08-02 09:59:51 +02:00
SimonGschnell 2de307682c convert identation to tabs 2024-08-02 09:26:39 +02:00
SimonGschnell 1d4f03e3f1 adds single phrase 2024-08-02 08:24:57 +02:00
SimonGschnell d4e33eb1df refactor 2024-08-01 15:04:18 +02:00
SimonGschnell 4317d5ebe9 tab spaces/ catch alerts 2024-08-01 14:16:20 +02:00
SimonGschnell 6fcc8cf7e8 code review changes 2024-08-01 11:49:14 +02:00
SimonGschnell bd7e45547f adds Phrasen to the Stundenplan dashboard widget 2024-07-31 14:51:43 +02:00
SimonGschnell 3641047963 adds bookmark phrasen and makes the data shared between the dashboard widget and the configuration view of the widget 2024-07-31 13:51:34 +02:00
cgfhtw cf440ffb43 Shared Data in Widget Component and Widget Config Component 2024-07-31 13:13:16 +02:00
SimonGschnell c2be0a4790 adds content to Url.js 2024-07-31 12:41:03 +02:00
SimonGschnell 8c84a63757 corrects how both the ampel and the ui phrasen are loaded 2024-07-31 09:40:50 +02:00
SimonGschnell 39574c1b3a adds delete endpoint for the dashboard bookmark widget 2024-07-30 15:27:24 +02:00
SimonGschnell 198b866268 adds fhcalert when confirming an ampel 2024-07-30 12:37:05 +02:00
SimonGschnell 02cf36c17c adds Phrasen to the dashboard ampel-widget 2024-07-30 12:25:26 +02:00
SimonGschnell 284cf711fd adds the sql scripts to create dashboard.tbl_bookmark and dashboard.tbl_bookmark_sequence 2024-07-30 11:26:22 +02:00
SimonGschnell f4210e7671 fixes the Vue component layout for the ampeln dashboardwidget 2024-07-29 13:44:17 +02:00
SimonGschnell 2c45478877 fixes the fetched ampeln in the ampelWidget 2024-07-29 13:17:29 +02:00
SimonGschnell 65b71191a0 adds +1 to month in getMonth() function because the month index of a javascript date starts with 0, additional cleanup in Ampel.js Widgett 2024-07-26 15:41:21 +02:00
SimonGschnell fb30a8e009 translates the ampel queries in separate private function 2024-07-26 14:07:56 +02:00
SimonGschnell ca6e3a8463 adds endpoint to query all user ampeln that were assigned after the start_working_date with the appropriate beschreibungs translations 2024-07-25 15:16:01 +02:00
SimonGschnell 0849e795a0 also adds the horizontal line under the heading 2024-07-24 14:59:02 +02:00
SimonGschnell 012cbe9a25 pulls the header out of the content div which makes the headings smaller in the content view with a specific css 2024-07-24 14:57:11 +02:00
SimonGschnell e9d45b6532 removes the old way a modal was shown in the news widget of the dashboard 2024-07-24 14:51:04 +02:00
SimonGschnell 94df440f88 adds a heading to the Content and the News View again 2024-07-24 14:49:58 +02:00
SimonGschnell 4e929f4cce Merge branch 'feature-25999/C4' into feature-40309/Cis_News_widget 2024-07-24 14:40:15 +02:00
SimonGschnell 563f5e5f9e merging C4 2024-07-24 14:37:16 +02:00
SimonGschnell 1e3146d33f dashboardAmpeln 2024-07-24 13:31:00 +02:00
SimonGschnell 4b0878b248 Merge branch 'master' into feature-39911/Suche_um_raeume_erweitern 2024-07-24 13:00:52 +02:00
SimonGschnell 1211d63ccf adds placeholders for the ampeln and adds new endpoints that fetch activeAmpeln and confirmedActiveAmpeln of the user 2024-07-23 13:59:04 +02:00
SimonGschnell 7e983292ea adds the endpoint that fetches all ampeln of a user that are not confirmed by the user yet and also removes some unnecessary comments from other enpoints 2024-07-23 11:26:52 +02:00
SimonGschnell 2083e95f8c adds vertical layout for the documents view when the viewport is less than lg 2024-07-23 09:14:38 +02:00
SimonGschnell f207419859 removes the import for userdata and profilUpdate from the old fhcapi which should be replaced by the new fhcapi 2024-07-23 08:58:52 +02:00
SimonGschnell e613ac3255 computes the childactions for the room in the search result independently 2024-07-22 14:33:19 +02:00
SimonGschnell 9170653260 adds a childaction for the rooms when searching for a room to see the eventoverview of the room 2024-07-22 14:07:00 +02:00
SimonGschnell f4bf3eec86 merging feature-39911/Suche_um_raeume_erweitern 2024-07-22 12:55:01 +02:00
SimonGschnell 82417a7f6f removes old api files and removes the use(fhcApi) because it is already imported in the Phrasen plugin 2024-07-22 11:36:12 +02:00
SimonGschnell a0871657ca adds insertFile to the new ProfilUpdate FhcAPIController and starts a transaction when deleting the foreign key from the profil update and deleting the old file 2024-07-22 11:24:47 +02:00
SimonGschnell 0cc6222175 adds deleteProfilRequest to the new ProfilUpdate FhcAPIController 2024-07-19 14:57:42 +02:00
SimonGschnell 8700abd0fa adds updateProfilRequest to the new ProfilUpdate FhcAPIController 2024-07-19 14:50:00 +02:00
SimonGschnell 12626511e9 adds insertProfilRequest to the new ProfilUpdate FhcAPIController 2024-07-19 14:00:40 +02:00
SimonGschnell a06f9b581f adds selectProfilRequest to the new ProfilUpdate FhcAPIController 2024-07-19 13:11:58 +02:00
SimonGschnell be66150631 adds acceptProfilRequest and denyProfilRequest to the new ProfilUpdate FhcAPIController 2024-07-19 11:38:15 +02:00
SimonGschnell 9eb61649eb adds getProfilRequestFiles to the new ProfilUpdate FhcAPIController 2024-07-19 09:06:49 +02:00
SimonGschnell ddd4d5bafe parses the links in the moodle addon dynamically, so that other addons can easily override the phrase used for the links 2024-07-18 14:03:15 +02:00
SimonGschnell 2711113a69 solves column title race condition 2024-07-18 11:43:08 +02:00
SimonGschnell 328a46f16d adds getTopic to the new ProfilUpdate FhcAPIController 2024-07-18 10:40:30 +02:00
SimonGschnell 885315c22b adds getStatus to the new ProfilUpdate FhcAPIController 2024-07-18 09:52:08 +02:00
SimonGschnell 29aa7f5056 adds isMitarbeiter to the new Profil FhcAPIController 2024-07-18 09:36:30 +02:00
SimonGschnell fdd3026212 adds getAllNationen to the new Profil FhcAPIController 2024-07-18 08:53:45 +02:00
SimonGschnell da8bb697df change url of Gesamtnote Menu Punkt 2024-07-16 15:42:42 +02:00
SimonGschnell 3417dcd41d centers the text, displays default message and makes # links not clickable and removes the link styling from them 2024-07-16 15:18:23 +02:00
Johann Hoffmann 630d2659b3 extension/anwesenheit_assistenz -> extension/anw_ent_admin; removed hardocoded status; check for overlapping excuse timespans; and a lot more ;) 2024-07-15 17:38:13 +02:00
SimonGschnell 14df81cbfb adds c4_linkList and additional styling to the LvUebersicht Menu 2024-07-12 16:14:20 +02:00
SimonGschnell 1614771150 loads content of the menu punkte in iframe inside a full-screen modal 2024-07-12 13:17:44 +02:00
ma0048 c94f185308 - faktor für lvs hinzugefuegt 2024-07-10 15:13:46 +02:00
SimonGschnell a83e07350e makes the pinboard link redirect to all news 2024-07-10 11:35:36 +02:00
SimonGschnell d364630d92 instead of modifying the original menu keys, it adds new keys for the cis4 version of the menu 2024-07-10 10:48:24 +02:00
SimonGschnell bc9f247323 replaces wrong quatations in the menu items if the link_onclick array key is defined 2024-07-10 09:10:35 +02:00
SimonGschnell 56080f6681 changes the LVUebersicht and the endpoint 2024-07-09 15:28:28 +02:00
SimonGschnell 8a44a9e1af passes the menu as a reference to the on Events instead of using a callback function 2024-07-09 10:37:43 +02:00
SimonGschnell 84029fc729 updates editAdressen in the Profil 2024-07-08 15:15:08 +02:00
Johann Hoffmann 66b151dce0 Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp
# Conflicts:
#	system/dbupdate_3.4.php
#	system/phrasesupdate.php
2024-07-08 14:42:01 +02:00
SimonGschnell 0347f8bf02 filters the menu to remove all elements that don't have the position property 2024-07-08 11:43:48 +02:00
SimonGschnell e98f59e984 adds all menu punkte from fh-core to the LvMenu endpoint function 2024-07-08 10:54:39 +02:00
SimonGschnell 578afaeb08 adds fh-core menu logic WIP 2024-07-05 15:21:14 +02:00
SimonGschnell 08555a77be makes contentModal bigger for the room content and uses the raum_info component to insert the tabulator in the content 2024-07-05 10:00:54 +02:00
SimonGschnell 79ffc1c077 creating lvMenu with Event hooks WIP 2024-07-04 15:37:50 +02:00
SimonGschnell 92afdf71cd changing fhcapi for the client side for the profil WIP 2024-07-03 15:53:01 +02:00
SimonGschnell 2a7735bca5 outsources internal queryies to the appropriate classes, to assign the values to the needed variables to fill the menu array of the menu_lv.inc.php 2024-07-03 11:56:18 +02:00
Johann Hoffmann affbe7821a email vorlagen sql insert; trim entschuldigungs begründung to max size; WIP routing; WIP fancy loader overlay; WIP Api Testing; lektor ui finetuning; 2024-07-02 16:51:42 +02:00
SimonGschnell 19753a9ef7 test api endpoint to include the lvinfo menu link 2024-07-02 14:50:54 +02:00
SimonGschnell 57d3d3af13 removes the shared storage for the searchbar and saves the data local in the searchbar again 2024-07-02 10:28:35 +02:00
SimonGschnell 3d2ea2821e fixes little typo, that fails to render the widget 2024-07-02 09:26:19 +02:00
SimonGschnell ff0f2320e1 changes the layout of the searchbar to be the same in the mobile view and in the desktop view 2024-07-01 14:43:43 +02:00
SimonGschnell f4f08c0710 stores the local information of the searchbar inside a collected storage in case more than one searchbar is used 2024-07-01 13:53:55 +02:00
SimonGschnell 3e3f005525 changes the layout/buttons of the searchbarsettings, adds responsive searchbar in the header for mobile views 2024-06-28 14:34:41 +02:00
SimonGschnell d0f457d8ed changes the data format from the studierendenEmail api call and displays the mailto on the modal 2024-06-28 11:06:44 +02:00
SimonGschnell c34144a4e8 creates sql query in the lehreinheit_model to query the studierenden Mail inside a lehrveranstaltung and creates the matching fhcapi methods / frontend/v1 api controllers 2024-06-27 15:09:09 +02:00
SimonGschnell ffc1241188 news widget 'alle News' redirects to the news URI 2024-06-27 11:53:22 +02:00
SimonGschnell 5070353bf0 passes the active_addons constant to the LvUebersicht Modal 2024-06-26 16:37:54 +02:00
SimonGschnell a540ac3f7e adds a General view for the content_types that dont need any special extra computation 2024-06-26 15:58:50 +02:00
Johann Hoffmann 1305633511 removed 99% of console.logs; fixed entschuldigung update notiz only; added kontrolleDeleteMaxReach Constant from config; updateAnwesenheiten notiz fix; Entschuldigungs studiengang fetch fix; 2024-06-26 15:38:22 +02:00
SimonGschnell 93b7f6e57c fixes little typo 2024-06-26 15:20:19 +02:00
SimonGschnell 4640db5aff adds a view components for the news if the content that gets loaded has the template_kurzbz news 2024-06-26 14:17:44 +02:00
SimonGschnell 478adb740e changes the db query and adopts the layout of the Vue component to show the correct betreff and content of the news 2024-06-26 13:21:32 +02:00
SimonGschnell f546554f87 changes the layout of the news widget in the dashboard 2024-06-25 16:48:05 +02:00
SimonGschnell f4176ebcda adds the content of the news to the dashboard items and makes them scrollable through css classes 2024-06-25 14:18:11 +02:00
Johann Hoffmann dd044b9146 entschuldigungen reload fix; student anw group header toggle fix; scan error msg fix; delete modal with kontrolle selection; scan code route renamed to profile/scan from student/scan; fixed sum formatting; 2024-06-24 16:35:48 +02:00
SimonGschnell 27287bd07a creating the api endpoint that fetches the content of the news instead of text metdata 2024-06-24 16:05:51 +02:00
SimonGschnell 7267d526bb rendering content pages 2024-06-24 14:23:34 +02:00
SimonGschnell f8c431e0bc updating comment of the content function 2024-06-24 14:23:34 +02:00
SimonGschnell 629ea3716e changes how the content and the news are displayed and also modifies the modals for the roominformation which now get their data from props instead of passing them directly via refs 2024-06-24 14:23:34 +02:00
SimonGschnell 6230aa47ae now also displays the room information inside a modal and does not redirect to the content site 2024-06-24 14:23:34 +02:00
SimonGschnell b3dfcdc295 the calendar modal is correctly opened when the correct event is called 2024-06-24 14:23:34 +02:00
SimonGschnell bb9d4bda04 adds a general modal for the lehrveranstaltungs Uebersicht with all the links connected to the lehrveranstaltung 2024-06-24 14:23:34 +02:00
SimonGschnell d92ad0a6c6 links the ort_kurzbz from the Stundenplan in the Dashboard to the Ort Information Content 2024-06-24 14:23:34 +02:00
SimonGschnell 63f089dc27 changes the layout of the Stundenplan Events 2024-06-24 13:50:13 +02:00
SimonGschnell 77cd3bb02d removes the z-index from the calendar header so that it doesn't show over the menu when used in mobil view 2024-06-24 13:11:55 +02:00
SimonGschnell 008847e490 adds a sql query for the grouping algorithm 2024-06-24 13:08:44 +02:00
Johann Hoffmann 570798b5f7 landing page is now container for tabs or single component directly; WIP reworking lektor UI; 2024-06-24 10:51:23 +02:00
Johann Hoffmann b4b44d9a89 added entschuldigung & anw_user notizen; entschukldigung notizen working; WIP anw notizen; api fixes entschuldigung; LE for LVA fetch now disregarding stundenplan; Paths renamed to new controller names; 2024-06-18 14:15:35 +02:00
Johann Hoffmann 473815639b added entschuldigung max reach constant; rewrote SQL queries from string insert to param escaping; removed Stundenplan Lookup from LE for LVA fetch; load LE Stundenplan termine and serve as option when starting new kontrolle. 2024-06-17 17:39:56 +02:00
SimonGschnell a0472c6573 little changes 2024-06-14 14:44:29 +02:00
SimonGschnell f83cd3b87a checks whether the user wants to fetch content or the news 2024-06-14 11:18:29 +02:00
SimonGschnell dd7c8480f3 removes unwanted methods and properties from CalendarModal 2024-06-13 12:29:36 +02:00
SimonGschnell de4accab83 cleans up the Stundenplan grouping algorithm 2024-06-13 12:27:09 +02:00
SimonGschnell d1afd9f09d groups the uids of the reservierungen in the raum uebersicht and renders different template if the calender entry is a reservierung or a stundenplan event 2024-06-12 14:42:30 +02:00
SimonGschnell 9c51f25c9e modifies how the slot template from the Calendar Page is passed to the CalendarApp and prints the reservierungen differently (but the reservierungen are not grouped yet) 2024-06-11 15:03:09 +02:00
Johann Hoffmann e7e5d76531 fhcapi use factory merge 2024-06-10 17:23:37 +02:00
Johann Hoffmann 52a55a018c merge fix 2024-06-10 15:13:30 +02:00
Johann Hoffmann aa1d70f8f0 fix 2024-06-10 13:35:06 +02:00
Johann Hoffmann 9350e9230f API refactor 2024-06-10 13:30:44 +02:00
SimonGschnell 022ad26dd2 reservierungen query also joins the studiengangs and mitarbeiter information 2024-06-10 13:01:55 +02:00
SimonGschnell 392d8f38d2 adding the reservierungen to the room plannung 2024-06-10 11:39:16 +02:00
SimonGschnell 8442690bc7 splits the multiple stg into different rows if there are more than one stg in one lv 2024-06-10 10:56:12 +02:00
SimonGschnell 70b0b3fae7 MVP algorithm for stundenplan gruppierung (testing) 2024-06-07 15:06:28 +02:00
Johann Hoffmann 068aa03b4f Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp 2024-06-06 11:02:56 +02:00
SimonGschnell 25d284389a gruppieren algorithm erweitern 2024-06-06 09:25:46 +02:00
SimonGschnell 1a5d270936 calendarDate preparation 2024-06-04 15:00:41 +02:00
SimonGschnell 3df1aaf371 uses the new fhcApi factory to make the roomInformation get request from the frontent/v1/stundenplan api and uses the CalendarDate class to get the first day of the week and the last day of the week to make the request for the room information over the whole week 2024-06-04 08:24:58 +02:00
Harald Bamberger 7491b9c1b0 try to fix mobile dashboard view 2024-06-03 11:35:11 +02:00
Harald Bamberger 204de30459 make news modal more responsive 2024-06-03 10:46:26 +02:00
Harald Bamberger 92319b9b29 quick fix for overlapping dashboard elements on mobile phones 2024-06-03 10:27:03 +02:00
SimonGschnell 39321dcde3 adds the roomInformation Calendar to the menu and uses different template for the calendar page slot 2024-05-31 12:28:06 +02:00
SimonGschnell b9bd8e1d4d Merge branch 'feature-25999/C4' into feature-39912/Room_planning_calendar 2024-05-31 08:53:40 +02:00
SimonGschnell 5021c47c9f calendar style changes 2024-05-27 12:20:58 +02:00
SimonGschnell 87681351b9 Merge branch 'feature-25999/C4' into feature-39912/Room_planning_calendar 2024-05-27 10:55:44 +02:00
SimonGschnell 16f90604b6 stundenplan modal for LVs and making calendar header sticky 2024-05-24 11:17:06 +02:00
SimonGschnell 234ec03db9 adds the phrase noGrade 2024-05-24 09:37:07 +02:00
Johann Hoffmann 0536ff0044 load person_id & uid for students to navigate them with admin view; WIP studentDropdown selection; WIP changing studentComponent to work with different permissions; 2024-05-23 16:49:53 +02:00
SimonGschnell 729509a45d WIP 2024-05-23 15:40:23 +02:00
SimonGschnell 12b2f3ab07 adding more information to the cis40 stundenplan 2024-05-23 15:39:31 +02:00
Alexei Karpenko 854d836e30 Abschlussprüfungsprotokolle: added link in FAS to read-only form 2024-05-23 13:56:18 +02:00
SimonGschnell 25deb0a440 takes the value of the node not just the node 2024-05-23 13:01:18 +02:00
SimonGschnell cef41f3710 fixes html, one closing div to much 2024-05-23 12:44:12 +02:00
Johann Hoffmann 59a1e84fb2 Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp
# Conflicts:
#	public/js/components/filter/Filter.js
#	public/js/plugin/FhcApi.js
#	system/dbupdate_3.4.php
2024-05-22 15:42:19 +02:00
SimonGschnell 186e9e6f08 WIP room planning in calendar 2024-05-21 15:56:18 +02:00
SimonGschnell c566d07847 fixes little xml layout issue 2024-05-21 13:34:58 +02:00
SimonGschnell 48bb2ef7e1 adds the insert query for the new raum template and the update statement to update the template for every room content 2024-05-21 11:05:22 +02:00
SimonGschnell 393475e62c adds the content update script for the room content to the checksystem 2024-05-21 10:49:27 +02:00
SimonGschnell d07c568d5e adds dbupdate queryies for the new raum template 2024-05-21 10:37:53 +02:00
Johann Hoffmann 7530a74ff3 demo stand gf; 2024-05-16 16:39:54 +02:00
SimonGschnell c7e01bd3f2 creates the sql query with the needed room information to be displayed in the search 2024-05-15 14:37:18 +02:00
SimonGschnell 56e6efe416 WIP sql query for the raum search 2024-05-14 15:57:48 +02:00
SimonGschnell 841e3b0390 raum query 2024-05-14 14:21:52 +02:00
Harald Bamberger b3c6127cfe Merge branch 'feature-25999/C4_TEST' into feature-25999/C4 2024-05-14 14:01:24 +02:00
Johann Hoffmann 3b762c8065 getStudentsForLvaInSemester data query; getLektorIsTeachingLE veryfication query; getLektorenForLvaInSemester selection query; moved setup from app to landing page, landing page thus unskippable; now checking qr code age in check in; charts smaller size now; more phrasen; lektor tabulator height fix; ma uid selection of lektors for admin and assistenz; tested and implemented QRDelete Cronjob; 2024-05-13 16:01:26 +02:00
SimonGschnell fd8e49c11f hotfix in Modal.js 2024-05-08 14:35:41 +02:00
SimonGschnell 6fa5ff81d6 Merge branch 'feature-25999/task-39464' into feature-25999/C4_TEST 2024-05-08 12:01:53 +02:00
SimonGschnell 0942480428 adds the missing model for the function 2024-05-08 11:58:35 +02:00
SimonGschnell 2fd2746a74 Merge branch 'feature-25999/task-39464' of github.com:FH-Complete/FHC-Core into feature-25999/task-39464 2024-05-08 11:56:50 +02:00
SimonGschnell 8e2129902c Merge branch 'feature-25999/task-39464' into feature-25999/C4_TEST 2024-05-08 11:29:39 +02:00
SimonGschnell d0509abb8b also adds the new controller functions to the CisVue/Cms and CisHmvc/Cms 2024-05-08 11:28:16 +02:00
SimonGschnell c2a782e164 updates news fetching and DB_Model pagination methods 2024-05-08 11:28:16 +02:00
SimonGschnell 5ac0b249ec makes component Pagination page_size prop a required prop 2024-05-08 11:28:16 +02:00
SimonGschnell 5142f5656b passes the page_size down from the parent component to the child component 2024-05-08 11:28:16 +02:00
SimonGschnell 7bd70a6436 makes it possible to send the page_size from the frontend to the backend to adopt how many rows to query 2024-05-08 11:28:16 +02:00
SimonGschnell c017014171 changes how the pagination is done in the DB_Model 2024-05-08 11:28:16 +02:00
SimonGschnell 36c8862b99 implementing frontend pagination for components 2024-05-08 11:28:16 +02:00
SimonGschnell 29f7e34e10 adds pagination logic to C4 news 2024-05-08 11:28:16 +02:00
SimonGschnell 730db74743 Merge branch 'feature-25999/C4_ma0594_profilePage' into feature-25999/C4_TEST 2024-05-08 11:14:41 +02:00
SimonGschnell d1207ced02 Merge branch 'master' into feature-25999/C4_TEST 2024-05-08 11:06:34 +02:00
SimonGschnell fb6bb96fbd making Filter-core-cmp emit the tableBuilt event 2024-05-08 10:58:38 +02:00
SimonGschnell 9db09a040a Merge branch 'master' into feature-25999/C4_ma0594_profilePage 2024-05-08 09:58:18 +02:00
SimonGschnell a563f053ef adds the width and the height properties to the dashboard item, they were missing and caused a bug where the news widget was not displaying correctly 2024-05-06 14:19:04 +02:00
Johann Hoffmann 3846f38a6f added PK to tbl_anwesenheit_check; chenged anwesenheiten sum function to account for timespans of the checks; added extension/anwesenheit_admin berechtigung; fotos are now being sent as links to bild.php; studentByLva table now with von & bis times of the check; now updating attendance check times when starting further checks on the same date; checking if time the code is being sent is in the timespan of the kontrolle; added method to delete QR codes older than certain ms to be called from QRDelete Cronjob; 2024-05-06 11:21:01 +02:00
SimonGschnell efcebb567f responsive adjustments 2024-05-03 10:46:20 +02:00
SimonGschnell e6ad3b3168 adjust responsiveness of createAnrechnung.php 2024-05-03 10:35:46 +02:00
SimonGschnell f9058b954e adjusting the responsive layout for approveAnrechnungDetail view 2024-05-03 10:31:53 +02:00
SimonGschnell 4aa8807830 adds responsiveness for the view approveAnrechnungUebersicht 2024-05-03 09:48:18 +02:00
SimonGschnell 9975f767b8 adds responsiveness to reviewAnrechnungDetail.php 2024-05-02 12:15:57 +02:00
SimonGschnell 0b58d4fd6f also adds the programmatically unselectable logic to the reject button 2024-05-02 11:43:19 +02:00
SimonGschnell bcafb6cea6 removes unnecessary function call from reviewAnrechnungUebersicht.js 2024-05-02 11:30:38 +02:00
SimonGschnell 6ea802717b adds pointer-events none to all rows with the class .tabulator-unselectable except for the links inside those rows, because it was not possible to programmatically retrigger the selectableCheck 2024-05-02 11:14:12 +02:00
Johann Hoffmann 2c08a482e3 finished phrasen in backend; setup component is no a modal in landing page and only for lektors with multiple LE assigned in an lva; assistenz skips landing page; tabulator formatting fixes; getAllAnwesenheitenByLektor now fetches students and their anwesenheiten entries seperately which is significantly faster; 2024-05-02 09:29:50 +02:00
SimonGschnell 10bfb6c9e8 also fixes the isSelectable bug when rejecting a anrechnung in the approveAnrechnungenUebersicht view 2024-04-30 15:03:30 +02:00
SimonGschnell 86d3042cc6 makes the rows that were recently selected unselectable and adds the correct styling in the approveAnrechnungUebersicht view 2024-04-30 14:18:22 +02:00
SimonGschnell ac0103751d adds a border to the tableWidget and also adds a function that finds the tableunqiueid using the tableInstance 2024-04-30 09:48:08 +02:00
SimonGschnell 20a2e369c5 adds new button to show all new and changed lehrauftraege in the orderLehrauftrag view, so that the user can set the initial filter himself 2024-04-29 15:53:56 +02:00
SimonGschnell 555db0d5af fixes the selection of the tableUniqueID 2024-04-29 11:45:08 +02:00
SimonGschnell b0d31361c1 updates fontawesome version 2024-04-29 11:38:03 +02:00
SimonGschnell 8cf63f3b76 replaces the icons images with actual icons from the fontawesome6 library 2024-04-29 11:34:18 +02:00
SimonGschnell ffe4fcb0b3 removes the cis styles from the admin views 2024-04-26 14:43:56 +02:00
SimonGschnell dec6b160a6 fixes the acceptLehrauftrag view with bootstrap5 and tabulator5 2024-04-26 14:07:24 +02:00
SimonGschnell e4f1da751d migrating the acceptLehrauftrags view to bootstrap 5 2024-04-25 15:19:24 +02:00
SimonGschnell 88fd26d192 Merge branch 'master' into feature-36185/requestAnrechnung_bootstrap3_zu_bootstrap5 2024-04-25 14:35:50 +02:00
SimonGschnell 580b6239c2 remove the body tag from all views that use the FHC-Header view 2024-04-25 14:35:06 +02:00
SimonGschnell b7ffe00c69 sets the height of the adminZeitverfuegbarkeit to 50% of the screen ehight 2024-04-25 14:16:28 +02:00
SimonGschnell d01b05fd73 edit anrechnungszeitfenster does actually edit and not insert a new anrechnungszeitfenster 2024-04-25 13:30:32 +02:00
SimonGschnell deb0197452 fixes the adminAnrechnungen page 2024-04-25 13:13:24 +02:00
SimonGschnell fed30daad0 bug fix, only appending the event to the accept and deny action button if they were actually created 2024-04-25 09:41:32 +02:00
SimonGschnell a2e943ac40 adjusts the actions of the ProfilUpdateView table with accept and deny buttons 2024-04-25 09:29:47 +02:00
Johann Hoffmann f5d534a409 added require branch update file in dbupdate_3.4.php; added phrasen everywhere in frontend, WIP translating backend messages; 2024-04-24 15:52:53 +02:00
SimonGschnell cea06994de fixes the bug with the columnDefault tooltips that was inside the TableWidget.js file 2024-04-24 14:59:46 +02:00
SimonGschnell 5a62dbc740 refactors the adminAnrechnung page because it is used in an bootstrap3 environment 2024-04-24 11:35:02 +02:00
SimonGschnell 7dfe2f1932 tabulator5 function changes 2024-04-24 10:00:12 +02:00
Johann Hoffmann 633b9eeafe loading STG permissions for assistenz into frontend and only fetching entschuldigungsdata for those; new data fetch api methods for lektor to visualize graphs: getAllByLva & getAllByStudiengang. old one renamed to getAllByLvaAssigned; automatic email to responsible adress on entschuldigung upload of a student; focused on pie charts for reusable landing page design; fixed entschuldigungen date filter validation; WIP extension specific phrases; 2024-04-23 17:00:32 +02:00
SimonGschnell 96b79c8740 corrects reviewAnrechnungDetail style typo, and adds the height function to the adminAnrechnung table again 2024-04-23 13:43:00 +02:00
SimonGschnell bebec98285 adds a little space with a br between the tablewidget header and the table itself 2024-04-23 13:16:04 +02:00
SimonGschnell 8d68faf922 replaces the pull-right class with a conditional if bootstrapVersion was set to 5 2024-04-23 13:06:02 +02:00
SimonGschnell 9ae36b54e1 remove the 50% height from the table and add fitColumns to the table so that the columns take the whole available space 2024-04-23 12:55:44 +02:00
SimonGschnell 11c9622186 replaces the anrechnungen.css with styles in the zeitverfuegbarkeit view 2024-04-23 12:50:29 +02:00
SimonGschnell 3a1ac15740 adds the button width and margin classes from the Tabulator.css (used in Tabulator4) to the anrechnungen.css file 2024-04-23 12:47:17 +02:00
SimonGschnell 51ee16926c adds a tabulator redraw when adding the details column to the tableWidget 2024-04-23 09:49:41 +02:00
SimonGschnell e1fac8e871 adds the bootstrapVersion flag to all the TableWidgetData files 2024-04-22 17:11:02 +02:00
SimonGschnell 977c2d4432 Merge branch 'master' into feature-36185/requestAnrechnung_bootstrap3_zu_bootstrap5 2024-04-22 15:18:19 +02:00
SimonGschnell 258c5f7777 Merge branch 'master' into feature-36185/requestAnrechnung_bootstrap3_zu_bootstrap5 2024-04-22 14:56:07 +02:00
SimonGschnell e2e7966f83 adds accept and deny actions in the actions column of the ProfilUpdateView component 2024-04-22 14:55:37 +02:00
SimonGschnell 349865b8fb fixes the phrasen for the column titles of the ProfilUpdateView 2024-04-22 13:52:38 +02:00
SimonGschnell 27428b15bb changes the escaping string for the xslt_xhtml_c4 2024-04-22 11:49:19 +02:00
Harald Bamberger 93ae5577f8 try with here documents 2024-04-22 11:25:24 +02:00
SimonGschnell 1447a930d3 adds more phrasen to the profil and the profilUpdate views, headers of tables phrasen 2024-04-19 14:24:32 +02:00
SimonGschnell 4bb9c61168 also fixes the phrasen for the student/Mitarbeiter View Ansicht 2024-04-18 15:06:38 +02:00
SimonGschnell bc0d581402 fixes phrasen in the studentProfil 2024-04-18 15:00:28 +02:00
SimonGschnell 4e5379c5d9 adds an edit button over every section in the profil page to edit that section 2024-04-18 14:53:51 +02:00
SimonGschnell cc0ea44de3 also adds the new controller functions to the CisVue/Cms and CisHmvc/Cms 2024-04-18 11:56:55 +02:00
SimonGschnell 3993d614d4 updates news fetching and DB_Model pagination methods 2024-04-18 11:52:58 +02:00
SimonGschnell 71f63095c2 makes component Pagination page_size prop a required prop 2024-04-17 15:15:51 +02:00
SimonGschnell 92f2c6e0a2 passes the page_size down from the parent component to the child component 2024-04-17 15:12:55 +02:00
SimonGschnell 284ae0637e makes it possible to send the page_size from the frontend to the backend to adopt how many rows to query 2024-04-17 14:54:22 +02:00
SimonGschnell 6c642f1242 changes how the pagination is done in the DB_Model 2024-04-17 14:23:09 +02:00
SimonGschnell d77499b73b implementing frontend pagination for components 2024-04-15 13:35:33 +02:00
Johann Hoffmann 563e7bebc0 setupComponent currently uses globalProperties as model for le selection; lektorComponent uses globalProperties for le_id; le_selection now has sophisticated info String detailing every group associated with le for lektor; WIP assistenz filter setup; WIP checking in router guard for missing le_id when they have not loaded yet; 2024-04-12 15:01:37 +02:00
SimonGschnell ad956bef8e adds pagination logic to C4 news 2024-04-12 14:38:01 +02:00
SimonGschnell ea9bd93e73 phrasen fix and bug where profilUpdates were only sorted when accepting the request and not denying 2024-04-12 09:39:28 +02:00
SimonGschnell 86504fd663 doesn't show the footer if the view inside the EditProfil Modal is set to Status 2024-04-11 11:39:29 +02:00
SimonGschnell 2b68831415 adds more filter options for the ProfilUpdateView 2024-04-11 11:20:32 +02:00
SimonGschnell 4fc4cd762d adopts logic to fetched profilUpdate status and topic from the database 2024-04-11 09:15:19 +02:00
SimonGschnell 21c2bafed6 adapt the logic of the profilUpdate feature to use constant status and topics from the database 2024-04-10 15:08:21 +02:00
SimonGschnell 5b2365a1e2 stores the status of profilUpdate with their language in the database and adapts the logic to it 2024-04-09 15:02:17 +02:00
SimonGschnell 78031bf1ad fixes buggs that were produced with the introduction of new phrasen 2024-04-09 09:08:47 +02:00
SimonGschnell 2df91bce5c adds phrasen to the ProfilUpdateView.js file 2024-04-08 15:49:28 +02:00
SimonGschnell 960341e25d adds more profil phrasen error messages 2024-04-08 15:08:20 +02:00
SimonGschnell 1b04d70839 adds phrasen for profil in php controller and adds error message phrasen 2024-04-08 15:03:08 +02:00
Johann Hoffmann cf0c7a2f8c put le_ids aswell as viewdata for le selection in globalProperties to share between components; using FhcApi Plugin for API calls; le selection in setup now with info (gruppe_kurzbz, lehrform_kurzbz, semester, verband, gruppe); fixed setting foto in viewData after refreshing sum eg after kontrolle; 2024-04-08 12:25:25 +02:00
SimonGschnell b77e56161d fixing some not working phrasen 2024-04-08 09:58:53 +02:00
SimonGschnell 0cd86e3e54 cannot use this keyword when assigning default values to props in componenets 2024-04-05 14:57:00 +02:00
SimonGschnell 150b4ec09d phrasen for acceptDenyUpdate.js and ProfilUpdateView.js 2024-04-05 10:33:23 +02:00
SimonGschnell c1cb2904e6 adding phrases for Profil and ProfilUpdate 2024-04-04 15:02:47 +02:00
SimonGschnell 6af2a01166 tabulator5 migration changes 2024-04-04 09:55:41 +02:00
SimonGschnell 2e5f53f59a changes tabulator cell alignment in tabulator5 2024-04-04 09:36:46 +02:00
SimonGschnell dd2f982e95 adding the uniqueID jquery identifier to acceptLehrvertrag.js 2024-04-03 14:33:35 +02:00
SimonGschnell a2d71d3a8d adjusts how the AcceptDenyModal is used and included in the ProfilUpdateView 2024-04-02 16:38:29 +02:00
SimonGschnell 51a65495aa corrects the insertion of the dms_kategorie profil_aenderung in the checksystem 2024-04-02 15:31:56 +02:00
SimonGschnell e33d863732 upgrades pruefungsprotokollUebersicht to tabulator 5 2024-04-02 13:03:52 +02:00
SimonGschnell 4e3ab802b6 removes unnecessary debugging log 2024-04-02 12:49:33 +02:00
SimonGschnell d8fb36543f migrates adminZeitverfuegbarkeit to tabulator5 2024-04-02 12:46:51 +02:00
SimonGschnell e29dfd99f3 migrate approveLehrauftrag/acceptLehrauftrag/orderLehrauftrag to tabulator 5 2024-04-02 12:34:51 +02:00
Johann Hoffmann 927ed934c0 new Controller & routes for Landing Page; Fixed querying students for n LE; Pictures in LektorOverview & Detailview; WIP SetupComponent to select missing parameters in case; added highcharts library as pure JS; WIP designing Charts based on role & parameter input or setup; Integration in old cis via Mein Cis/Meine LV aswell as Studium/Studiengänge currently as "Anwesenheiten NEU"; WIP Landing Page Design; WIP LE Selection from Stundenplan Entries with appropriate Classification; defined settings for QR Regeneration and showing time left on a progress bar; entry query parameters are being handled inside globalProperties, controller parameters are still inside permissions array; 2024-03-22 14:12:17 +01:00
SimonGschnell 7dec1178e4 changes the parameter list of the tooltip function in tabulator 5 for approveAnrechnungUebersicht and reviewAnrechungUebersicht 2024-03-21 14:51:04 +01:00
SimonGschnell 72b19987bd removes unnecessary debugging prints 2024-03-21 14:46:03 +01:00
SimonGschnell 1a76231df0 migrated orderLehrauftrag to tabulator5 2024-03-21 14:37:28 +01:00
SimonGschnell 57e5626fe4 reset the navbar to use bootstrap3 2024-03-21 13:52:56 +01:00
SimonGschnell a8c60c105d migrating approveLehrauftrag to tabulator5 2024-03-21 13:42:43 +01:00
SimonGschnell 47dfb66b8d replacing string concatenation with string literals for tableWidget Header and Footer 2024-03-21 09:27:44 +01:00
SimonGschnell 081a2d69f5 set version 3 as the default version of bootstrap for the tableWidget 2024-03-21 08:49:28 +01:00
SimonGschnell 59f25bd3a2 adding the bootstrapVersion flag to the /widget/table view to dynamically render css classes + little fixes 2024-03-20 13:26:23 +01:00
SimonGschnell 78a16982f8 updates the tableHelpsite to use bootstrap5 classes if the bootstrapVersion flag is set to 5 2024-03-20 13:25:32 +01:00
SimonGschnell de15d43bb7 adds bootstrapVersion flag to the tableWidget options to render bootstrap3 classes or bootstrap5 classes 2024-03-19 15:29:28 +01:00
SimonGschnell acac5dfc65 trying to independenly restyle the navigationWidget 2024-03-18 15:17:14 +01:00
SimonGschnell 92cb4dedef migrates adminAnrechnungData and adminAnrechnung.js to use tabulator5 2024-03-18 11:49:54 +01:00
SimonGschnell 3cdc051861 updates adminAnrechnung view to bootstrap5 2024-03-18 11:42:34 +01:00
SimonGschnell 961526925c updates reviewAnrechnungDetail.js to change the correct bootstrap5 classes in the javascript 2024-03-18 11:07:12 +01:00
SimonGschnell 571bf8ebad update reviewAnrechnungenDetail to Bootatrap5 and little styling fixes for other Detail views 2024-03-18 11:02:26 +01:00
Johann Hoffmann 44260ddb4d basic link to Anwesenheit Extension from cis_menu_lv.inc.php checking on CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN in global.config-default.inc.php 2024-03-18 10:58:14 +01:00
Johann Hoffmann b39b8559d9 Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp 2024-03-18 10:55:05 +01:00
SimonGschnell 72bf2525b7 updating reviewAnrechnungUebersicht to bootstrap5 and tabulator5 2024-03-18 10:14:05 +01:00
SimonGschnell 83ccc93305 little adjustments and migrations 2024-03-15 15:02:17 +01:00
SimonGschnell 5ecac3cb99 migrates createAnrechnung to bootstrap 5 and tabulator 5 2024-03-15 15:01:55 +01:00
SimonGschnell 183cb1ac17 little adjustments on requestAnrechnung 2024-03-15 12:52:21 +01:00
SimonGschnell cc461aab8b updates js file of approveAnrechnungDetail to be bootstrap5 conform 2024-03-15 12:52:00 +01:00
SimonGschnell f9c894307d buttons with attribute disabled and title fix 2024-03-15 11:58:31 +01:00
SimonGschnell 9360c8a470 migrates approveAnrechnungDetail to bootstrap5 and adds little adjustments to requestAnrechungImportant 2024-03-15 11:57:11 +01:00
SimonGschnell 868d10ffd6 adds bg-secondary-subtle to the color palette and fixes buttons that are disabled and have a title attribute 2024-03-15 11:56:16 +01:00
SimonGschnell 465ab736ee changed AnrechnungenInfo panel to bootstrap5 accordion 2024-03-15 11:18:31 +01:00
SimonGschnell 8556632f90 updating approveAnrechnungDetail to boostrap5 2024-03-14 11:36:42 +01:00
SimonGschnell 8a835cb7f8 reset searchbar.js fixing searchbar style 2024-03-13 14:44:56 +01:00
SimonGschnell 3c2190b280 fixes zustellAdressenCount for EditAdresse and formats code files 2024-03-13 14:01:29 +01:00
SimonGschnell c0e6552c08 fixes zustellKontakteCount in EditKontakt 2024-03-13 13:44:08 +01:00
SimonGschnell e7480eb9ff hotfix, editProfil modal in fetchProfilUpdates component 2024-03-13 12:23:45 +01:00
SimonGschnell 1816f3f5f6 fully upgrades the approveAnrechnungUebersicht to tabulator5 2024-03-13 10:22:10 +01:00
SimonGschnell 6722fde9c9 adapts approveAnrechnungUebersicht for the new tabultor5 functions 2024-03-12 15:33:24 +01:00
SimonGschnell 70418b8ff6 updates TableWidget.js functions that are no longer valid in tabulator5 2024-03-12 14:30:40 +01:00
SimonGschnell 1dc4f5b56a upgrading tableWidget to tabulator 5 with custom jquery_wrapper 2024-03-12 12:28:59 +01:00
Harald Bamberger 691bbaaf82 workaround for tabulator jquery_wrapper 2024-03-12 09:59:21 +01:00
SimonGschnell aa7982fea9 adds jquery adjustments 2024-03-08 12:34:26 +01:00
SimonGschnell 1b65f6f4e6 trying to add callbacks after the tabulator called the tableBuilt event with jquery 2024-03-07 14:48:11 +01:00
SimonGschnell 7eda02f366 adds include variable tabulator5JQuery to FHC-Common.php 2024-03-07 11:46:05 +01:00
SimonGschnell b1411549f3 better folder structure for Cis Profil 2024-03-07 11:14:58 +01:00
SimonGschnell 96e0bfa72c changes how the EditProfil Modal passes props to its children 2024-03-07 11:08:43 +01:00
SimonGschnell 464799d22b tabulator upgrade 2024-03-06 14:46:21 +01:00
SimonGschnell e41e24be04 adding the option to add css classes to the HTMLWidget 2024-03-05 15:38:51 +01:00
SimonGschnell 144a872c98 adds cutsom cis css style which lowers the overall font size 2024-03-05 09:36:16 +01:00
SimonGschnell b7a1236acc anrechnung.css update 2024-03-04 15:06:08 +01:00
SimonGschnell dd309e972b js alert messages update, need to update the phrasesupdate.php 2024-03-04 15:03:49 +01:00
SimonGschnell 84ba0dbb64 bootstrap 5 upgrade (tooltips,cards,margins,..) 2024-03-04 13:50:06 +01:00
SimonGschnell ccf01100bb adds new classes because alert-info/warning/... are not consistent in the new bootstrap versions 2024-03-01 15:36:10 +01:00
Johann Hoffmann 8ccc621a91 Finalized db schema changes for Anwesenheitskontrolle and Checkin; Multiple Lektor scenario not being managed yet; reworked frontend requests towards API Controller to not confuse vue router; WIP UX; 2024-02-27 11:42:42 +01:00
SimonGschnell 21f7099878 refactor 2024-02-23 14:32:06 +01:00
SimonGschnell f09692edd1 adds primevue autocomplete field for EditAdresse 2024-02-22 15:04:24 +01:00
SimonGschnell ee7a819094 Merge branch 'master' into feature-25999/C4_ma0594dev 2024-02-22 12:06:16 +01:00
SimonGschnell 989f1ecf02 finishes the documentation in Profil.php controller and refactors getView 2024-02-22 11:50:08 +01:00
Johann Hoffmann 63a06dfef2 WIP api controller backend; WIP adapting queries to new db schema; 2024-02-22 10:30:18 +01:00
SimonGschnell 0b84e1b608 finishes documentation on Profil.php controller 2024-02-22 09:00:53 +01:00
SimonGschnell 4edd242f09 adds documentation to the Profil.php controller not finished 2024-02-21 15:44:41 +01:00
SimonGschnell 2a393f0087 adds the fields gemeinde and nation to the EditAdresse Component and adds autocomplete for the gemeinde if the nation is A 2024-02-21 12:31:41 +01:00
SimonGschnell 1bed062a01 querying the right data for the EditAdresse Nation and Gemeinde Fields 2024-02-20 15:57:17 +01:00
SimonGschnell 6f7bca6eab adds loading modal to ProfilUpdateView 2024-02-20 14:32:28 +01:00
SimonGschnell 47abce4aad handles the loading modal in the root Profil app when inserting a new profil update that may takes some time because it has to send out emails 2024-02-20 10:50:35 +01:00
SimonGschnell 1afb9130c0 adds a loading animation when waiting for the emails to be sent out when inserting a new profil update request 2024-02-19 15:12:16 +01:00
SimonGschnell 2e9cc2b291 /ProfilUpdate/id/ was added to the ProfilUpdate controller to automatically open the necessary profil_update on startup of the page, this functionality is used when sending emails with the link to the profil_update 2024-02-19 14:36:45 +01:00
SimonGschnell 2d5aea2bb8 translates the english status into a german version for the email vorlage 2024-02-19 09:14:45 +01:00
SimonGschnell 318087c572 sends email to the user if a profil update was accepted or rejected 2024-02-16 15:37:20 +01:00
SimonGschnell 501224b9b7 sends emails on insertion of an profil update to the studiengänge in case of students and to hr in case of a mitarbeiter 2024-02-16 14:33:49 +01:00
SimonGschnell 34b995ed6d adds dms_kategorie for profil updates as an insert into statement in the dbupdate file 2024-02-15 16:20:54 +01:00
SimonGschnell 04f6ee6156 Merge branch 'master' into feature-25999/C4_ma0594dev 2024-02-15 15:16:07 +01:00
SimonGschnell 6eeeb8b4b7 send email 2024-02-15 15:09:41 +01:00
SimonGschnell 279fbe51c3 sendMail function now gets all the studiengang emails of an active student or sends the mail to personalverwaltung if it is a mitarbeiter 2024-02-15 14:24:07 +01:00
Johann Hoffmann afa00caa4c Merge remote-tracking branch 'origin/feature-34543/UX_Template' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp
# Conflicts:
#	system/filtersupdate.php
2024-02-15 14:16:33 +01:00
SimonGschnell fd260a6307 changes the check if a user has permissions to accept or deny a profil update 2024-02-15 09:59:27 +01:00
SimonGschnell 028be08ec3 fixes little bug with profil update checking 2024-02-14 14:38:21 +01:00
SimonGschnell 5758d7cf4f overrides old zustelladressen/kontakte when changing or adding a new zustelladresse/kontakt 2024-02-14 14:18:31 +01:00
SimonGschnell b655c4021a instead of calculating how many zustelladressen or zustellkontakte a user has in the backend, it is calculated in the client side to prevent an extra api call 2024-02-14 11:42:20 +01:00
SimonGschnell 65a9b8c80f little fix 2024-02-14 09:01:40 +01:00
SimonGschnell bfba05753e also shows the zustellungs warning when there is more than one kontakt marked as zustellung 2024-02-14 08:56:25 +01:00
SimonGschnell 5ee241d914 now editAdressen shows a warning message if a new adresse is marked as zustelladresse 2024-02-13 15:30:23 +01:00
SimonGschnell 409221434a removes the checkbox for heimatadresse because it should not be changed by the user 2024-02-13 14:25:07 +01:00
SimonGschnell 66b843be1b hides the profil updates list if no profil update is present 2024-02-13 14:20:01 +01:00
SimonGschnell 1be8c27cb5 checks the permissions of a user when accepting or denying a profil update 2024-02-13 13:37:10 +01:00
SimonGschnell 92f2f5108c refactor of Profil.php to reuse function functionalities 2024-02-13 11:39:57 +01:00
SimonGschnell 24b467cd90 show different options for address types if the user is a mitarbeiter or a student 2024-02-12 16:29:19 +01:00
SimonGschnell 9ac523c087 deletes column name from public.tbl_profil_update 2024-02-12 16:00:17 +01:00
SimonGschnell 4b898bd976 queries full name of user that created profil_update using join in Profil_update_model 2024-02-12 15:58:52 +01:00
SimonGschnell 78bffb1348 little bugfix 2024-02-12 14:08:26 +01:00
SimonGschnell 6aa0bbb037 fixed little bug with fileOutput 2024-02-12 12:27:15 +01:00
SimonGschnell a09a350338 berechtigungen für die Ansicht von Profil Update Dokumente 2024-02-12 11:30:49 +01:00
SimonGschnell b21d3448cb fixes some data handling errors in controller functions 2024-02-12 09:07:51 +01:00
SimonGschnell 90012856dc EditAdresse layout change 2024-02-09 15:21:53 +01:00
SimonGschnell bbf6616cd9 corrects the display of links to attachments of a profil update request 2024-02-09 14:41:29 +01:00
SimonGschnell 43492add0b changes how files are attached/replaced to a profil update 2024-02-09 13:55:08 +01:00
SimonGschnell cda13ac705 makes the send button in the profil update popup disabled instead of not showing it 2024-02-08 13:47:03 +01:00
SimonGschnell 89bc5a5d9d Assistenten koennen nur Profil Aenderungen von Studenten ansehen deren Organisationseinheit in den Berechtigung des Assistenten vorhanden sind (und kleiner sessionStorage fix der einen String zu Boolean converted) 2024-02-08 11:48:14 +01:00
SimonGschnell fa1871a059 adopting profil controllers/models/views to db table change 2024-02-07 16:34:00 +01:00
SimonGschnell 3739581a29 db tabellen anpassung 2024-02-07 16:25:39 +01:00
SimonGschnell 9362aea0cf when user does not have permissions to accept/deny a profil update request it is notified via alert modal 2024-02-07 14:21:25 +01:00
SimonGschnell 286c7be83d only displays profil update requests the uid has permissions for (mitarbeiter/stammdaten or student/stammdaten), also fixes bug and adds JSON.parse to get the value in the sessionStorage 2024-02-07 13:25:50 +01:00
SimonGschnell 1e260a178c trying to restructure where editData is created 2024-02-06 16:24:43 +01:00
SimonGschnell 3d2c7e4026 sorts the data of the profil updates before displaying them in a table and tooltips have been added to the hr profil update requests table 2024-02-06 11:26:45 +01:00
SimonGschnell f47650f5e9 shows a menu when right clicking a profil update request in the hr view 2024-02-05 15:33:51 +01:00
Johann Hoffmann c6d4c34cad define AnwesenheitenByLektor in system/filtersupdate.php 2024-02-05 15:32:03 +01:00
SimonGschnell ff88581ecd stores the value of the selection to show all or only the pending Profil update requests in the sessionStorage 2024-02-05 14:26:38 +01:00
SimonGschnell 4faaa78ee1 also shows the zustelladresse checkbox when viewing an Adresse component in the hr View for Profil Updates 2024-02-05 13:16:51 +01:00
SimonGschnell a2d0f9e39a funciton that queries the ProfilUpdates now takes a associative array instead of multiple separate parameters 2024-02-05 11:17:07 +01:00
SimonGschnell 6e55382d15 adds zustelladresse as a field to EditKontakte component 2024-02-05 09:52:27 +01:00
SimonGschnell c88da53c03 only allows to user to send profil updates when the input doesn't correspond the original values 2024-02-02 09:49:07 +01:00
SimonGschnell e5182a20ac adds a select to the profilUpdateRequests to change display between only pending and all requests 2024-02-01 15:27:24 +01:00
SimonGschnell d813f55a9b makes it possible to display documents when reviewing profil update requests 2024-02-01 14:08:55 +01:00
SimonGschnell 1460e6ed80 modifing uploaded files int the fetchProfilUpdates component works correctly 2024-01-31 15:22:03 +01:00
SimonGschnell 0e69e432da fixes a lot of bugs and adds the inseramum/insertvon/updateamum/updatevon fields to the cis_profil_update db table 2024-01-31 14:26:54 +01:00
SimonGschnell 6f081e4136 removes logs 2024-01-31 09:15:48 +01:00
SimonGschnell df1fe01abe makes watcher eager and aligns files vertically 2024-01-31 09:05:23 +01:00
SimonGschnell 3362eb8e31 changing the text_input component to accept documents for the name or the title of a PersonUpdateRequest 2024-01-30 15:59:56 +01:00
SimonGschnell a21a292da6 dokument upload 2024-01-29 16:48:41 +01:00
SimonGschnell 76f2501fec little layout fix 2024-01-29 11:14:51 +01:00
SimonGschnell 9ebb04a01b StudentView also uses the layout components 2024-01-29 09:49:50 +01:00
SimonGschnell 783a2fb2b0 removes print in MitarbeiterView Controller and MitarbeiterView uses the components to render the information 2024-01-29 09:22:20 +01:00
SimonGschnell bdf59f3230 layout fixes and adding profilUpdateRequests component to Student view 2024-01-26 17:51:08 +01:00
SimonGschnell bece495ac8 fixes edge cases realted to creating new profil update requests 2024-01-26 16:37:39 +01:00
SimonGschnell 15cd9155f1 updates kontakt_id / adresse_id in profilUpdateRequest after inserting new kontakt/adresse in db 2024-01-25 16:43:47 +01:00
SimonGschnell 20672cd311 add/delete/update von Adressen funktioniert 2024-01-24 17:03:06 +01:00
SimonGschnell a390eefd75 add/delete/update kontakt is possible 2024-01-24 16:06:22 +01:00
SimonGschnell 20d6a34506 little style changes and adds name field to the public.tbl_cis_profil_update table 2024-01-24 12:18:21 +01:00
SimonGschnell 5f55834ccf controller functionality to apply profil update requests to the user 2024-01-23 18:03:38 +01:00
SimonGschnell 13f2bb4e85 fixes little bug where status timestamp was converted from null to the current date, with create_date in php 2024-01-23 11:40:02 +01:00
SimonGschnell df74bade9b fixes bug when getting all the profil update requests and makes it possible to add a message when dening or accepting a profil update 2024-01-23 11:00:43 +01:00
SimonGschnell 7abe04a69f fixes little bug for View Profil and changes layout of the profil update fetch component 2024-01-22 16:02:52 +01:00
SimonGschnell fb9b65b138 changes how to display the hr table with all the user update requests and the update request table in the profil view, also adds some new columns to the cis_profil_update table to store the status, status date and status message 2024-01-22 14:45:32 +01:00
SimonGschnell 0d5e8e89a6 splits the ProfilComponents.js file into multiple components in the ProfilComponents Folder and StudentProfil uses the components 2024-01-19 15:07:57 +01:00
SimonGschnell 84b23a148e modulerizing the profil page in multiple reusable components 2024-01-18 15:32:52 +01:00
SimonGschnell 5e7e2b63dd disables the kontakt input field in the EditKontakt component if no Kontakttyp was selected 2024-01-18 11:31:28 +01:00
SimonGschnell c5f6ce861b when adding a new kontakt or address, it is possible to modify it afterwards 2024-01-18 09:20:01 +01:00
SimonGschnell 8bda0f2f96 first template for the functionality to add a new kontakt/address 2024-01-17 15:34:53 +01:00
SimonGschnell 49fda27e56 profilUpdates need to have unique adresse_id or kontakt_id 2024-01-17 13:53:32 +01:00
SimonGschnell a5c77543b1 adds functionality to delete a Kontakt or an Adress 2024-01-17 12:07:06 +01:00
SimonGschnell b53dec6a31 adds breadcrumb to modal and adjusts controller functions and api calls 2024-01-16 15:44:04 +01:00
SimonGschnell 73792d1e78 the user is now able to delete an existing change request that he made 2024-01-15 15:40:55 +01:00
SimonGschnell e881abe904 allows user to make profil changes requests and to oversee his requested changes 2024-01-15 15:15:16 +01:00
SimonGschnell d3a3ebacfc first templates for the components Select and Breadcrumbs 2024-01-10 15:02:11 +01:00
SimonGschnell 75ce2a0aa8 Shows Select option names without _ 2024-01-10 09:11:24 +01:00
SimonGschnell b1d8a2f5a4 adds topic field to the cis_profil_update table and changes the layout of the editProfil Modul 2024-01-09 15:51:50 +01:00
SimonGschnell 5b597dbc31 changing the editProfil Modal from an Accordion to a select 2024-01-08 15:19:18 +01:00
SimonGschnell e479a7aa49 stores the old and the new value in the profil update request, to track which information has to be updated in the database 2024-01-05 10:40:47 +01:00
Simon Gschnell ee8051915e formats the update timestamps in php, differently tracks which properties and informations where changed by the user 2024-01-04 16:06:47 +01:00
Simon Gschnell d412c1d00e first template for the hr view to accept or deny profil update requests 2024-01-03 14:38:40 +01:00
Simon Gschnell ddab42123b refactores the modal out of the view into its own modal component 2024-01-02 12:50:04 +01:00
Simon Gschnell bb0656c480 http response returns the timestamp of the change 2023-12-29 12:01:25 +01:00
Simon Gschnell a27b80c394 show the date of the last edit profil information request if there is any 2023-12-29 10:17:33 +01:00
Simon Gschnell 59b848c576 fetches profil update request if an entry with uid in table public.tbl_cis_profil_update exists 2023-12-28 11:51:58 +01:00
Simon Gschnell 414541b6cf checks if table entry for uid exists and performs update or insert on result 2023-12-28 10:43:21 +01:00
Simon Gschnell 981e782c57 checks whether the editProfilData was changed by the user and is not in the original state 2023-12-28 10:15:24 +01:00
Simon Gschnell 87f640d66a little layout fix for MitarbeiterViewProfil.js 2023-12-27 11:20:54 +01:00
Simon Gschnell d8cd52f7a0 accordion styling 2023-12-27 11:16:18 +01:00
Simon Gschnell f3e23b888d fixing the accordion with editData 2023-12-27 10:42:33 +01:00
Simon Gschnell 620528fa50 moves the collapseFunction to the parent component Profil and also manages the collapse state from the parent 2023-12-27 09:27:18 +01:00
Simon Gschnell 733275a162 first profil info edit template 2023-12-22 14:18:49 +01:00
Simon Gschnell d6ef9c4ec4 adds custom floating label css construct to the rest of the profil views 2023-12-21 11:46:42 +01:00
Simon Gschnell fed4f7f929 replaced form-control with custom css construct 2023-12-21 08:53:56 +01:00
Simon Gschnell 6f8bd9527c changes the styling when hovering over form-control fields in the profil view, so that it does not also change the behavior of other elements that use form-control on the web page 2023-12-19 16:00:43 +01:00
Simon Gschnell 9c69d8cc46 trims the student information so that the value is falsy in javascript 2023-12-19 15:49:57 +01:00
Simon Gschnell 8666dbe3a6 wrong uid was used to get the emails of the student profil view 2023-12-19 15:36:11 +01:00
Simon Gschnell c08171536c changes the tel and mailto links of all profil views 2023-12-19 15:34:28 +01:00
Simon Gschnell 030be5b83f queryies the telefon number of the mitarbeiter with standort and adds tel links to all phone numbers 2023-12-19 11:02:44 +01:00
Simon Gschnell a3e70afdc1 adds font-size 1rem to the .tabulator class of the FilterComponent 2023-12-19 11:01:51 +01:00
Simon Gschnell 8b06ef030a adds icons and some layout changes 2023-12-18 15:27:45 +01:00
Simon Gschnell f0a3b8db95 Merge remote-tracking branch 'origin/feature-25999/C4' into feature-25999/C4_ma0594dev
merges menu width
2023-12-18 12:26:01 +01:00
cgfhtw eb05922043 menu width 2023-12-18 12:25:16 +01:00
Simon Gschnell 5fbe374ea3 removes the p-4 for all screensizes from the cis-main and adds different padding for mobile view Cis-main in Cis.css 2023-12-18 12:21:17 +01:00
Simon Gschnell 64326136d5 Merge remote-tracking branch 'origin/feature-25999/C4' into feature-25999/C4_ma0594dev 2023-12-18 12:14:07 +01:00
Simon Gschnell fa3d9e1e05 layout changes 2023-12-18 12:13:03 +01:00
cgfhtw 9c2f062d34 Css update 2023-12-18 09:56:59 +01:00
cgfhtw 2e1f38cc91 Merge remote-tracking branch 'origin/feature-25999/C4' into feature-25999/C4 2023-12-18 09:54:15 +01:00
cgfhtw ae0c311be3 Css korrektur 2023-12-18 09:53:52 +01:00
Simon Gschnell 1d75a26230 responsive layout 2023-12-15 14:40:56 +01:00
Simon Gschnell 98006b3d2b puts hidden quick links in card 2023-12-14 09:19:07 +01:00
Simon Gschnell 91781d3a38 adds cards to the main information of the mitarbeiter profil view 2023-12-13 15:56:24 +01:00
Simon Gschnell d87670edb8 adds Mailverteiler in card 2023-12-13 15:49:51 +01:00
Simon Gschnell 5671bb340b resposive profil information column change and remove default table sideMenu prop 2023-12-13 14:47:40 +01:00
Simon Gschnell bff4fa5544 Merge branch 'master' into feature-25999/C4_ma0594dev 2023-12-13 14:34:37 +01:00
Simon Gschnell b6dbe1513e adds the collapsing funktions to all the different profil view that use a table with more than one column 2023-12-13 13:59:23 +01:00
Simon Gschnell 8fe19d40bc little fix for the collapsing columns function 2023-12-13 13:26:44 +01:00
Simon Gschnell ba17974371 adds the collapsing function to the column itself 2023-12-13 12:58:34 +01:00
Simon Gschnell b400ea758c fixing the hide/show all collapsed table columns function by calling the click event instead of changing the classes and styles manually 2023-12-13 12:54:44 +01:00
Simon Gschnell 058863ba8d fix for show/hide all collapsed columns icon function, weird bug where collapsed columns icons don't work on first click 2023-12-13 11:22:47 +01:00
Simon Gschnell 4715ce3b95 icon to show or hide all collapsed columns 2023-12-13 10:58:05 +01:00
Simon Gschnell a72b8a153e layout changes 2023-12-12 15:34:28 +01:00
Simon Gschnell 633cd6be0f adds wrap word to every view and deltes the old profil view 2023-12-12 14:48:26 +01:00
Simon Gschnell 5b03abb50c restyling for the hidden dropdown quick links 2023-12-12 14:42:15 +01:00
Simon Gschnell 036365e148 shows all columns, removes the hidding of a column 2023-12-12 14:00:01 +01:00
Simon Gschnell 4b45914d4f adds the collapse formater function as a global Vue function that can be used by alle the different view components 2023-12-12 13:50:38 +01:00
Simon Gschnell b2c8bcb2bf adds a little shadow to the collapsed columns in the tables 2023-12-12 13:21:15 +01:00
Simon Gschnell 350911d474 adds responsive layout collapse to both tables 2023-12-12 12:15:27 +01:00
Simon Gschnell 3a191f4a11 adds responsive layout to the tables by collapsing the columns of a table 2023-12-12 12:09:03 +01:00
Simon Gschnell 38301572ae Mailverteiler nehmen ganze Spalte ein bei Viewport lg 2023-12-12 09:41:53 +01:00
Simon Gschnell aefe73b642 overflow-wrap: break-word style for better text wrapping 2023-12-12 09:28:49 +01:00
Simon Gschnell efc8e7c5fe css fix to wrap words when space gets little 2023-12-12 09:04:07 +01:00
Simon Gschnell 37f89010a4 adds Mitarbeiter und Studenten Profil Titel 2023-12-11 15:18:44 +01:00
Simon Gschnell 84706c957e changes dynamically the col width if a kontakt anmerkung is vorhanden or not 2023-12-11 14:35:17 +01:00
Simon Gschnell 9beb426531 adding word wrap to bootstrap columns 2023-12-11 13:47:56 +01:00
Simon Gschnell 832a3de8c5 centers the text of the link under the image 2023-12-11 13:38:44 +01:00
Simon Gschnell d378cd3002 center profil image in the middle 2023-12-11 13:05:25 +01:00
Simon Gschnell f45d692e66 used new layout for the different views 2023-12-11 12:55:54 +01:00
Simon Gschnell e8a89cf277 add comments to the layout to logically seperate the different columns and rows 2023-12-11 09:47:39 +01:00
Simon Gschnell 8f152cdf50 fixed layout bug, table now shows under profil information without disturbing the right panel 2023-12-11 08:51:51 +01:00
Harald Bamberger 3f84fa7f2d use smaller base font-size 2023-12-07 17:17:48 +01:00
Simon Gschnell a48cbaabb9 layout template 2023-12-07 15:59:01 +01:00
Simon Gschnell 02e7ef12de Profil information layout 2023-12-06 13:47:35 +01:00
Simon Gschnell 617c126aa8 store getAuthUID and getAuthPersonID inside Profil controller to avoid extra calls 2023-12-06 09:52:46 +01:00
Simon Gschnell 28b7a41b80 cleaning up the code not needed in the Profil controler 2023-12-05 13:55:51 +01:00
Simon Gschnell 0d3c55b019 dynamic component inside the profil app now controlls the view and the data 2023-12-05 13:52:31 +01:00
Simon Gschnell 087bf229af restructuring controller 2023-12-05 10:39:39 +01:00
Simon Gschnell 71fda916a3 added Menu link and Profile pop up link 2023-12-04 09:25:08 +01:00
Simon Gschnell 75547ea5e3 adding link to search to view profile 2023-12-01 13:35:29 +01:00
Simon Gschnell 48f4afae73 adds Ort_kurzbz for the View_Mitarbeiter 2023-12-01 11:41:17 +01:00
Simon Gschnell 38f76f68f1 conditional rendering for different Profile Views 2023-12-01 11:07:25 +01:00
Simon Gschnell f26801b7de adds a prop to the FilterTable component to conditionally render the filter columns, this was added because there is no need for a filter column when the table only has 1 column 2023-11-28 14:58:16 +01:00
Simon Gschnell c68856b740 completes the index view for both student and mitarbeiter 2023-11-28 14:56:42 +01:00
Simon Gschnell e3ec0fc36c upadtes api calls 2023-11-28 14:55:42 +01:00
Simon Gschnell 2df956ef20 layout for index Mitarbeiter 2023-11-27 12:04:57 +01:00
Simon Gschnell 1817757745 adds the @ to the emails and changes the layout of the information displayed on the profile page 2023-11-27 12:01:04 +01:00
Simon Gschnell dee3b35a5d solved table bug 2023-11-23 14:48:05 +01:00
Simon Gschnell d08b904530 mailverteiler und deren mailto href 2023-11-23 10:02:22 +01:00
Simon Gschnell 0e813f78fb updates the foto_sperre_function to automatically update the data of the vue component 2023-11-22 09:51:49 +01:00
Simon Gschnell 16b61d0560 Daten fuer die Betriebsmittel und zutrittskarten_ausgegebenam gesammelt 2023-11-20 17:30:58 +01:00
Simon Gschnell 4fead18c06 adds the model calls for the benutzerfunktionen information for the cis profile 2023-11-17 15:27:41 +01:00
Simon Gschnell 6b27c00d30 new data collection 2023-11-17 13:09:32 +01:00
Simon Gschnell 40a58ad9d0 Merge branch 'feature-25999/C4' of github.com:FH-Complete/FHC-Core into feature-25999/C4 2023-11-17 13:05:48 +01:00
Simon Gschnell dee0bdaa17 querying new data for the cis profile page 2023-11-15 15:09:59 +01:00
Simon Gschnell 7c229bbcee importing the api calls in the component and creating api endpoints for the cis profile page 2023-11-15 13:49:06 +01:00
SimonGschnell 9227cc12f0 retrieving user data from mitarbeiter and benutzer models 2023-11-14 14:36:47 +01:00
SimonGschnell 5b385d376e creating the controller/view/api base 2023-11-14 11:52:45 +01:00
cgfhtw c0fbc74862 Bug: search url not dynamic 2023-11-13 15:04:41 +01:00
cgfhtw 8e3939a885 bug: path seperator 2023-11-06 11:20:00 +01:00
cgfhtw 7dee77a6af Code Quality 2023-07-27 11:42:03 +02:00
cgfhtw ace3bd6736 Verbesserungen 2023-07-27 10:57:53 +02:00
cgfhtw cfe7c5b0da Merge branch 'feature-27351/Digitalisierung_Formulare_Neu' into feature-25999/C4 2023-07-25 14:07:17 +02:00
cgfhtw 764628d5fb Merge branch 'feature-27351/Digitalisierung_Formulare_Neu' into feature-25999/C4 2023-07-25 10:40:38 +02:00
cgfhtw 2046b6c2a8 Menu Entry: Studierendenantrag 2023-07-25 10:38:48 +02:00
cgfhtw 8901791911 Merge branch 'feature-27351/Digitalisierung_Formulare_Neu' into feature-25999/C4 2023-07-19 14:37:59 +02:00
cgfhtw ffd12e8ddf Access Rights 2023-07-19 11:17:17 +02:00
cgfhtw 044695183f Merge branch 'feature-24647/Konfigurierbare_Dashboards' into feature-25999/C4 2023-07-19 11:15:40 +02:00
cgfhtw 0beabe0f4a spaces to tabs 2023-07-19 11:11:52 +02:00
cgfhtw 0fd53dc3ac spaces to tabs 2023-07-19 11:10:01 +02:00
cgfhtw 72169b26c3 separate class attribute and property for easier readability 2023-07-19 11:06:01 +02:00
cgfhtw 7b96f99929 Access Rights Api Controller 2023-07-19 10:59:39 +02:00
cgfhtw 72d0517701 Merge branch 'master' into feature-25999/C4 2023-07-19 10:55:35 +02:00
cgfhtw dc21662fc9 Add missing SQL Rights for web 2023-07-14 13:01:01 +02:00
cgfhtw b0c9231d14 Hmvc: Safer Code 2023-07-14 09:02:25 +02:00
cgfhtw c5db083a84 Correct paths 2023-07-12 15:32:52 +02:00
cgfhtw 5f3e393ed1 Default menu: correct paths 2023-07-12 09:12:03 +02:00
cgfhtw 3e4703408b directories from variables 2023-07-10 08:42:48 +02:00
cgfhtw d54868070f 29006: Dashboard verbesserungen 2023-05-08 12:39:25 +02:00
cgfhtw 2780ec5636 Dashboard Admin Demo 2023-05-05 14:27:33 +02:00
cgfhtw 4f43b79ed5 default controller 2023-04-14 12:50:07 +02:00
cgfhtw 95458c193c CIS4 Entry & View titles 2023-03-31 14:50:56 +02:00
cgfhtw 2a59fad2fc CMS loading speedup 2023-03-31 09:21:52 +02:00
cgfhtw e2cf663f88 Default Menu 2023-03-31 09:21:09 +02:00
cgfhtw 7e518c3978 Documents 2023-03-24 11:26:16 +01:00
cgfhtw 9e11dfb668 code quality 2023-03-14 11:00:36 +01:00
cgfhtw 6b6392deb4 Missing ; 2023-03-13 09:02:46 +01:00
cgfhtw 2238b872c6 Documents Self Service 2023-03-13 09:01:45 +01:00
cgfhtw 83c0413815 code quality 2023-03-10 10:29:54 +01:00
cgfhtw 91e43bbc07 Documents first draft 2023-03-10 09:28:57 +01:00
cgfhtw f9975eb530 Code Quality 2023-03-10 09:28:04 +01:00
cgfhtw 555b8f4e6b access rights 2023-02-24 11:59:27 +01:00
cgfhtw 280890a00d Stundenplan Widget 2023-02-24 11:57:54 +01:00
cgfhtw 3d1908982a Merge branch 'feature-24647/Konfigurierbare_Dashboards' into feature-25999/C4 2023-02-09 16:12:36 +01:00
cgfhtw 9f72206796 Stundenplan Widget Basic 2023-02-06 11:44:36 +01:00
cgfhtw 13b898179e Widget classes 2023-02-06 09:46:32 +01:00
cgfhtw 7e2d63e3fe Css cleanup 2023-02-06 08:53:32 +01:00
cgfhtw 0f60ab2a54 Stundenplan & Calendar 2023-02-06 08:43:43 +01:00
cgfhtw d1f69d4696 MyLV Verbesserungen & cleanup 2023-02-06 08:42:42 +01:00
cgfhtw 034bed6580 cleanup 2023-01-16 11:40:40 +01:00
cgfhtw 2e126692f2 MyLv: Permissions & notFound fallback 2023-01-16 11:38:24 +01:00
cgfhtw 559e4d2bc0 cleanup 2023-01-16 11:22:53 +01:00
cgfhtw 2f2f19306b MyLv 2023-01-16 10:32:24 +01:00
cgfhtw ebc7b5a3d9 Login/Logout 2023-01-16 10:31:02 +01:00
cgfhtw c5b996f35e use vue for cms for link correction 2022-12-16 13:41:16 +01:00
cgfhtw 00c52e4880 cleanup 2022-12-16 11:43:35 +01:00
cgfhtw 4335c2da80 add Dashboard to HMVC 2022-12-16 11:36:33 +01:00
cgfhtw 085ed750ca using cis.php and routing news 2022-12-16 11:34:39 +01:00
cgfhtw c56b774d1d 3 Versions 2022-12-15 09:42:28 +01:00
cgfhtw 266ba7523f s&d 2022-11-29 08:48:50 +01:00
cgfhtw 546e55ed96 Merge branch 'feature-24647/Konfigurierbare_Dashboards' into feature-25999/C4 2022-11-24 15:36:38 +01:00
cgfhtw 4120f5a566 Merge remote-tracking branch 'origin/feature-24647/Konfigurierbare_Dashboards' into feature-24647/Konfigurierbare_Dashboards 2022-11-24 11:53:06 +01:00
cgfhtw 4758fcb413 access rights 2022-11-24 11:52:09 +01:00
cgfhtw 3e0aa849d4 bugfixes & "+" background 2022-11-24 11:52:01 +01:00
Harald Bamberger 3e17892831 fixed path to news placeholder image 2022-11-24 11:50:09 +01:00
cgfhtw d51a95a8a0 test controller & views 2022-11-24 11:48:46 +01:00
cgfhtw d7c2362a0e double widgets bug 2022-11-22 14:39:33 +01:00
cgfhtw a5749a5ea2 bug: wrong check for empty fields when adding new widgets (coordinates are based on 0,0 not 1,1) 2022-11-08 14:47:44 +01:00
cgfhtw 0e7343acfb bug: uncaught promise on widget-picker abort 2022-11-08 14:46:44 +01:00
cgfhtw 0d65ae5b85 widget icons absolute path 2022-11-03 11:37:13 +01:00
cgfhtw 55959ccd41 modal size 2022-11-03 11:33:52 +01:00
cgfhtw 935881dce2 icon & cursor 2022-11-03 11:28:25 +01:00
cgfhtw 3764df6102 Add widget to preset bugfix 2022-11-03 11:24:29 +01:00
Harald Bamberger e1addbfe04 Merge branch 'master' into feature-24647/Konfigurierbare_Dashboards_api
- mv dbchanges from system/dbupdate_3.3.php to system/dbupdate_3.4.php
- mv dbchanges include file from system/dashboard/ to system/dbupdate_3.4/ and prevent direct script access
2022-11-03 10:41:56 +01:00
Harald Bamberger 677f74781b Merge branch 'feature-24647/Konfigurierbare_Dashboards_widgets' into feature-24647/Konfigurierbare_Dashboards_api 2022-11-03 10:31:36 +01:00
Harald Bamberger c78c731388 renamed Dashboard Controller to DashboardDemo and used view to dashboard_demo 2022-11-03 10:27:39 +01:00
cgfhtw 8fd61edaab Admin Components 2022-10-28 12:41:25 +02:00
cgfhtw 92ec7f44ef Update Dashboard Endpoints for Admin GUI 2022-10-28 12:40:57 +02:00
cgfhtw be6ad8ce2a cleanup 2022-10-28 12:39:19 +02:00
Cris 630c1bc2bc Changed to display 4 Ampeln in Widget 2022-10-25 14:35:38 +02:00
Cris a1ccd392f5 Added News Widget 2022-10-25 14:28:25 +02:00
Cris bc723b22f4 Added getAll() to News Model 2022-10-25 14:28:14 +02:00
Cris 71699f6e74 Added Ampel Widget 2022-10-25 14:17:52 +02:00
Cris 1d6c5b4257 Added Url Widget 2022-10-25 14:17:32 +02:00
Cris 7f1cc966f0 Added API Controller to perform API calls 2022-10-25 13:00:43 +02:00
Cris aaf64a759b Added Widgets to Widget Controller 2022-10-25 12:59:03 +02:00
Cris ae05b34cbf Removed test function 2022-10-25 12:58:14 +02:00
Cris fdc52ae47d Added Offcanvas Component 2022-10-25 12:57:27 +02:00
Cris c5d3f47457 Merged Modal Component, adapted body padding there 2022-10-25 12:55:49 +02:00
Cris 699b76f4cb Added general used methods and computed property to Abstract Mixin Component
. apiurl: returns app root and ci router from FHC_JS_DATA_OBJECT
. formatDateTime: returns human readable date time
. getDate: returns human readable date
2022-10-25 12:54:35 +02:00
cgfhtw 1043714767 adminMode in Sections 2022-10-25 09:51:20 +02:00
cgfhtw a65d297997 use FHC_JS_DATA_STORAGE_OBJECT for apiurl 2022-10-24 16:01:02 +02:00
cgfhtw a3722273e9 use Bootstrap modals 2022-10-24 15:44:12 +02:00
cgfhtw 4aa7b9854a setConfig is an emit not a prop 2022-10-24 15:08:10 +02:00
Cris b6308d1ff5 Merge remote-tracking branch 'origin/feature-24647/Konfigurierbare_Dashboards_api' into feature-24647/Konfigurierbare_Dashboards_widgets 2022-10-24 11:04:31 +02:00
cgfhtw 8983a0e821 Bootstrap Modal (+ Alert,Confirm,Prompt) 2022-10-24 11:01:27 +02:00
Cris 67f1094a97 Added Modal Component 2022-10-17 13:40:18 +02:00
Cris 065dd1d081 Added FHTW illustration image 2022-10-17 13:38:07 +02:00
Cris ecbc6d8e3d Added Dashboard Controller & View 2022-10-17 13:37:08 +02:00
Cris 0bd6af8da1 Merge remote-tracking branch 'origin/feature-24647/Konfigurierbare_Dashboards_api' into feature-24647/Konfigurierbare_Dashboards_widgets 2022-10-13 15:14:29 +02:00
cgfhtw 680787d881 Don't move out of bounds on Drag&Drop 2022-10-13 14:44:33 +02:00
cgfhtw a71ead0a85 Ajax update: better data consistency 2022-10-13 14:38:03 +02:00
cgfhtw fd2aa8a1bb Cleanup & uid from AuthLib 2022-10-13 08:43:08 +02:00
cgfhtw 6570c958b3 Bug: DataTransfer in Chrome 2022-10-12 15:50:40 +02:00
Cris b4053c45fd Merge remote-tracking branch 'origin/feature-24647/Konfigurierbare_Dashboards_api' into feature-24647/Konfigurierbare_Dashboards_widgets 2022-10-12 15:17:47 +02:00
cgfhtw dd4d71bd7d Bug: Deepmerge on update 2022-10-12 10:29:52 +02:00
Cris c7c8913833 Adapted Dashboard DB Update: Berechtigungen ergänzt / Typspezifikation entfernt.
. Berechtigungen ergänzt:
  - dashboard/benutzer
  - dashboard/admin

. Typspezifikation entfernt in Create Sequence
  - war nicht mit PHPSQL 9.6.2 kompatibel.
2022-10-12 09:19:54 +02:00
cgfhtw a468338ead Configurable CSS classes to Default Widget 2022-10-12 09:08:24 +02:00
cgfhtw 39bbcac217 Widget controller & model & table 2022-10-12 08:58:48 +02:00
cgfhtw a3ad8eb337 dashboard.tbl_widget new fields 2022-10-11 15:41:43 +02:00
cgfhtw 4f3e8dcb3c Basic VUE Components & Test WidgetController 2022-10-05 10:43:43 +02:00
Harald Bamberger 90e006feb5 allow widgets array for add operations 2022-10-04 08:22:27 +02:00
Harald Bamberger d14608ed28 level funktion_kurzbz added to presets and overrides 2022-10-03 07:59:11 +02:00
Harald Bamberger ad369bbe44 add dashboard schema and tables create script 2022-09-28 16:53:48 +02:00
Harald Bamberger 252abeafcb dummy config changed to test function level in config 2022-09-28 15:26:45 +02:00
Harald Bamberger fb7f445e22 progress on api endpoints to add and remove presets and overrides 2022-09-21 11:38:16 +02:00
Harald Bamberger 5c9c4b7e2d store configs as json in database and merge them 2022-09-16 10:46:29 +02:00
Harald Bamberger ff93c957cd dashboard config api first steps 2022-09-14 19:05:29 +02:00
402 changed files with 39867 additions and 5787 deletions
+2
View File
@@ -2,6 +2,8 @@ documents/
vendor/
/nbproject/
.vscode
composer.phar
/.idea/
.settings
.project
+9
View File
@@ -0,0 +1,9 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
// CMS Content Id for CIS4 Menu Root
$config['cis_menu_root_content_id'] = 11066;
// send Mails for ProfilUpdate
$config['cis_send_profil_update_mails'] = true;
+7
View File
@@ -0,0 +1,7 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
// use vuejs dev version
$config['use_vuejs_dev_version'] = false;
// use bundled javascript
$config['use_bundled_javascript'] = false;
+9 -4
View File
@@ -1,6 +1,12 @@
<?php
// Header menu
if(defined('CIS4') && CIS4) {
$root = APP_ROOT;
} else {
$root = CIS_ROOT;
}
$config['navigation_header'] = array(
'*' => array(
'fhcomplete' => array(
@@ -50,7 +56,7 @@ $config['navigation_header'] = array(
'requiredPermissions' => 'basis/vilesci:r',
'children' => array(
'cis' => array(
'link' => CIS_ROOT,
'link' => $root,
'icon' => '',
'description' => 'CIS',
'sort' => 10
@@ -223,7 +229,7 @@ $config['navigation_menu']['organisation/Reihungstest/index'] = array(
'target' => '_blank'
),
'auswertung' => array(
'link' => CIS_ROOT.'/cis/testtool/admin/auswertung.php',
'link' => $root.'/cis/testtool/admin/auswertung.php',
'description' => 'Auswertung',
'icon' => 'list-alt',
'sort' => 1,
@@ -319,5 +325,4 @@ $config['navigation_menu']['system/issues/Issues/*'] = array(
'target' => '_blank',
'requiredPermissions' => array('admin:rw')
),
);
);
+5 -3
View File
@@ -50,7 +50,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
| Examples: my-controller/index -> my_controller/index
| my-controller/my-method -> my_controller/my_method
*/
$route['default_controller'] = 'Vilesci';
$route['default_controller'] = defined('CIS4') && CIS4 ? 'Cis4' : 'Vilesci';
$route['translate_uri_dashes'] = FALSE;
// Class name conflicts
@@ -61,6 +61,9 @@ $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';
$route['CisVue'] = 'CisVue/dashboard';
$route['Cis/Stundenplan/(:any)'] = 'Cis/Stundenplan';
// load routes from extensions
$subdir = 'application/config/extensions';
$dirlist = scandir($subdir);
@@ -81,5 +84,4 @@ if ($dirlist)
}
}
}
}
}
+77
View File
@@ -0,0 +1,77 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Auth extends FHC_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
// Load Helpers
$this->load->helper('form');
$this->load->helper('hlp_authentication');
// Loads phrases system
$this->loadPhrases([
'global'
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function login()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required|trim|callback_validation');
$this->form_validation->set_rules('password', 'Password', 'required|trim');
if ($this->form_validation->run())
{
redirect($this->authlib->getLandingPage('/CisVue/Dashboard'));
}
else
{
$this->load->view('Cis/Login');
}
}
/**
* @return boolean
*/
public function validation()
{
$username = $this->input->post('username');
$password = $this->input->post('password');
$this->load->library('AuthLib', [false]); // without authentication otherwise loooooop!
$login = $this->authlib->loginLDAP($username, $password);
if (isSuccess($login))
return true;
$this->form_validation->set_message('validation', 'Incorrect username/password.');
return false;
}
/**
* @return void
*/
public function logout()
{
$this->load->library('AuthLib');
$this->authlib->logout();
redirect('/Cis/Auth/login', 'refresh');
}
}
+192
View File
@@ -0,0 +1,192 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \stdClass as stdClass;
/**
*
*/
class Documents extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => [self::PERM_LOGGED],
'student' => ['admin:r'],
'download' => [self::PERM_LOGGED]
]);
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$this->loadPhrases([
'global',
'tools'
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
return $this->showDocuments(getAuthUID());
}
/**
* @param string $uid Administratoren dürfen die UID als Parameter übergeben um die Dokumente von anderen Personen anzuzeigen
* @return void
*/
public function student($uid)
{
return $this->showDocuments($uid);
}
/**
* @param string $uid
* @return void
*/
protected function showDocuments($uid)
{
$this->load->model('crm/Konto_model', 'KontoModel');
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$stati = $this->PrestudentstatusModel->loadWhereUid($uid, null, true);
if (isError($stati))
return $this->load->view('errors/html/error_db.php', [
'heading' => 'Database Error',
'message' => getError($stati)
]);
$stati = getData($stati);
if (!$stati)
return $this->load->view('errors/html/error_general.php', [
'heading' => 'User ist kein Student',
'message' => 'Es konnten keine Studiensemester gefunden werden in denen der User als Student inskripiert ist'
]);
$stgs = [];
$stsemArray = [];
$buchungstypen = implode('\',\'', defined("CIS_DOKUMENTE_STUDIENBEITRAG_TYPEN") ? unserialize(CIS_DOKUMENTE_STUDIENBEITRAG_TYPEN) : []);
$person_ids = [];
foreach ($stati as $status) {
$person_ids[] = $status->person_id;
if(!in_array($status->studiensemester_kurzbz, $stsemArray)) {
$stsemArray[] = $status->studiensemester_kurzbz;
}
if (!isset($stgs[$status->studiengang_kz])) {
$stg = $this->StudiengangModel->load($status->studiengang_kz);
if (isError($stg))
return $this->load->view('errors/html/error_db.php', [
'heading' => 'Database Error',
'message' => getError($stg)
]);
$stg = getData($stg);
if (!$stg)
return $this->load->view('errors/html/error_db.php', [
'heading' => 'Database Error',
'message' => 'No Studiengang found for studiengang_kz ' . $status->studiengang_kz
]);
$stgs[$status->studiengang_kz] = current($stg);
$stgs[$status->studiengang_kz]->studiensemester = [];
}
if (!isset($stgs[$status->studiengang_kz]->studiensemester[$status->studiensemester_kurzbz])) {
$stgs[$status->studiengang_kz]->studiensemester[$status->studiensemester_kurzbz] = new stdClass();
$stgs[$status->studiengang_kz]->studiensemester[$status->studiensemester_kurzbz]->inskriptionsbestaetigung = (boolean)getData(
$this->KontoModel->checkStudienbeitragFromPrestudent(
$status->prestudent_id,
$status->studiensemester_kurzbz,
$buchungstypen
)
);
}
}
$person_ids = array_unique($person_ids);
$selfservice = null;
if (!defined('CIS_DOKUMENTE_SELFSERVICE') || CIS_DOKUMENTE_SELFSERVICE) {
$this->load->model('crm/Akte_model', 'AkteModel');
$selfservice = [];
foreach ($person_ids as $person_id) {
$result = $this->AkteModel->getArchiv($person_id, null, true);
if (isError($result))
return $this->load->view('errors/html/error_db.php', [
'heading' => 'Database Error',
'message' => getError($result)
]);
$selfservice = array_merge($selfservice, getData($result) ?: []);
}
}
$this->load->view('Cis/Documents', [
'stsemArray' => $stsemArray,
'stgs' => $stgs,
'uid' => $uid,
'studienbuchblatt' => defined('CIS_DOKUMENTE_STUDIENBUCHLBATT_DRUCKEN') && CIS_DOKUMENTE_STUDIENBUCHLBATT_DRUCKEN,
'studienerfolgsbestaetigung' => defined('CIS_DOKUMENTE_STUDIENERFOLGSBESTAETIGUNG_DRUCKEN') && CIS_DOKUMENTE_STUDIENERFOLGSBESTAETIGUNG_DRUCKEN,
'selfservice' => $selfservice
]);
}
/**
* @param integer $akte_id
* @param string $uid (optional) Administratoren dürfen die UID als Parameter übergeben um die Dokumente von anderen Personen anzuzeigen
*
* @return void
*/
public function download($akte_id, $uid = null)
{
if (!is_numeric($akte_id))
return show_404();
$this->load->model('crm/Akte_model', 'AkteModel');
$result = $this->AkteModel->load($akte_id);
if (isError($result))
return show_error(getError($result));
$akte = getData($result);
if (!$akte)
return show_404();
$akte = current($akte);
$admin_access = false;
if ($uid !== null && $this->permissionlib->isBerechtigt('admin')) {
$stati = $this->PrestudentstatusModel->loadWhereUid($uid, null, true);
if (hasData($stati)) {
$person_ids = array_map(function ($status) {
return $status->person_id;
}, getData($stati));
$person_ids = array_unique($person_ids);
if (count($person_ids) == 1 && current($person_ids) == $akte->person_id) {
$admin_access = true;
}
}
}
if (!$admin_access && ($akte->person_id != getAuthPersonId() || !$akte->stud_selfservice))
return show_error('Forbidden', 403);
// NOTE(chris): Log bei einem Download vom Becheid
if (isset($akte->dokument_kurzbz) && ($akte->dokument_kurzbz === 'Bescheid' || $akte->dokument_kurzbz === 'BescheidEng')) {
$this->load->model('system/Webservicelog_model', 'WebservicelogModel');
$this->WebservicelogModel->insert([
'webservicetyp_kurzbz' => 'content',
'request_id' => (isset($akte->akte_id) && !empty($akte->akte_id)) ? $akte->akte_id : null,
'beschreibung' => 'Bescheidbestaetigungsdownload',
'request_data' => $_SERVER['QUERY_STRING'],
'execute_time' => date('c'),
'execute_user' => getAuthUID()
]);
}
$this->output->set_content_type($akte->mimetype);
$this->output->set_output(base64_decode($akte->inhalt));
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class MyLv extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => ['basis/cis:r'],
'Info' => [self::PERM_LOGGED]
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
$this->load->view('Cis/MyLv');
}
public function Info($studien_semester,$lvid)
{
$this->load->view('Cis/LvInfo',['lvid'=> $lvid, 'studien_semester' => $studien_semester]);
}
}
+737
View File
@@ -0,0 +1,737 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Profil extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => ['basis/cis:r'],
'foto_sperre_function' => ['basis/cis:r'],
'getView' => ['basis/cis:r'],
'View' => ['basis/cis:r'],
'isMitarbeiter' => ['basis/cis:r'],
'isStudent' => ['basis/cis:r'],
'getZustellAdresse' => ['basis/cis:r'],
'getZustellKontakt' => ['basis/cis:r'],
'getAllNationen' => ['basis/cis:r'],
'getGemeinden' => ['basis/cis:r'],
]);
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
$this->load->model('ressource/Betriebsmittelperson_model', 'BetriebsmittelpersonModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Profil_update_model', 'ProfilUpdateModel');
$this->load->model('content/DmsVersion_model', 'DmsVersionModel');
//? put the uid and pid inside the controller for reusability
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* index loads the Profil view
* @access public
* @return void
*/
public function index()
{
$this->load->view('Cis/Profil');
}
/**
* redirects to the index function (needed to allow calling this URI)
* @access public
* @return void
*/
public function View($uid)
{
$this->load->view('Cis/Profil');
}
/**
* checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php)
* @access public
* @param $uid the userID used to check if it is a mitarbeiter
* @return boolean
*/
public function isStudent($uid)
{
$result = $this->StudentModel->isStudent($uid);
if (isError($result)) {
show_error("error when calling Student_model function isStudent with uid " . $uid);
}
$result = getData($result);
echo json_encode($result);
}
/**
* checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php)
* @access public
* @param $uid the userID used to check if it is a mitarbeiter
* @return boolean
*/
public function isMitarbeiter($uid)
{
$result = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($result)) {
show_error("error when calling Mitarbeiter_model function isMitarbeiter with uid " . $uid);
}
$result = getData($result);
echo json_encode($result);
}
/**
* gets the adressen that are marked as zustell from the currenlty logged in user
* @access public
* @return array a list of adresse_id's
*/
public function getZustellAdresse()
{
$this->AdresseModel->addSelect(["adresse_id"]);
$adressen_res = $this->AdresseModel->loadWhere(['person_id' => $this->pid, 'zustelladresse' => true]);
$adressen_res = hasData($adressen_res) ? getData($adressen_res) : null;
$adressen_res = array_map(function ($item) {
return $item->adresse_id;
}, $adressen_res);
echo json_encode($adressen_res);
}
/**
* gets the kontakte that are marked as zustell from the currenlty logged in user
* @access public
* @return array a list of kontakt_id's
*/
public function getZustellKontakt()
{
$this->KontaktModel->addSelect(["kontakt_id"]);
$kontakt_res = $this->KontaktModel->loadWhere(['person_id' => $this->pid, 'zustellung' => true]);
$kontakt_res = hasData($kontakt_res) ? getData($kontakt_res) : null;
$kontakt_res = array_map(function ($item) {
return $item->kontakt_id;
}, $kontakt_res);
echo json_encode($kontakt_res);
}
/**
* function that returns the data used for the corresponding view
* the client side parses the @param $uid and calls this function to get the data to the correct view
* @access public
* @param boolean $uid the userID used to identify which information should be retrieved for which view
* @return stdClass all the data corresponding to a view of a user
*/
public function getView($uid)
{
$res = new stdClass();
// if parsing the URL did not found a UID then the UID of the logged in user is used
if ($uid == "Profil" || $uid == $this->uid) {
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($this->uid);
if (isError($isMitarbeiter)) {
show_error("error while checking if UID: " . $this->uid . " is a mitarbeiter");
}
$isMitarbeiter = getData($isMitarbeiter);
if ($isMitarbeiter) {
$res->view = "MitarbeiterProfil";
$res->data = $this->mitarbeiterProfil();
$res->data->pid = $this->pid;
} else {
$res->view = "StudentProfil";
$res->data = $this->studentProfil();
$res->data->pid = $this->pid;
}
}
// UID is availabe when accessing Profil/View/:uid
else {
$this->PersonModel->addSelect(["person_id"]);
$pid = $this->PersonModel->getByUid($uid);
if (isError($pid)) {
show_error("error while trying to update table public.tbl_person while searching for a person with UID: " . $uid);
}
$pid = hasData($pid) ? getData($pid)[0] : null;
if (!$pid) {
show_error("Person with UID: " . $uid . " does not exist");
}
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($isMitarbeiter)) {
show_error("error while checking if UID: " . $uid . " is a mitarbeiter");
}
$isMitarbeiter = getData($isMitarbeiter);
if ($isMitarbeiter) {
$res->view = "ViewMitarbeiterProfil";
$res->data = $this->viewMitarbeiterProfil($uid);
} else {
$res->view = "ViewStudentProfil";
$res->data = $this->viewStudentProfil($uid);
}
}
echo json_encode($res);
}
/**
* update column foto_sperre in public.tbl_person
* @access public
* @param boolean $value new value for the column
* @return boolean the new value added to the column in public.tbl_person
*/
public function foto_sperre_function($value)
{
$res = $this->PersonModel->update($this->pid, ["foto_sperre" => $value]);
if (isError($res)) {
show_error("error while trying to update table public.tbl_person");
}
$this->PersonModel->addSelect("foto_sperre");
$res = $this->PersonModel->load($this->pid);
if (isError($res)) {
show_error("error while trying to query table public.tbl_person");
}
$res = hasData($res) ? getData($res)[0] : null;
echo json_encode($res);
}
/**
* gets all nations in the table bis.tbl_nation
*
* @access public
* @return array all the nations in table bis.tbl_nation
*/
public function getAllNationen()
{
$this->load->model('codex/Nation_model', "NationModel");
$this->NationModel->addSelect(["nation_code as code", "langtext"]);
$nation_res = $this->NationModel->load();
if (isError($nation_res)) {
show_error("error while trying to query table codex.tbl_nation");
}
$nation_res = hasData($nation_res) ? getData($nation_res) : null;
echo json_encode($nation_res);
}
/**
* gets specific gemeinden which are related to the ZIP and the Nation passed in the body of the get request
* @access public
* @var $_GET function uses GET request payload
* @return boolean the new value added to the column in public.tbl_person
*/
public function getGemeinden()
{
/** @var $nation value parsed out of the body of the get request */
$nation = $this->input->get('nation', true);
/** @var $zip value parsed out of the body of the get request and converted to a php integer with json_decode */
$zip = json_decode($this->input->get('zip', true));
$this->load->model('codex/Gemeinde_model', "GemeindeModel");
$this->GemeindeModel->addDistinct();
$this->GemeindeModel->addSelect(["name"]);
if ($nation == "A") {
if (isset($zip) && $zip > 999 && $zip < 32000) {
$gemeinde_res = $this->GemeindeModel->loadWhere(['plz' => $zip]);
if (isError($gemeinde_res)) {
show_error("error while trying to query bis.tbl_gemeinde");
}
$gemeinde_res = hasData($gemeinde_res) ? getData($gemeinde_res) : null;
$gemeinde_res = array_map(function ($obj) {
return $obj->name;
}, $gemeinde_res);
echo json_encode($gemeinde_res);
} else {
echo json_encode(error("ortschaftskennziffer code was not valid"));
}
} else {
echo json_encode(error("Nation was not 'A' (Austria)"));
}
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
/**
* function that returns the data used for viewing another mitarbeiter profile
* @access private
* @param integer $uid the userID to retrieve the mitarbeiter data
* @return stdClass restricted mitarbeiter data
*/
private function viewMitarbeiterProfil($uid)
{
$mailverteiler_res = $this->getMailverteiler($uid);
$benutzer_funktion_res = $this->getBenutzerFunktion($uid);
$benutzer_res = $this->getBenutzerAlias($uid);
$person_res = $this->getPersonInfo($uid);
$mitarbeiter_res = $this->getMitarbeiterInfo($uid);
$telefon_res = $this->getTelefonInfo($uid);
$res = new stdClass();
$res->username = $uid;
//? Person Info
foreach ($person_res as $key => $val) {
$res->$key = $val;
}
//? Mitarbeiter Info
foreach ($mitarbeiter_res as $key => $val) {
$res->$key = $val;
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $uid . "@" . DOMAIN;
$extern_email = array();
$extern_email["type"] = "alias";
$extern_email["email"] = $benutzer_res->alias . "@" . DOMAIN;
$res->emails = array($intern_email, $extern_email);
$res->funktionen = $benutzer_funktion_res;
$res->mailverteiler = $mailverteiler_res;
$res->standort_telefon = isset($telefon_res) ? $telefon_res->kontakt : null;
return $res;
}
/**
* function that returns the data used for viewing another student profile
* @access private
* @param integer $uid the userID to retrieve the student data
* @return stdClass restricted student data
*/
private function viewStudentProfil($uid)
{
$mailverteiler_res = $this->getMailverteiler($uid);
$person_res = $this->getPersonInfo($uid);
$student_res = $this->getStudentInfo($uid);
$matr_res = $this->getMatrikelNummer($uid);
$res = new stdClass();
$res->username = $uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Student Information
foreach ($student_res as $key => $value) {
$res->$key = $value;
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $uid . "@" . DOMAIN;
$res->emails = [$intern_email];
$res->matrikelnummer = $matr_res->matr_nr;
$res->mailverteiler = $mailverteiler_res;
return $res;
}
/**
* function that returns the data used for the mitarbeiter profile
* @access private
* @return stdClass mitarbeiter data
*/
private function mitarbeiterProfil()
{
$zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid);
$adresse_res = $this->getAdressenInfo($this->pid);
$kontakte_res = $this->getKontaktInfo($this->pid);
$mailverteiler_res = $this->getMailverteiler($this->uid);
$person_res = $this->getPersonInfo($this->uid, true);
$benutzer_funktion_res = $this->getBenutzerFunktion($this->uid);
$betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid);
$profilUpdates = $this->getProfilUpdates($this->uid);
$telefon_res = $this->getTelefonInfo($this->uid);
$mitarbeiter_res = $this->getMitarbeiterInfo($this->uid);
$res = new stdClass();
$res->username = $this->uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Mitarbeiter Information
foreach ($mitarbeiter_res as $key => $value) {
$res->$key = $value;
}
$res->adressen = $adresse_res;
$res->zutrittsdatum = $zutrittskarte_ausgegebenam;
$res->kontakte = $kontakte_res;
$res->mittel = $betriebsmittelperson_res;
$res->mailverteiler = $mailverteiler_res;
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $this->uid . "@" . DOMAIN;
$extern_email = array();
$extern_email["type"] = "alias";
$extern_email["email"] = $mitarbeiter_res->alias . "@" . DOMAIN;
$res->emails = [$intern_email, $extern_email];
$res->funktionen = $benutzer_funktion_res;
$res->standort_telefon = $telefon_res;
$res->profilUpdates = $profilUpdates;
return $res;
}
/**
* function that returns the data used for the student profile
* @access private
* @return stdClass student data
*/
private function studentProfil()
{
$betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid);
$kontakte_res = $this->getKontaktInfo($this->pid);
$zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid);
$adresse_res = $this->getAdressenInfo($this->pid);
$mailverteiler_res = $this->getMailverteiler($this->uid);
$person_res = $this->getPersonInfo($this->uid, true);
$zutrittsgruppe_res = $this->getZutrittsgruppen($this->uid);
$student_res = $this->getStudentInfo($this->uid);
$matr_res = $this->getMatrikelNummer($this->uid);
$profilUpdates = $this->getProfilUpdates($this->uid);
$res = new stdClass();
$res->username = $this->uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Student Information
foreach ($student_res as $key => $value) {
$res->$key = trim($value);
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $this->uid . "@" . DOMAIN;
$res->emails = [$intern_email];
$res->adressen = $adresse_res;
$res->zutrittsdatum = $zutrittskarte_ausgegebenam;
$res->kontakte = $kontakte_res;
$res->mittel = $betriebsmittelperson_res;
$res->matrikelnummer = $matr_res->matr_nr;
$res->zuttritsgruppen = $zutrittsgruppe_res;
$res->mailverteiler = $mailverteiler_res;
$res->profilUpdates = $profilUpdates;
return $res;
}
/**
* gets all the mailverteiler using the tables: tbl_benutzer, tbl_benutzergruppe, tbl_gruppe
* @access private
* @param integer $uid the userID used to retrieve the mailverteiler
* @return array returns the mailvertailer corresponding to a userID
*/
private function getMailverteiler($uid)
{
$this->PersonModel->addSelect('gruppe_kurzbz, beschreibung');
$this->PersonModel->addJoin('tbl_benutzer', 'person_id');
$this->PersonModel->addJoin('tbl_benutzergruppe', 'uid');
$this->PersonModel->addJoin('tbl_gruppe', 'gruppe_kurzbz');
$mailverteiler_res = $this->PersonModel->loadWhere(array('mailgrp' => true, 'uid' => $uid));
if (isError($mailverteiler_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($mailverteiler_res));
}
$mailverteiler_res = hasData($mailverteiler_res) ? getData($mailverteiler_res) : null;
$mailverteiler_res = array_map(function ($element) {
$element->mailto = "mailto:" . $element->gruppe_kurzbz . "@" . DOMAIN;
return $element;
}, $mailverteiler_res);
return $mailverteiler_res;
}
/**
* gets all the Benutzerfunktionen of a corresponding user
* @access private
* @param integer $uid the userID used to retrieve the Benutzerfunktionen
* @return array returns the Benutzerfunktionen corresponding to a userID
*/
private function getBenutzerFunktion($uid)
{
$this->BenutzerfunktionModel->addSelect(["tbl_benutzerfunktion.bezeichnung as Bezeichnung", "tbl_organisationseinheit.bezeichnung as Organisationseinheit", "datum_von as Gültig_von", "datum_bis as Gültig_bis", "wochenstunden as Wochenstunden"]);
$this->BenutzerfunktionModel->addJoin("tbl_organisationseinheit", "oe_kurzbz");
$benutzer_funktion_res = $this->BenutzerfunktionModel->loadWhere(array('uid' => $uid));
if (isError($benutzer_funktion_res)) {
show_error("was not able to query the table public.tbl_benutzerfunktion:" . getData($benutzer_funktion_res));
}
$benutzer_funktion_res = hasData($benutzer_funktion_res) ? getData($benutzer_funktion_res) : null;
return $benutzer_funktion_res;
}
/**
* gets all the Betriebsmittel of a corresponding user
* @access private
* @param integer $uid the userID used to retrieve the Betriebsmittel
* @return array returns the Betriebsmittel corresponding to a userID
*/
private function getBetriebsmittelInfo($pid)
{
$this->BetriebsmittelpersonModel->addSelect(["CONCAT(betriebsmitteltyp, ' ' ,beschreibung) as Betriebsmittel", "nummer as Nummer", "ausgegebenam as Ausgegeben_am"]);
//? betriebsmittel are not needed in a view
$betriebsmittelperson_res = $this->BetriebsmittelpersonModel->getBetriebsmittel($pid);
if (isError($betriebsmittelperson_res)) {
show_error("was not able to query the table public.tbl_betriebsmittelperson:" . getData($betriebsmittelperson_res));
}
$betriebsmittelperson_res = hasData($betriebsmittelperson_res) ? getData($betriebsmittelperson_res) : null;
return $betriebsmittelperson_res;
}
/**
* gets the alias of a corresponding user
* @access private
* @param integer $uid the userID used to get the alias
* @return string the alias of the userID
*/
private function getBenutzerAlias($uid)
{
$this->BenutzerModel->addSelect(["alias"]);
$benutzer_res = $this->BenutzerModel->load([$uid]);
if (isError($benutzer_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($benutzer_res));
} else {
$benutzer_res = hasData($benutzer_res) ? getData($benutzer_res)[0] : null;
}
return $benutzer_res;
}
/**
* gets the person information corresponding to a user
* @access private
* @param integer $uid the userID used to get the person information
* @param integer $geburtsInfo flag wether to add the columns gebort, gebdatum, foto_sperre or not
* @return array all the person informaion corresponding to a userID
*/
private function getPersonInfo($uid, $geburtsInfo = null)
{
$selectClause = ["foto", "anrede", "titelpost as postnomen", "titelpre as titel", "vorname", "nachname"];
/** @param integer $geburtsInfo */
if ($geburtsInfo) {
array_push($selectClause, "gebort");
array_push($selectClause, "gebdatum");
array_push($selectClause, "foto_sperre");
}
$this->BenutzerModel->addSelect($selectClause);
$this->BenutzerModel->addJoin("tbl_person", "person_id");
$person_res = $this->BenutzerModel->load([$uid]);
if (isError($person_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($person_res));
} else {
$person_res = hasData($person_res) ? getData($person_res)[0] : null;
}
return $person_res;
}
/**
* gets the mitarbeiter information corresponding to a user
* @access private
* @param integer $uid the userID used to get the mitarbeiter information
* @return array all the mitarbeiter informaion corresponding to a userID
*/
private function getMitarbeiterInfo($uid)
{
$this->MitarbeiterModel->addSelect(["kurzbz", "telefonklappe", "alias", "ort_kurzbz"]);
$this->MitarbeiterModel->addJoin("tbl_benutzer", "tbl_benutzer.uid = tbl_mitarbeiter.mitarbeiter_uid");
$mitarbeiter_res = $this->MitarbeiterModel->load($uid);
if (isError($mitarbeiter_res)) {
show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($mitarbeiter_res));
} else {
$mitarbeiter_res = hasData($mitarbeiter_res) ? getData($mitarbeiter_res)[0] : null;
}
return $mitarbeiter_res;
}
/**
* gets the telefon information corresponding to a user
* @access private
* @param integer $uid the userID used to get the telefon information
* @return array all the telefon informaion corresponding to a userID
*/
private function getTelefonInfo($uid)
{
$this->MitarbeiterModel->addSelect(["kontakt"]);
$this->MitarbeiterModel->addJoin("tbl_kontakt", "tbl_mitarbeiter.standort_id = tbl_kontakt.standort_id");
$this->MitarbeiterModel->addLimit(1);
$telefon_res = $this->MitarbeiterModel->loadWhere(["mitarbeiter_uid" => $uid, "kontakttyp" => "telefon"]);
if (isError($telefon_res)) {
show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($telefon_res));
}
$telefon_res = hasData($telefon_res) ? getData($telefon_res)[0] : null;
return $telefon_res;
}
/**
* gets the student information corresponding to a user
* @access private
* @param integer $uid the userID used to get the student information
* @return array all the student informaion corresponding to a userID
*/
private function getStudentInfo($uid)
{
$this->StudentModel->addSelect(['tbl_studiengang.bezeichnung as studiengang', 'tbl_student.semester', 'tbl_student.verband', 'tbl_student.gruppe', 'tbl_student.matrikelnr as personenkennzeichen']);
$this->StudentModel->addJoin('tbl_studiengang', "tbl_studiengang.studiengang_kz=tbl_student.studiengang_kz");
$student_res = $this->StudentModel->load([$uid]);
if (isError($student_res)) {
show_error("was not able to query the table public.tbl_student:" . getData($student_res));
}
$student_res = hasData($student_res) ? getData($student_res)[0] : null;
return $student_res;
}
/**
* gets the profil updates corresponding to a user
* @access private
* @param integer $uid the userID used to get the profil updates
* @return array all the profil updates corresponding to a userID
*/
private function getProfilUpdates($uid)
{
$profilUpdates = $this->ProfilUpdateModel->getProfilUpdatesWhere(['uid' => $uid]);
if (isError($profilUpdates)) {
show_error("was not able to query the table public.tbl_profil_update:" . getData($profilUpdates));
}
$profilUpdates = hasData($profilUpdates) ? getData($profilUpdates) : null;
return $profilUpdates;
}
/**
* gets the Matrikelnummer corresponding to a user
* @access private
* @param integer $uid the userID used to get the Matrikelnummer
* @return integer the Matrikelnummer corresponding to a userID
*/
private function getMatrikelNummer($uid)
{
$this->BenutzerModel->addSelect(["matr_nr"]);
$this->BenutzerModel->addJoin("tbl_person", "person_id");
$matr_res = $this->BenutzerModel->load([$uid]);
if (isError($matr_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($matr_res));
}
$matr_res = hasData($matr_res) ? getData($matr_res)[0] : [];
return $matr_res;
}
/**
* gets the Zutrittsgruppen corresponding to a user
* @access private
* @param integer $uid the userID used to get the Zutrittsgruppen
* @return array all the Zutrittsgruppen corresponding to a userID
*/
private function getZutrittsgruppen($uid)
{
$this->BenutzergruppeModel->addSelect(['bezeichnung']);
$this->BenutzergruppeModel->addJoin('tbl_gruppe', 'gruppe_kurzbz');
$zutrittsgruppe_res = $this->BenutzergruppeModel->loadWhere(array("uid" => $uid, "zutrittssystem" => true));
if (isError($zutrittsgruppe_res)) {
show_error("was not able to query the table public.tbl_benutzergruppe:" . getData($zutrittsgruppe_res));
}
$zutrittsgruppe_res = hasData($zutrittsgruppe_res) ? getData($zutrittsgruppe_res) : null;
return $zutrittsgruppe_res;
}
/**
* gets the address information corresponding to a user
* @access private
* @param integer $uid the userID used to get the address information
* @return array all the address information corresponding to a userID
*/
private function getAdressenInfo($pid)
{
$adresse_res = $this->AdresseModel->addSelect(["adresse_id", "strasse", "tbl_adressentyp.bezeichnung as typ", "plz", "ort", "zustelladresse", "gemeinde", "nation"]);
$adresse_res = $this->AdresseModel->addOrder("zustelladresse", "DESC");
$adresse_res = $this->AdresseModel->addJoin("tbl_adressentyp", "typ=adressentyp_kurzbz");
$adresse_res = $this->AdresseModel->loadWhere(["person_id" => $pid]);
if (isError($adresse_res)) {
show_error("was not able to query the table public.tbl_adresse:" . getData($adresse_res));
}
$adresse_res = hasData($adresse_res) ? getData($adresse_res) : null;
return $adresse_res;
}
/**
* gets the kontakt information corresponding to a user
* @access private
* @param integer $uid the userID used to get the kontakt information
* @return array all the kontakt information corresponding to a userID
*/
private function getKontaktInfo($pid)
{
$this->KontaktModel->addSelect(['kontakttyp', 'kontakt_id', 'kontakt', 'tbl_kontakt.anmerkung', 'tbl_kontakt.zustellung']);
$this->KontaktModel->addJoin('public.tbl_standort', 'standort_id', 'LEFT');
$this->KontaktModel->addJoin('public.tbl_firma', 'firma_id', 'LEFT');
$this->KontaktModel->addOrder('kontakttyp, kontakt, tbl_kontakt.updateamum, tbl_kontakt.insertamum');
$kontakte_res = $this->KontaktModel->loadWhere(['person_id' => $pid]);
if (isError($kontakte_res)) {
show_error("was not able to query the table public.tbl_kontakt:" . getData($kontakte_res));
}
$kontakte_res = hasData($kontakte_res) ? getData($kontakte_res) : null;
return $kontakte_res;
}
/**
* gets the date of issue of the FH access card corresponding to a user
* @access private
* @param integer $uid the userID used to get the date of issue of the FH access card
* @return string the date of issue of the FH access card corresponding to a userID
*/
private function getZutrittskarteDatum($uid)
{
$zutrittskarte_ausgegebenam = $this->BetriebsmittelpersonModel->getBetriebsmittelByUid($uid, "Zutrittskarte");
if (isError($zutrittskarte_ausgegebenam)) {
show_error("was not able to query the table wavi.tbl_bentriebsmittelperson:" . getData($zutrittskarte_ausgegebenam));
}
$zutrittskarte_ausgegebenam = hasData($zutrittskarte_ausgegebenam) ? getData($zutrittskarte_ausgegebenam)[0]->ausgegebenam : null;
//? formats date from 01-01-2000 to 01.01.2000
$zutrittskarte_ausgegebenam = str_replace("-", ".", $zutrittskarte_ausgegebenam);
return $zutrittskarte_ausgegebenam;
}
}
@@ -0,0 +1,814 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
/**
*
*/
class ProfilUpdate extends Auth_Controller
{
public static $STATUS_PENDING = NULL;
public static $STATUS_ACCEPTED = NULL;
public static $STATUS_REJECTED = NULL;
public static $TOPICS = [];
public function __construct()
{
parent::__construct([
'index' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
'id' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
'getProfilUpdateWithPermission' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
'acceptProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'],
'denyProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'],
'show' => ['basis/cis:r'],
'insertProfilRequest' => ['basis/cis:rw'],
'updateProfilRequest' => ['basis/cis:rw'],
'deleteProfilRequest' => ['basis/cis:rw'],
'selectProfilRequest' => ['basis/cis:r'],
'insertFile' => ['basis/cis:rw'],
'getProfilRequestFiles' => ['basis/cis:r'],
'getStatus' => ['basis/cis:r'],
'getTopic' => ['basis/cis:r'],
]);
$this->load->config('cis');
$this->load->model('person/Profil_update_model', 'ProfilUpdateModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->load->model('person/Adressentyp_model', 'AdressenTypModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('system/Sprache_model', 'SpracheModel');
$this->load->model('person/Profil_update_status_model', 'ProfilUpdateStatusModel');
$this->load->model('person/Profil_update_topic_model', 'ProfilUpdateTopicModel');
// Load language phrases
$this->loadPhrases(
array(
'ui',
'global',
'person',
'profil',
'profilUpdate'
)
);
$this->load->library('DmsLib');
$this->load->library('PermissionLib');
//? put the uid and pid inside the controller for reusability
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
// setup the ProfilUpdate states
$this->ProfilUpdateStatusModel->addSelect(['status_kurzbz']);
$status_kurzbz = $this->ProfilUpdateStatusModel->load();
if (hasData($status_kurzbz)) {
list($status_pending, $status_accepted, $status_rejected) = getData($status_kurzbz);
self::$STATUS_PENDING = $status_pending->status_kurzbz;
self::$STATUS_ACCEPTED = $status_accepted->status_kurzbz;
self::$STATUS_REJECTED = $status_rejected->status_kurzbz;
}
// setup the ProfilUpdate topics
$this->ProfilUpdateTopicModel->addSelect(['topic_kurzbz']);
$topic_kurzbz = $this->ProfilUpdateTopicModel->load();
if (hasData($topic_kurzbz)) {
foreach (getData($topic_kurzbz) as $topic) {
self::$TOPICS[$topic->topic_kurzbz] = $topic->topic_kurzbz;
}
}
}
public function index()
{
$this->load->view('Cis/ProfilUpdate');
}
public function id($profil_update_id = null)
{
$this->load->view('Cis/ProfilUpdate', ['profil_update_id' => $profil_update_id]);
}
public function getStatus()
{
echo json_encode([self::$STATUS_PENDING => self::$STATUS_PENDING, self::$STATUS_ACCEPTED => self::$STATUS_ACCEPTED, self::$STATUS_REJECTED => self::$STATUS_REJECTED]);
}
public function getTopic()
{
echo json_encode(self::$TOPICS);
}
private function sendEmail_onProfilUpdate_response($uid, $topic, $status)
{
if($this->config->item('cis_send_profil_update_mails') === false)
{
return;
}
$this->load->helper('hlp_sancho_helper');
$email = $uid . "@" . DOMAIN;
function languageQuery($language)
{
return "select index from public.tbl_sprache where sprache = '" + $language + "'";
}
$this->ProfilUpdateStatusModel->addSelect(["bezeichnung_mehrsprachig[(" . languageQuery('German') . ")] as status_de", "bezeichnung_mehrsprachig[(" . languageQuery('English') . ")] as status_en"]);
$status_translation = $this->ProfilUpdateStatusModel->loadWhere(["status_kurzbz" => $status]);
if (isError($status_translation)) {
show_error($this->p->t('profilUpdate', 'ProfilUpdateStatusTranslationError'));
}
$status_translation = hasData($status_translation) ? getData($status_translation)[0] : null;
if (isset($status_translation)) {
$mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => APP_ROOT . 'Cis/Profil'], $email, ("Profil Änderung " . $this->p->t('profilUpdate', 'pending')));
if (!$mail_res) {
show_error($this->p->t('profilUpdate', 'profilUpdate_email_error'));
}
}
}
private function sendEmail_onProfilUpdate_insertion($uid, $profil_update_id, $topic)
{
if($this->config->item('cis_send_profil_update_mails') === false)
{
return;
}
$this->load->helper('hlp_sancho_helper');
$emails = [];
$isMitarbeiter_res = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($isMitarbeiter_res)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error'));
}
$isMitarbeiter_res = getData($isMitarbeiter_res);
//! if the $uid is a mitarbeiter and student, only the hr is notified by email
if ($isMitarbeiter_res) {
//? user is not a student therefore he is a mitarbeiter, send email to Personalverwaltung
//? use constant variable MAIL_GST to mail to the personalverwaltung
$this->MitarbeiterModel->addSelect([TRUE]);
$this->MitarbeiterModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid");
//? check if the the userID is a mitarbeiter and if the benutzer is active
$res = $this->MitarbeiterModel->loadWhere(["public.tbl_mitarbeiter.mitarbeiter_uid" => $uid, "public.tbl_benutzer.aktiv" => TRUE]);
if (isError($res)) {
show_error("was not able to query the mitarbeiter and benutzer by the uid: " . $uid);
}
if (hasData($res)) {
array_push($emails, MAIL_GST);
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error'));
}
} else {
//? if it is not a mitarbeiter, check whether it is a student and send email to studiengang
$isStudent_res = $this->StudentModel->isStudent($uid);
if (isError($isStudent_res)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_studentCheck_error'));
}
$isStudent_res = getData($isStudent_res);
if ($isStudent_res) {
//? Send email to the Studiengangsassistentinnen
$this->StudentModel->addSelect(["public.tbl_studiengang.email"]);
$this->StudentModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_student.student_uid");
$this->StudentModel->addJoin("public.tbl_prestudent", "public.tbl_benutzer.person_id = public.tbl_prestudent.person_id");
$this->StudentModel->addJoin("public.tbl_prestudentstatus", "public.tbl_prestudentstatus.prestudent_id = public.tbl_prestudent.prestudent_id");
$this->StudentModel->addJoin("public.tbl_studiengang", "public.tbl_studiengang.studiengang_kz = public.tbl_prestudent.studiengang_kz");
//* check if the benutzer itself is active
//* check if the student status is Student or Diplomand (active students)
$this->StudentModel->db->where_in("public.tbl_prestudentstatus.status_kurzbz", ['Student', 'Diplomand']);
$res = $this->StudentModel->loadWhere(["public.tbl_benutzer.aktiv" => TRUE, "public.tbl_student.student_uid" => $uid]);
if (isError($res)) {
show_error(getData($res));
} else {
$res = hasData($res) ? getData($res) : [];
foreach ($res as $emailObj) {
array_push($emails, $emailObj->email);
}
}
}
}
$mail_res = [];
//? sending email
foreach ($emails as $email) {
array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => APP_ROOT . 'Cis/ProfilUpdate/id/' . $profil_update_id], $email, ("Profil Änderung von " . $uid)));
}
foreach ($mail_res as $m_res) {
if (!$m_res) {
show_error($this->p->t('profilUpdate', 'profilUpdate_email_error'));
}
}
}
public function show($dms_id)
{
$profil_update = $this->ProfilUpdateModel->loadWhere(['attachment_id' => $dms_id]);
$profil_update = hasData($profil_update) ? getData($profil_update)[0] : null;
//? checks if an profil update exists with the dms_id requested from the user
if ($profil_update) {
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($profil_update->uid));
$is_student_profil_update = getData($this->StudentModel->isStudent($profil_update->uid));
if (
$this->permissionlib->isBerechtigt('student/stammdaten:r') && $is_student_profil_update ||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten:r') && $is_mitarbeiter_profil_update ||
$this->uid == $profil_update->uid
) {
// Get file to be downloaded from DMS
$newFilename = $this->uid . "/document_" . $dms_id;
$download = $this->dmslib->download($dms_id);
if (isError($download))
return $download;
// Download file
$this->outputFile(getData($download));
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
return;
}
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_dms_error'));
return;
}
}
public function insertFile($replace)
{
$replace = json_decode($replace);
if (!count($_FILES)) {
echo json_encode([]);
return;
}
//? if replace is set it contains the profil_update_id in which the attachment_id has to be replaced
if (isset($replace)) {
$this->ProfilUpdateModel->addSelect(["attachment_id"]);
$profilUpdate = $this->ProfilUpdateModel->load([$replace]);
if (isError($profilUpdate)) {
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_loading_error')));
}
//? get the attachmentID
$dms_id = hasData($profilUpdate) ? getData($profilUpdate)[0]->attachment_id : null;
//? delete old dms_file of Profil Update
$this->deleteOldVersionFile($dms_id);
}
$files = $_FILES['files'];
$file_count = count($files['name']);
$res = [];
for ($i = 0; $i < $file_count; $i++) {
$_FILES['files']['name'] = $files['name'][$i];
$_FILES['files']['type'] = $files['type'][$i];
$_FILES['files']['tmp_name'] = $files['tmp_name'][$i];
$_FILES['files']['error'] = $files['error'][$i];
$_FILES['files']['size'] = $files['size'][$i];
$dms = [
"kategorie_kurzbz" => "profil_aenderung",
"version" => 0,
"name" => $_FILES['files']['name'],
"mimetype" => $_FILES['files']['type'],
"beschreibung" => $this->uid . " Profil Änderung",
"insertvon" => $this->uid,
"insertamum" => "NOW()",
];
$tmp_res = $this->dmslib->upload($dms, 'files', array("jpg", "png", "pdf"));
$tmp_res = hasData($tmp_res) ? getData($tmp_res) : null;
array_push($res, $tmp_res);
}
echo json_encode($res);
}
public function selectProfilRequest()
{
$_GET = json_decode($this->input->raw_input_stream, true);
$uid = $this->input->get('uid');
$id = $this->input->get('id');
$whereClause = ['uid' => $this->uid];
if (isset($uid))
$whereClause['uid'] = $uid;
if (isset($id))
$whereClause['id'] = $id;
$res = $this->ProfilUpdateModel->getProfilUpdatesWhere($whereClause);
$res = hasData($res) ? getData($res) : null;
echo json_encode($res);
}
public function getProfilRequestFiles()
{
$id = json_decode($this->input->raw_input_stream);
$this->ProfilUpdateModel->addSelect(["attachment_id"]);
$attachmentID = $this->ProfilUpdateModel->load([$id]);
if (isError($attachmentID)) {
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_loading_error')));
}
//? get the attachmentID
$dms_id = hasData($attachmentID) ? getData($attachmentID)[0]->attachment_id : null;
//? get the name to the file
$this->DmsVersionModel->addSelect(["name", "dms_id"]);
$attachment = $this->DmsVersionModel->load([$dms_id, 0]);
if (isError($attachment)) {
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error')));
}
$attachment = hasData($attachment) ? getData($attachment) : null;
//? returns {name:..., dms_id:...}
echo json_encode($attachment);
}
public function insertProfilRequest()
{
$json = json_decode($this->input->raw_input_stream);
$payload = $json->payload;
$identifier = property_exists($json->payload, "kontakt_id") ? "kontakt_id" : (property_exists($json->payload, "adresse_id") ? "adresse_id" : null);
$data = ["topic" => $json->topic, "uid" => $this->uid, "requested_change" => json_encode($payload), "insertamum" => "NOW()", "insertvon" => $this->uid, "status" => self::$STATUS_PENDING ?: 'Pending'];
//? insert fileID in the dataset if sent with post request
if (isset($json->fileID)) {
$data['attachment_id'] = $json->fileID;
}
//? loops over all updateRequests from a user to validate if the new request is valid
$res = $this->ProfilUpdateModel->getProfilUpdatesWhere(["uid" => $this->uid]);
if (isError($res)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_loading_error'));
}
$res = hasData($res) ? getData($res) : null;
//? the user cannot delete a zustelladresse/kontakt
if (isset($payload->delete) && $payload->{$identifier == "kontakt_id" ? "zustellung" : "zustelladresse"}) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error')));
return;
}
//? if the user tries to delete a adresse, checks whether the adresse is a heimatadresse, if so an error is raised
if (isset($payload->delete) && $identifier == "adresse_id") {
$adr = $this->AdresseModel->load($payload->$identifier);
$adr = getData($adr)[0];
if ($adr->heimatadresse) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error')));
return;
}
}
if ($res) {
$pending_changes = array_filter($res, function ($element) {
return $element->status == (self::$STATUS_PENDING ?: "Pending");
});
foreach ($pending_changes as $update_request) {
$existing_change = $update_request->requested_change;
//? the user can add as many new kontakte/adressen as he likes
if (!isset($payload->add) && property_exists($existing_change, $identifier) && property_exists($payload, $identifier) && $existing_change->$identifier == $payload->$identifier) {
//? the kontakt_id / adresse_id of a change has to be unique
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_changeTwice_error')));
return;
}
//? if it is not updating any kontakt/adresse, the topic has to be unique
elseif (!$identifier && $update_request->topic == $json->topic) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_changeTopicTwice_error', ['0' => $update_request->topic])));
return;
}
}
}
$insertID = $this->ProfilUpdateModel->insert($data);
if (isError($insertID)) {
show_error(getData($insertID));
} else {
$insertID = hasData($insertID) ? getData($insertID) : null;
//? sends emails to the correspondents of the $uid
$this->sendEmail_onProfilUpdate_insertion($this->uid, $insertID, $json->topic);
echo json_encode(success($insertID));
}
}
public function updateProfilRequest()
{
$json = json_decode($this->input->raw_input_stream);
$updateData = ["requested_change" => json_encode($json->payload), "updateamum" => "NOW()", "updatevon" => $this->uid];
if (isset($json->fileID)) {
$updateData['attachment_id'] = json_decode($json->fileID);
}
$updateID = $this->ProfilUpdateModel->update([$json->ID], $updateData);
//? insert fileID in the dataset if sent with post request
if (isError($updateID)) {
//catch error
} else {
$updateID = hasData($updateID) ? getData($updateID)[0] : null;
//TODO: should an email be sent to the responsable people when the user changes his profil update
echo json_encode(success($updateID));
}
}
public function deleteProfilRequest()
{
$json = json_decode($this->input->raw_input_stream);
$delete_res = $this->ProfilUpdateModel->delete([$json]);
echo json_encode($delete_res);
}
public function getProfilUpdateWithPermission($status = null)
{
// early return if no status has been passed as argument
if (!isset($status)) {
echo json_encode($this->ProfilUpdateModel->getProfilUpdateWithPermission());
return;
}
// get the sprache of the user
$sprachenIndex = $this->SpracheModel->loadWhere(["sprache" => getUserLanguage()]);
$sprachenIndex = hasData($sprachenIndex) ? getData($sprachenIndex)[0]->index : null;
if (isset($sprachenIndex) && isset($status)) {
// get the corresponding status kurz_bz primary key out of the translation
$status = $this->ProfilUpdateStatusModel->execReadOnlyQuery("select * from public.tbl_profil_update_status where ? = ANY(bezeichnung_mehrsprachig)", [$status]);
$status = hasData($status) ? getData($status)[0]->status_kurzbz : null;
$res = $this->ProfilUpdateModel->getProfilUpdateWithPermission(isset($status) ? ['status' => $status] : null);
echo json_encode($res);
}
}
private function getOE_from_student($student_uid)
{
//? returns the oe_einheit eines Studenten
$query = "SELECT public.tbl_studiengang.oe_kurzbz
FROM public.tbl_student
JOIN public.tbl_studiengang ON tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
WHERE public.tbl_student.student_uid = ?;";
$res = $this->StudentModel->execReadOnlyQuery($query, [$student_uid]);
if (!isSuccess($res)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_loadingOE_error'));
}
$res = hasData($res) ? getData($res) : [];
$res = array_map(
function ($item) {
return $item->oe_kurzbz;
},
$res
);
return $res;
}
public function acceptProfilRequest()
{
$_POST = json_decode($this->input->raw_input_stream, true);
$id = $this->input->post('profil_update_id', true);
$uid = $this->input->post('uid', true);
//? fetching person_id using UID
$personID = $this->PersonModel->getByUid($uid);
$personID = hasData($personID) ? getData($personID)[0]->person_id : null;
$status_message = $this->input->post('status_message', true);
$topic = $this->input->post('topic', true);
//! somehow the xss check converted boolean false to empty string
$requested_change = $this->input->post('requested_change');
//! check for required information
if (!isset($id) || !isset($uid) || !isset($personID) || !isset($requested_change) || !isset($topic)) {
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_requiredInformation_error')));
}
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($uid));
$is_student_profil_update = getData($this->StudentModel->isStudent($uid));
//? check if the permissions are set correctly
if (
$this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) && $is_student_profil_update ||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") && $is_mitarbeiter_profil_update
) {
if (is_array($requested_change) && array_key_exists("adresse_id", $requested_change)) {
$insertID = $this->handleAdresse($requested_change, $personID);
$insertID = hasData($insertID) ? getData($insertID) : null;
if (isset($insertID)) {
$requested_change['adresse_id'] = $insertID;
$update_res = $this->updateRequestedChange($id, $requested_change);
if (isError($update_res)) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_address_error', [$insertID])));
return;
}
}
} else if (is_array($requested_change) && array_key_exists("kontakt_id", $requested_change)) {
$insertID = $this->handleKontakt($requested_change, $personID);
$insertID = hasData($insertID) ? getData($insertID) : null;
if (isset($insertID)) {
$requested_change['kontakt_id'] = $insertID;
$update_res = $this->updateRequestedChange($id, $requested_change);
if (isError($update_res)) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_kontakt_error', [$insertID])));
return;
}
}
} else {
switch ($topic) {
// mapping phrasen to database columns to make the update with the correct column names
case self::$TOPICS['Titel']:
$topic = "titelpre";
break;
case self::$TOPICS['Postnomen']:
$topic = "titelpost";
break;
case self::$TOPICS['Vorname']:
$topic = "vorname";
break;
case self::$TOPICS['Nachname']:
$topic = "nachname";
break;
default:
show_error($this->p->t('profilUpdate', 'profilUpdate_topic_error', [$topic]));
return;
}
$result = $this->PersonModel->update($personID, [$topic => $requested_change["value"]]);
if (isError($result)) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_insert_error')));
return;
}
}
$this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_ACCEPTED);
echo json_encode($this->setStatusOnUpdateRequest($id, self::$STATUS_ACCEPTED, $status_message, $requested_change));
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
}
}
public function denyProfilRequest()
{
$_POST = json_decode($this->input->raw_input_stream, true);
$id = $this->input->post('profil_update_id', true);
$uid = $this->input->post('uid', true);
$topic = $this->input->post('topic', true);
$status_message = $this->input->post('status_message', true);
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($uid));
$is_student_profil_update = getData($this->StudentModel->isStudent($uid));
if (
$this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) && $is_student_profil_update ||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") && $is_mitarbeiter_profil_update
) {
$this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_REJECTED);
echo json_encode($this->setStatusOnUpdateRequest($id, self::$STATUS_REJECTED, $status_message));
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
}
}
private function updateRequestedChange($id, $requested_change)
{
return $this->ProfilUpdateModel->update([$id], ['requested_change' => json_encode($requested_change)]);
}
private function setStatusOnUpdateRequest($id, $status, $status_message)
{
return $this->ProfilUpdateModel->update([$id], ["status" => $status, "status_timestamp" => "NOW()", "status_message" => $status_message]);
}
private function deleteOldVersionFile($dms_id)
{
if (!isset($dms_id)) {
return;
}
//? collect all the results of the deleted versions in an array
$res = array();
//? delete all the different versions of the dms_file
$dmsVersions = $this->DmsVersionModel->loadWhere(["dms_id" => $dms_id]);
$dmsVersions = hasData($dmsVersions) ? getData($dmsVersions) : null;
if (isset($dmsVersions)) {
$zwischen_res = array_map(function ($item) {
return $item->version;
}, $dmsVersions);
foreach ($zwischen_res as $version) {
array_push($res, $this->DmsVersionModel->delete([$dms_id, $version]));
}
} else {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error')));
}
//? returns a result for each deleted dms_file
return $res;
}
private function handleKontakt($requested_change, $personID)
{
$kontakt_id = $requested_change["kontakt_id"];
//? removes the kontakt_id because we don't want to update the kontakt_id in the database
unset($requested_change["kontakt_id"]);
//! ADD
if (array_key_exists('add', $requested_change) && $requested_change['add']) {
//? removes add flag
unset($requested_change['add']);
$requested_change['person_id'] = $personID;
$requested_change['insertamum'] = "NOW()";
$requested_change['insertvon'] = getAuthUID();
$insertID = $this->KontaktModel->insert($requested_change);
$insert_kontakt_id = $insertID;
if (isError($insert_kontakt_id)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_insertKontakt_error'));
}
$insert_kontakt_id = hasData($insert_kontakt_id) ? getData($insert_kontakt_id) : null;
if ($insert_kontakt_id) {
$this->handleDupplicateZustellKontakte($requested_change['zustellung'], $insert_kontakt_id);
}
}
//! DELETE
elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) {
$this->KontaktModel->delete($kontakt_id);
}
//! UPDATE
else {
$requested_change['updateamum'] = "NOW()";
$requested_change['updatevon'] = getAuthUID();
$update_kontakt_id = $this->KontaktModel->update($kontakt_id, $requested_change);
if (isError($update_kontakt_id)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_updateKontakt_error'));
}
$update_kontakt_id = hasData($update_kontakt_id) ? getData($update_kontakt_id) : null;
if ($update_kontakt_id) {
$this->handleDupplicateZustellKontakte($requested_change['zustellung'], $update_kontakt_id);
}
}
return isset($insertID) ? $insertID : null;
}
private function handleAdresse($requested_change, $personID)
{
$this->AdressenTypModel->addSelect(["adressentyp_kurzbz"]);
$adr_kurzbz = $this->AdressenTypModel->loadWhere(["bezeichnung" => $requested_change['typ']]);
$adr_kurzbz = hasData($adr_kurzbz) ? getData($adr_kurzbz)[0]->adressentyp_kurzbz : null;
//? replace the address_typ with its correct kurzbz foreign key
$requested_change['typ'] = $adr_kurzbz;
$adresse_id = $requested_change["adresse_id"];
//? removes the adresse_id because we don't want to update the kontakt_id in the database
unset($requested_change["adresse_id"]);
//! ADD
if (array_key_exists('add', $requested_change) && $requested_change['add']) {
//? removes add flag
unset($requested_change['add']);
$requested_change['insertamum'] = "NOW()";
$requested_change['insertvon'] = getAuthUID();
$requested_change['person_id'] = $personID;
//TODO: zustelladresse, heimatadresse, rechnungsadresse und nation werden nicht beachtet
$insertID = $this->AdresseModel->insert($requested_change);
$insert_adresse_id = $insertID;
if (isError($insert_adresse_id)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_insertAdresse_error'));
}
$insert_adresse_id = hasData($insert_adresse_id) ? getData($insert_adresse_id) : null;
if ($insert_adresse_id) {
$this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $insert_adresse_id);
}
}
//! DELETE
elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) {
$this->AdresseModel->delete($adresse_id);
}
//! UPDATE
else {
$requested_change['updateamum'] = "NOW()";
$requested_change['updatevon'] = getAuthUID();
$update_adresse_id = $this->AdresseModel->update($adresse_id, $requested_change);
if (isError($update_adresse_id)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_updateAdresse_error'));
}
$update_adresse_id = hasData($update_adresse_id) ? getData($update_adresse_id) : null;
if ($update_adresse_id) {
$this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $update_adresse_id);
}
}
return isset($insertID) ? $insertID : null;
}
private function handleDupplicateZustellKontakte($zustellung, $kontakt_id)
{
if ($zustellung) {
$this->PersonModel->addSelect("public.tbl_kontakt.kontakt_id");
$this->PersonModel->addJoin("public.tbl_kontakt", "public.tbl_kontakt.person_id = public.tbl_person.person_id");
$zustellKontakteArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustellung" => TRUE]);
if (!isSuccess($zustellKontakteArray)) {
return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellkontakte_error'));
}
$zustellKontakteArray = hasData($zustellKontakteArray) ? getData($zustellKontakteArray) : null;
if ($zustellung && count($zustellKontakteArray) > 0) {
$zustellKontakteArray = array_filter($zustellKontakteArray, function ($kontakt) use ($kontakt_id) {
return $kontakt->kontakt_id != $kontakt_id;
});
foreach ($zustellKontakteArray as $kontakt) {
$this->KontaktModel->update($kontakt->kontakt_id, ["zustellung" => FALSE]);
}
}
}
}
private function handleDupplicateZustellAdressen($zustellung, $adresse_id)
{
if ($zustellung) {
$this->PersonModel->addSelect("public.tbl_adresse.adresse_id");
$this->PersonModel->addJoin("public.tbl_adresse", "public.tbl_adresse.person_id = public.tbl_person.person_id");
$zustellAdressenArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustelladresse" => TRUE]);
if (!isSuccess($zustellAdressenArray)) {
return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellAdressen_error'));
}
$zustellAdressenArray = hasData($zustellAdressenArray) ? getData($zustellAdressenArray) : null;
if ($zustellung && count($zustellAdressenArray) > 0) {
$zustellAdressenArray = array_filter($zustellAdressenArray, function ($adresse) use ($adresse_id) {
return $adresse->adresse_id != $adresse_id;
});
foreach ($zustellAdressenArray as $adresse) {
$this->AdresseModel->update($adresse->adresse_id, ["zustelladresse" => FALSE]);
}
}
}
}
}
+167
View File
@@ -0,0 +1,167 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Pub extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'bild' => ['basis/cis:r']
)
);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @param string $source [person|akte]
* @param integer $id
* @return void
*/
public function bild($source, $id)
{
$this->load->model('person/Person_model', 'PersonModel');
$person_id_user = '';
$serverzugriff = false;
// Wenn das Bild direkt aufgerufen wird, ist eine Authentifizierung erforderlich
// Wenn es vom Server selbst aufgerufen wird, ist keine Auth. notwendig
// (z.B. fuer die Erstellung von PDFs)
if ($_SERVER['REMOTE_ADDR'] != $_SERVER['SERVER_ADDR']) {
// Wenn Session gesetzt ist, keine Abfrage, da diese Personen noch keine UID haben
if (isset($_SESSION['incoming/user'])) { // Von Incomingtool
$result = $this->PersonModel->loadWhere([
'zugangscode' => $_SESSION['incoming/user']
]);
if (hasData($result))
$person_id_user = current(getData($result))->person_id;
} elseif (isset($_SESSION['prestudent/user'])) { // Von Prestudententool
$result = $this->PersonModel->loadWhere([
'zugangscode' => $_SESSION['prestudent/user']
]);
if (hasData($result))
$person_id_user = current(getData($result))->person_id;
} elseif (isset($_SESSION['bewerbung/personId'])) { // Von Bewerbungstool
$person_id_user = $_SESSION['bewerbung/personId'];
} else {
$person_id_user = getAuthPersonId();
}
} else {
$serverzugriff = true;
}
// Default Bild (Dummy Profilbild)
$cTmpHEX = base64_encode(file_get_contents(FHCPATH . 'skin/images/profilbild_dummy.jpg'));
if ($source == 'person' && $id) {
$foto_gesperrt = false;
// Person laden und Fotosperre überprüfen
$result = $this->PersonModel->load($id);
if (hasData($result)) {
$person = current(getData($result));
if ($person->foto_sperre) {
// Wenn der User selbst darauf zugreift darf er das Bild sehen
$foto_gesperrt = ($person_id_user != $id);
} elseif (!$person_id_user && !$serverzugriff) {
$foto_gesperrt = true;
}
if ($person->foto && !$foto_gesperrt) {
$cTmpHEX = base64_decode($person->foto);
}
}
}
if($source == 'akte' && $id != '')
{
$this->load->model('crm/Akte_model', 'AkteModel');
$this->AkteModel->addJoin('public.tbl_person', 'person_id');
$result = $this->AkteModel->loadWhere([
'person_id' => $id,
'dokument_kurzbz' => 'Lichtbil'
]);
if (hasData($result)) {
$foto_gesperrt = false;
$akte = current(getData($result));
if ($akte->foto_sperre) {
// Wenn der User selbst darauf zugreift darf er das Bild sehen
$foto_gesperrt = ($person_id_user != $id);
} elseif (!$person_id_user && !$serverzugriff) {
$foto_gesperrt = true;
}
// Wenn das Foto nicht im Inhalt steht wird aus aus dem DMS geladen
if (!$akte->inhalt && $akte->dms_id) {
$this->load->model('content/Dms_model', 'DmsModel');
$this->load->model('content/DmsVersion_model', 'DmsVersionModel');
$this->DmsModel->addJoin('campus.tbl_dms_version', 'dms_id');
$this->DmsModel->addOrder('version', 'DESC');
$this->DmsModel->addLimit(1);
$result = $this->DmsModel->load($akte->dms_id);
if (!hasData($result))
die('Kein Dokument vorhanden');
$dms = current(getData($result));
$filename = DMS_PATH . $dms->filename;
$this->DmsVersionModel->update([
'dms_id' => $dms->dms_id,
'version' => $dms->version
], [
'letzterzugriff' => date('c')
]);
if (file_exists($filename)) {
$handle = fopen($filename, "r");
if ($handle) {
while (!feof($handle)) {
$akte->inhalt .= fread($handle, 8192);
}
fclose($handle);
} else {
echo 'Fehler: Datei konnte nicht geoeffnet werden';
}
} else {
echo 'Die Datei existiert nicht';
}
}
if ($akte->inhalt && !$foto_gesperrt) {
$cTmpHEX = $akte->inhalt;
}
}
}
// die bilder werden, sofern es funktioniert, in jpg umgewandelt da es sonst zu fehlern beim erstellen
// von pdfs kommen kann.
$im = @imagecreatefromstring(base64_decode($cTmpHEX));
if ($im) {
@ob_clean();
header("Content-type: image/jpeg");
exit(imagejpeg($im));
} else {
// bei manchen Bildern funktioniert die konvertierung nicht
// diese werden dann einfach so angezeigt.
@ob_clean();
header("Content-type: image/gif");
exit($cTmpHEX);
}
}
}
@@ -3,30 +3,28 @@
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Test VBform Vue Component
*
*/
class TestVBform extends Auth_Controller
class Stundenplan extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'index' => 'system/developer:r'
)
);
parent::__construct([
'index' => ['basis/cis:r']
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Everything has a beginning
* @return void
*/
public function index()
{
$this->load->view('system/logs/testVBform.php');
$this->load->view('Cis/Stundenplan');
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Cis4 extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'index' => 'basis/cis:r'
)
);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
$this->load->model('person/Person_model','PersonModel');
$personData = getData($this->PersonModel->getByUid(getAuthUID()))[0];
$viewData = array(
'uid' => getAuthUID(),
'name' => $personData->vorname,
'person_id' => $personData->person_id
);
$this->load->view('CisVue/Dashboard.php',['viewData' => $viewData]);
}
}
+127
View File
@@ -0,0 +1,127 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
/**
*
*/
class Cms extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'content' => 'basis/cis:r',
'getNews' => 'basis/cis:r',
'getNewsRowCount' => 'basis/cis:r',
'getRoomInformation' => 'basis/cis:r',
'news' => 'basis/cis:r'
)
);
// Loads Libraries
$this->load->library('CmsLib');
// Loads phrases system
$this->loadPhrases([
'global'
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @param int $content_id
* @param int $version
* @param string $sprache
* @param boolean $sichtbar
*
* @return void
*/
public function content($content_id, $version = null, $sprache = null, $sichtbar = true)
{
// return early if the content_id for the content is missing
if (!isset($content_id))
$this->terminateWithError("content_id is missing");
$content = $this->ContentModel->load($content_id);
if (isError($content))
$this->terminateWithError(getError($content));
$content = getData($content);
if (NULL === $content)
$this->terminateWithError("Content not found");
$content = current($content);
$this->load->view('CisVue/Cms/Content', ['content_id' => $content_id, 'template_kurzbz' => $content->template_kurzbz, 'version' => $version, 'sprache' => $sprache, 'sichtbar' => $sichtbar]);
}
/**
* @param boolean $infoscreen
* @param string | null $studiengang_kz
* @param int | null $semester
* @param boolean $mischen
* @param string $titel
* @param boolean $edit
* @param boolean $sichtbar
*
* @return void
*/
public function news($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true)
{
$this->load->view('CisVue/Cms/Content', ['infoscreen' => $infoscreen, 'studiengang_kz' => $studiengang_kz, 'semester' => $semester, 'mischen' => $mischen, 'titel' => $titel, 'edit' => $edit, 'sichtbar' => $sichtbar]);
}
public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true)
{
$get_page = intval($this->input->get('page', true));
$get_page_size = intval($this->input->get('page_size', true));
if ($get_page) {
$page = $get_page;
}
if ($get_page_size) {
$page_size = $get_page_size;
} else {
$page_size = $this->page_size;
}
$news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size);
if (isError($news)) {
$this->terminateWithJsonError(getError($news));
}
$news = hasData($news) ? getData($news) : null;
if ($news) {
echo json_encode($news);
} else {
show_error("News: No data found");
}
}
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;
$num_rows = $this->NewsModel->countNewsWithContent(getSprache(), $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $this->page_size, $all, $mischen);
if (isError($num_rows)) {
$this->terminateWithJsonError(getError($num_rows));
}
$num_rows = hasData($num_rows) ? getData($num_rows) : null;
if ($num_rows) {
echo json_encode($num_rows);
} else {
show_error("News number rows: No data found");
}
}
public function getRoomInformation($ort_kurzbz){
$this->load->view('CisVue/Cms/RoomInformation',['ort_kurzbz'=>$ort_kurzbz]);
}
}
@@ -0,0 +1,45 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Dashboard extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'index' => 'dashboard/benutzer:r'
)
);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
$this->load->model('person/Person_model','PersonModel');
$begruesung = $this->PersonModel->getFirstName(getAuthUID());
if(isError($begruesung))
{
show_error("name couldn't be loaded for username ".getAuthUID());
}
$begruesung = getData($begruesung);
$viewData = array(
'name' => $begruesung
);
$this->load->view('CisVue/Dashboard.php', ['viewData' => $viewData]);
}
}
-16
View File
@@ -1,16 +0,0 @@
<?php
if ( !defined("PHPUNIT_TEST") ) {
show_404();
}
class Test extends CI_Controller
{
public function index()
{
// Yep... This is all we need.
ini_set('error_reporting', E_ALL); // or error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
}
}
@@ -0,0 +1,145 @@
<?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 Ampeln extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'open' => self::PERM_LOGGED,
'all' => self::PERM_LOGGED,
'confirm' => self::PERM_LOGGED,
'alleAmpeln' => self::PERM_LOGGED,
]);
$this->load->model('content/Ampel_model', 'AmpelModel');
$this->load->model('system/Sprache_model', 'SpracheModel');
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* confirms ampel and inserts ampel_id in public.tbl_ampel_benutzer_bestaetigt
* @access public
*
*/
public function confirm($ampel_id)
{
$this->load->library('form_validation');
$this->form_validation->set_data(['ampel_id'=> $ampel_id]);
$this->form_validation->set_rules('ampel_id', 'Ampel ID', 'required|integer');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
// load Ampel_benutzer_bestaetigt_model to confirm the ampel
$this->load->model('content/Ampel_Benutzer_Bestaetigt_model', 'AmpelBenutzerBestaetigtModel');
$insert_into_result = $this->AmpelBenutzerBestaetigtModel->insert(["ampel_id"=> $ampel_id, "uid"=> $this->uid]);
$insert_into_result = $this->getDataOrTerminateWithError($insert_into_result);
$this->terminateWithSuccess($insert_into_result);
}
/**
* queries active and not confirmed ampeln by the user
* @access public
*
*/
public function open()
{
$userAmpeln = array();
// fetch active ampeln
$activeAmpeln = $this->AmpelModel->openActive($this->uid, false);
$activeAmpeln = $this->getDataOrTerminateWithError($activeAmpeln);
foreach ($activeAmpeln as $ampel) {
// only include non confirmed active ampeln in the result
if (!$ampel->bestaetigt) {
// check if the user was assigned to the ampel
$zugeteilt = $this->AmpelModel->isZugeteilt($this->uid, $ampel->benutzer_select);
$zugeteilt = $this->getDataOrTerminateWithError($zugeteilt);
if($zugeteilt) $userAmpeln[] = $ampel;
}
}
$this->terminateWithSuccess($userAmpeln);
}
/**
* queries all ampeln of the user
* @access public
*
*/
public function all()
{
$userAmpeln = array();
$ampel_result = $this->AmpelModel->active(false, $this->uid);
$ampel_result = $this->getDataOrTerminateWithError($ampel_result);
foreach ($ampel_result as $ampel) {
// check if the ampel was assigned to the user
$zugeteilt = $this->AmpelModel->isZugeteilt($this->uid, $ampel->benutzer_select);
$zugeteilt = $this->getDataOrTerminateWithError($zugeteilt);
if ($zugeteilt) $userAmpeln[] = $ampel;
}
$this->terminateWithSuccess($userAmpeln);
}
/**
* queries all ampeln that were assigned to the user until start of first work day
* @access public
*
*/
public function alleAmpeln()
{
//fetch all ampeln
$alle_ampeln = $this->AmpelModel->alleAmpeln($this->uid);
$alle_ampeln = $this->getDataOrTerminateWithError($alle_ampeln);
$alle_ampeln = array_map(function ($ampel) {
// check if ampel is confirmed by user
$confirmedByUser = $this->AmpelModel->isConfirmed($ampel->ampel_id, $this->uid);
$ampel->bestaetigt = $confirmedByUser;
return $ampel;
}, $alle_ampeln);
$this->terminateWithSuccess($alle_ampeln);
}
}
@@ -0,0 +1,109 @@
<?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 Bookmark extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getBookmarks' => self::PERM_LOGGED,
'delete' => self::PERM_LOGGED,
'insert' => self::PERM_LOGGED,
]);
$this->load->model('dashboard/Bookmark_model', 'BookmarkModel');
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* gets the bookmarks associated to a user
* @access public
* @return void
*/
public function getBookmarks()
{
$bookmarks = $this->BookmarkModel->loadWhere(["uid"=>$this->uid]);
$bookmarks = $this->getDataOrTerminateWithError($bookmarks);
$this->terminateWithSuccess($bookmarks);
}
/**
* deletes bookmark from associated user
* @access public
* @return void
*/
public function delete($bookmark_id)
{
$bookmark = $this->BookmarkModel->load($bookmark_id);
$bookmark = current($this->getDataOrTerminateWithError($bookmark));
// only delete bookmark if the user is the owner of the bookmark
if($bookmark->uid == $this->uid || $this->permissionlib->isBerechtigt('admin')){
$delete_result = $this->BookmarkModel->delete($bookmark_id);
$delete_result = $this->getDataOrTerminateWithError($delete_result);
$this->terminateWithSuccess($delete_result);
}else{
$this->_outputAuthError(['delete' => ['admin:rw']]);
}
}
/**
* inserts new bookmark into the bookmark table
* @access public
* @return void
*/
public function insert()
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_rules('url', 'URL', 'required|valid_url|max_length[511]');
$this->form_validation->set_rules('title', 'Title', 'required|max_length[255]');
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
$url = $this->input->post('url',true);
$title = $this->input->post('title',true);
$tag = $this->input->post('tag', true);
$insert_into_result = $this->BookmarkModel->insert(['uid'=>$this->uid, 'url'=>$url, 'title'=>$title,'tag'=>$tag, 'insertvon'=>$this->uid, 'updateamum'=>NULL, 'updatevon'=>NULL]);
$insert_into_result = $this->getDataOrTerminateWithError($insert_into_result);
$this->terminateWithSuccess($insert_into_result);
}
}
@@ -0,0 +1,195 @@
<?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');
/**
* This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end)
* Provides data to the ajax get calls about the searchbar component
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class Cms extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
// NOTE(chris): additional permission checks will be done in SearchBarLib
parent::__construct([
'ContentID' => self::PERM_LOGGED,
'getOrtKurzbzContent' => self::PERM_LOGGED,
'content' => self::PERM_LOGGED,
'news' => self::PERM_LOGGED,
'getNewsRowCount' => self::PERM_LOGGED,
'getNews' => self::PERM_LOGGED,
]);
$this->load->model('content/News_model', 'NewsModel');
// setting up the papgination_size
$this->page_size = 10;
$this->load->library('CmsLib');
// Loads phrases system
$this->loadPhrases([
'global'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* fetches the content with the content_id and additional parameters
*/
public function content()
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('content_id','Content ID','required|is_natural');
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
// getting the get parameters
$content_id = $this->input->get("content_id",TRUE);
$version = $this->input->get("version",TRUE);
$sprache = $this->input->get("sprache",TRUE);
$sichtbar = $this->input->get("sichtbar",TRUE);
$content = $this->cmslib->getContent($content_id, $version, $sprache, $sichtbar);
$content = $this->getDataOrTerminateWithError($content);
$this->terminateWithSuccess($content);
}
/**
* Gets a JSON body via HTTP POST and provides the parameters
*/
public function ContentID()
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('ort_kurzbz', 'Ort', 'required');
if ($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
$ort_kurzbz = $this->input->get('ort_kurzbz',TRUE);
$content_id = $this->OrtModel->getContentID($ort_kurzbz);
$content_id = current($this->getDataOrTerminateWithError($content_id))->content_id;
$this->terminateWithSuccess($content_id);
}
//todo: there is the method news and getNews but only one should exist
public function news()
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('limit','Limit','required|is_natural_no_zero');
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
$this->load->model('content/news_model', 'NewsModel');
$limit = $this->input->get('limit',TRUE);
//query the news
$news = $this->NewsModel->getAll($limit);
//get the data or terminate with error
$news = $this->getDataOrTerminateWithError($news);
// collect the content of the news
foreach($news as $news_element){
$this->addMeta("content_id",$news_element->content_id);
//todo: quick fix, for query builder error when fetching content
$this->NewsModel->resetQuery();
$content = $this->cmslib->getContent($news_element->content_id);
$content = getData($content);
$news_element->content_obj = $content;
}
$withContent = function($news) {
return $news->content_obj != null;
};
$newsWithContent = array_filter($news, $withContent);
$this->terminateWithSuccess($newsWithContent);
}
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');
$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());
// getting the GET parameters
$page = intval($this->input->get('page', true));
$page_size = intval($this->input->get('page_size', true));
// default value for the page_size is 10
$page_size = $page_size ?? 10;
$news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size);
$news = $this->getDataOrTerminateWithError($news);
$this->addMeta('test', $this->p->t('global', 'studiengangsleitung'));
$this->addMeta('phrases', json_decode($this->p->getJson()));
$this->terminateWithSuccess($news);
}
}
@@ -0,0 +1,85 @@
<?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 Lehre extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'lvStudentenMail' => self::PERM_LOGGED,
'LV' => self::PERM_LOGGED,
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* constructs the emails of the groups from a lehrveranstaltung
*/
public function lvStudentenMail()
{
$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);
}
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$studentenMails = $this->LehreinheitModel->getStudentenMail($lehreinheit_id);
$studentenMails = $this->getDataOrTerminateWithError($studentenMails);
//convert array of objects into array of strings
$studentenMails = array_map(function($element){
return $element->mail;
}, $studentenMails);
$this->terminateWithSuccess($studentenMails);
}
public function LV($studiensemester_kurzbz, $lehrveranstaltung_id)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID(), $studiensemester_kurzbz, getUserLanguage(), $lehrveranstaltung_id);
$result = current($this->getDataOrTerminateWithError($result));
$this->terminateWithSuccess($result);
}
}
@@ -0,0 +1,532 @@
<?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');
use CI3_Events as Events;
/**
* This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end)
* Provides data to the ajax get calls about the searchbar component
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class LvMenu extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getLvMenu' => self::PERM_LOGGED
]);
$this->load->model("ressource/Mitarbeiter_model");
$this->load->model("education/Lehreinheit_model");
$this->load->model("education/Lehrveranstaltung_model");
$this->load->model("organisation/Studiengang_model");
$this->load->model("accounting/Vertrag_model");
$this->load->model("system/Variable_model");
$this->load->model("person/Benutzergruppe_model");
$this->load->model("education/Lvangebot_model");
$this->load->model("ressource/Lehretools_model");
$this->load->library("PermissionLib", null, 'PermissionLib');
$this->load->library("PhrasesLib");
$this->loadPhrases(array('global', 'lehre'));
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
*
*/
public function getLvMenu($lvid, $studiensemester_kurzbz)
{
// return early if parameters are missing
if(!isset($lvid) || !isset($studiensemester_kurzbz))
$this->terminateWithError('Missing parameters', self::ERROR_TYPE_GENERAL);
// get the sprache
$sprache = getUserLanguage();
// get the user
if (!$user=getAuthUID())
$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);
}
// definition of user_is_allowed_to_upload
$user_is_allowed_to_upload=false;
$angezeigtes_stsem = $studiensemester_kurzbz;
// load lehrveranstaltung
$lvres = $this->Lehrveranstaltung_model->load($lvid);
if(!hasData($lvres))
{
$this->terminateWithError('LV ' . $lvid . ' not found.');
}
$lv = (getData($lvres))[0];
// define studiengang_kz / semester / lehrverzeichnis
$studiengang_kz = $lv->studiengang_kz;
$semester = $lv->semester;
$short = $lv->lehreverzeichnis;
// load studiengang
$stgres = $this->Studiengang_model->load($lv->studiengang_kz);
if(!hasData($stgres))
{
$this->terminateWithError('Stg ' . $lv->studiengang_kz . ' nof found.');
}
$stg = (getData($stgres))[0];
$kurzbz = strtoupper($stg->typ . $stg->kurzbz);
$short_name = $lv->bezeichnung;
$short_short_name = $lv->lehreverzeichnis;
// angemeldet
$angemeldet = true;
if(defined('CIS_LEHRVERANSTALTUNG_WENNANGEMELDET_DETAILS_ANZEIGEN') && CIS_LEHRVERANSTALTUNG_WENNANGEMELDET_DETAILS_ANZEIGEN && !$is_lector)
{
$angemeldet = false;
$lesres = $this->Lehreinheit_model->getLehreinheitenForStudentAndStudienSemester(
$lvid, $user, $angezeigtes_stsem
);
if(hasData($lesres) && count(getData($lesres)) > 0)
$angemeldet = true;
}
// lehrfach
$lehrfach_id='';
if(defined('CIS_LEHRVERANSTALTUNG_LEHRFACH_ANZEIGEN') && CIS_LEHRVERANSTALTUNG_LEHRFACH_ANZEIGEN)
{
// Wenn der eingeloggte User zu einer der Lehreinheiten zugeteilt ist
// wird zusätzlich das Lehrfach der Lehreinheit angezeigt.
if($is_lector )
{
$result = $this->Lehreinheit_model->getLehrfachIdMitarbeiter($angezeigtes_stsem,$user,$lvid);
}
else
{
$result = $this->Lehreinheit_model->getLehrfachIdStudierender($angezeigtes_stsem,$user,$lvid);
}
// Wenn die LV mehrere verschiedenen Lehrfaecher hat, und der User zu mehreren davon zugeteilt ist
// wird das Lehrfach nicht angezeigt damit es nicht zu verwirrungen kommt.
if( ($lehrfaecher = getData($result)) && count($lehrfaecher)==1 && ($lehrfach = $lehrfaecher[0]))
{
$lehrfach_id=$lehrfach->lehrfach_id;
}
}
// lektor der lv
$lektor_der_lv=false;
$leinfores = $this->Lehreinheit_model->getLehreinheitInfo($lvid,$angezeigtes_stsem,$lehrfach_id);
$db_result = hasData($leinfores) ? getData($leinfores) : array();
foreach($db_result as $row_lector)
{
// Lektor wird erst angezeigt wenn der Auftrag erteilt wurde
if (defined('CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON')
&& CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON != '')
{
if (!$this->Vertrag_model->isVertragErteiltLV($lvid, $angezeigtes_stsem, $row_lector->uid))
{
continue;
}
}
if($user == $row_lector->uid)
{
$lektor_der_lv=true;
$user_is_allowed_to_upload=true;
}
// style of the link
if($row_lector->lvleiter === true)
$style='style="font-weight: bold"';
else
$style='';
}
//Berechtigungen auf Fachbereichsebene
$lehrfach_oe_kurzbz_arr = array();
$fbres = $this->Lehrveranstaltung_model->getBerechtigungenAufFachberechsebene($lvid, $angezeigtes_stsem);
$fbs = (hasData($fbres)) ? getData($fbres) : array();
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))
{
$user_is_allowed_to_upload=true;
}
}
// FH-Core Menu Logic
// ##########################################################################################
$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
// ##########################################################################################
$params = [
'sprache'=>$sprache,
//'p'=>$p,
'ci_p'=> $this->p,
//'db'=>$db,
'user'=>$user,
'is_lector'=>$is_lector,
'user_is_allowed_to_upload'=>$user_is_allowed_to_upload,
//'rechte'=>$rechte,
'angezeigtes_stsem'=>$angezeigtes_stsem,
//'lehreinheit'=>$lehreinheit,
'lv_obj'=>$lv,
'lv'=>$lv,
'lvid'=>$lvid,
'studiengang_kz'=>$studiengang_kz,
'semester'=>$semester,
'short'=>$short,
'stg_obj'=>$stg,
'kurzbz'=>$kurzbz,
'short_name'=>$short_name,
'short_short_name'=>$short_short_name,
//'dir_name'=>$dir_name,
'angemeldet'=>$angemeldet,
'lehrfach_id'=>$lehrfach_id,
'lektor_der_lv'=>$lektor_der_lv,
'lehrfach_oe_kurzbz_arr'=>$lehrfach_oe_kurzbz_arr,
];
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
if( !array_key_exists('c4_link',$row) || !array_key_exists('c4_icon',$row)){
unset($menu[$key]);
continue;
}
// fills pos array to sort the menu
$pos[$key] = $row['position'];
}
array_multisort($pos, SORT_ASC, SORT_NUMERIC, $menu);
// HTTP response
// ##########################################################################################
$this->terminateWithSuccess($menu);
}
private function fhc_menu_digitale_anwesenheiten(&$menu, $angemeldet, $studiengang_kz, $semester, $lvid, $angezeigtes_stsem){
// DIGITALE ANWESENHEITEN
if (defined('CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN') && CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN && $angemeldet) {
$menu[] = array
(
'id' => 'core_menu_digitale_anwesenheitslisten',
'position' => '50',
'name' => $this->p->t('lehre', 'digiAnw'),
'c4_icon' => base_url('skin/images/button_kreuzerltool.png'),
'c4_link' => base_url("index.ci.php/extensions/FHC-Core-Anwesenheiten/?stg_kz=$studiengang_kz&sem=$semester&lvid=$lvid&sem_kurzbz=$angezeigtes_stsem&nav=false"),
'c4_linkList' => []
);
}
}
private function fhc_menu_lvinfo(&$menu, $lvid, $studiengang_kz, $lektor_der_lv, $is_lector, $lehrfach_oe_kurzbz_arr){
// LVINFO
if(!defined('CIS_LEHRVERANSTALTUNG_LVINFO_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_LVINFO_ANZEIGEN)
{
$c4_linkList=array();
// Bearbeiten Button anzeigen wenn Lektor der LV und bearbeiten fuer Lektoren aktiviert ist
// Oder Berechtigung zum Bearbeiten eingetragen ist
if((!defined('CIS_LEHRVERANSTALTUNG_LVINFO_LEKTOR_EDIT') && $lektor_der_lv)
|| (defined('CIS_LEHRVERANSTALTUNG_LVINFO_LEKTOR_EDIT') && CIS_LEHRVERANSTALTUNG_LVINFO_LEKTOR_EDIT==true && $lektor_der_lv)
|| $this->PermissionLib->isBerechtigt('lehre/lvinfo',$studiengang_kz)
|| $this->PermissionLib->isBerechtigtMultipleOe('lehre/lvinfo', $lehrfach_oe_kurzbz_arr)
)
{
$c4_linkList[]= [$this->p->t('lehre', 'lvInfoBearbeiten'), 'ects/index.php?lvid='.$lvid];
}
elseif ($is_lector)
{
$c4_linkList[]= ["Bearbeiten der LV-Infos derzeit gesperrt",'#'];
}
$menu[]=array
(
'id'=>'core_menu_lvinfo',
'position'=>'10',
'name'=>$this->p->t('lehre', 'lehrveranstaltungsinformation'),
'icon'=>'../../../skin/images/button_lvinfo.png',
'link'=>'',
'c4_icon'=> base_url('skin/images/button_lvinfo.png'),
'c4_link'=>'',
'c4_linkList'=>$c4_linkList
);
}
}
private function fhc_menu_feedback(&$menu, $angemeldet, $lvid){
//FEEDBACK
if((!defined('CIS_LEHRVERANSTALTUNG_FEEDBACK_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_FEEDBACK_ANZEIGEN) && $angemeldet)
{
$menu[]=array
(
'id'=>'core_menu_feedback',
'position'=>'60',
'name'=>$this->p->t('lehre', 'feedback'),
'c4_icon'=> base_url('skin/images/button_feedback.png'),
'c4_link'=> base_url('feedback.php?lvid='.$lvid),
);
}
}
private function fhc_menu_gesamtnote(&$menu, $angemeldet, $lvid, $lv_obj, $is_lector, $angezeigtes_stsem){
//Gesamtnote
if($is_lector && ((!defined('CIS_LEHRVERANSTALTUNG_GESAMTNOTE_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_GESAMTNOTE_ANZEIGEN) && $angemeldet))
{
if($lv_obj->benotung)
{
$menu[]=array
(
'id'=>'core_menu_gesamtnote',
'position'=>'80',
'name'=>$this->p->t('lehre', 'gesamtnote'),
'c4_icon'=> base_url('skin/images/button_endnote.png'),
'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))
);
}
else
{
$menu[]=array
(
'id'=>'core_menu_gesamtnote',
'position'=>'80',
'name'=>$this->p->t('lehre', 'gesamtnote'),
'c4_icon'=>base_url('skin/images/button_endnote.png'),
'c4_link'=>'#',
'c4_linkList'=>[[$this->p->t('lehre', 'noteneingabedeaktiviert'),'#']],
);
}
}
}
private function fhc_menu_emailStudierende(&$menu, $user, $angemeldet, $lvid, $angezeigtes_stsem){
// Email an Studierende
if((!defined('CIS_LEHRVERANSTALTUNG_MAILSTUDIERENDE_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_MAILSTUDIERENDE_ANZEIGEN) && $angemeldet)
{
$mailto='mailto:';
$c4_linkList=array();
$studentMailsRes = $this->Lehrveranstaltung_model->getStudentEMail($lvid, $angezeigtes_stsem);
// get the data of the database result and map the array of objects to their object property
$studentMails = $this->getDataOrTerminateWithError($studentMailsRes, 'No student mails found');
$nomail='';
$variablesres = $this->Variable_model->getVariables($user);
$variables = (hasData($variablesres)) ? getData($variablesres) : array();
foreach ($studentMails as $row)
{
if($row->gruppe_kurzbz != '')
{
$bngrp_uids = $this->Benutzergruppe_model->getUids($row->gruppe_kurzbz, $angezeigtes_stsem);
if(count($bngrp_uids) > 0)
{
if(!$row->mailgrp)
{
$nomail = $row->gruppe_kurzbz . ' ';
}
else
{
$mailto .= mb_strtolower($row->gruppe_kurzbz . '@'
. DOMAIN . $variables['emailadressentrennzeichen']);
}
}
}
else
{
$mailto .= mb_strtolower($row->stg_typ . $row->stg_kurzbz
. $row->semester . trim($row->verband) . trim($row->gruppe)
. '@' . DOMAIN . $variables['emailadressentrennzeichen']);
}
}
if($nomail != '')
{
$c4_linkList[] = array(
$this->p->t('lehre', 'keinMailverteiler', array('nomail' => $nomail)),
'#'
);
$link_onclick = 'alert(\''.$this->p->t('lehre', 'keinMailverteiler', array('nomail' => $nomail)) . '\');';
}
else
{
$link_onclick = '';
}
$menu[]=array
(
'id'=>'core_menu_mailanstudierende',
'position'=>'100',
'name'=>$this->p->t('lehre', 'mail'),
'c4_icon'=>base_url('skin/images/button_feedback.png'),
'c4_icon2' => 'fa-regular fa-envelope',
'c4_link'=>$mailto,
'c4_linkList'=>$c4_linkList,
'link_onclick'=>$link_onclick
);
}
}
private function fhc_menu_abmeldung(&$menu, $user, $is_lector, $lvid, $angezeigtes_stsem){
if(!defined('CIS_LEHRVERANSTALTUNG_ABMELDUNG_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_ABMELDUNG_ANZEIGEN)
{
if(!$is_lector)
{
$gruppen = $this->Lvangebot_model->AbmeldungMoeglich($lvid, $angezeigtes_stsem, $user);
if(count($gruppen) > 0)
{
$menu[]=array
(
'id'=>'core_menu_abmeldung',
'position'=>'120',
'name'=>$this->p->t('lehre', 'abmelden'),
'c4_icon'=>base_url('skin/images/button_studiupload.png'),
'c4_link'=>base_url('abmeldung.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem)),
);
}
}
}
}
private function fhc_menu_lehretools(&$menu, $lvid, $angezeigtes_stsem, $sprache){
//Anzeigen von zusaetzlichen Lehre-Tools
$lehretools = $this->Lehretools_model->getTools($lvid, $angezeigtes_stsem, $sprache);
foreach($lehretools as $row)
{
$menu[] = array(
'id' => 'core_menu_lehretools_' . $row->lehre_tools_id,
'position' => '1000',
'name' => $row->bezeichnung,
'c4_icon' => base_url('cms/dms.php?id='.$row->logo_dms_id),
'c4_link' => $row->basis_url,
);
}
}
private function fhc_menu_anrechnungStudent(&$menu, $lvid, $angezeigtes_stsem){
// Anerkennung nachgewiesener Kenntnisse (Anrechnung) - Anzeige fuer Studenten
if((!defined('CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN)
&& $this->PermissionLib->isBerechtigt('student/anrechnung_beantragen'))
{
$menu[]=array
(
'id' => 'core_menu_anerkennungNachgewiesenerKenntnisse',
'position' => '128',
'name' => $this->p->t('lehre', 'anrechnung'),
'c4_icon' => base_url('skin/images/button_listen.png'),
'c4_icon2' => 'fa-regular fa-folder-open',
'c4_link' => base_url('cis.php/lehre/anrechnung/RequestAnrechnung?studiensemester='.urlencode($angezeigtes_stsem).'&lv_id='.urlencode($lvid))
);
}
}
private function fhc_menu_anrechnungLector(&$menu, $angezeigtes_stsem){
// Anerkennung nachgewiesener Kenntnisse (Anrechnung) - Anzeige fuer LektorInnen
if((!defined('CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN)
&& $this->PermissionLib->isBerechtigt('lehre/anrechnung_empfehlen'))
{
$menu[]=array
(
'id' => 'core_menu_anerkennungNachgewiesenerKenntnisse_empfehlen',
'position' => '128',
'name' => $this->p->t('lehre', 'anrechnungen'),
'c4_icon'=> base_url('skin/images/button_listen.png'),
'c4_icon2' => 'fa-regular fa-folder-open',
'c4_link' => base_url('cis.php/lehre/anrechnung/ReviewAnrechnungUebersicht?studiensemester='.urlencode($angezeigtes_stsem))
);
}
}
}
@@ -0,0 +1,95 @@
<?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');
/**
* This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end)
* Provides data to the ajax get calls about the searchbar component
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class Ort extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
// NOTE(chris): additional permission checks will be done in SearchBarLib
parent::__construct([
'ContentID' => self::PERM_LOGGED,
'getOrtKurzbzContent' => self::PERM_LOGGED,
]);
$this->load->model('ressource/Ort_model', 'OrtModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Gets a JSON body via HTTP POST and provides the parameters
*/
public function ContentID()
{
// if error
//$this->terminateWithError(SearchBarLib::ERROR_WRONG_JSON, self::ERROR_TYPE_GENERAL);
$ort_kurzbz = $this->input->get('ort_kurzbz',TRUE);
if(!$ort_kurzbz){
$this->terminateWithError("missing ort_kurzbz parameter", self::ERROR_TYPE_GENERAL);
}
$result = $this->OrtModel->getContentID($ort_kurzbz);
if(isError($result)){
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$result = hasData($result) ? current(getData($result)) : null;
$this->terminateWithSuccess($result->content_id ?? NULL);
}
/**
* @param int $version
* @param string $sprache
* @param boolean $sichtbar
*
* @return $content
*/
public function getOrtKurzbzContent($version = null, $sprache = null, $sichtbar = true)
{
$content_id = $this->input->get("content_id",TRUE);
$this->load->library('CmsLib');
$content = $this->cmslib->getContent($content_id, $version, $sprache, $sichtbar);
if (isError($content))
$this->terminateWithError(getError($content), self::ERROR_TYPE_GENERAL);
$content = hasData($content) ? getData($content) : null;
$this->terminateWithSuccess($content);
}
}
@@ -28,8 +28,13 @@ class Phrasen extends FHCAPI_Controller
public function __construct()
{
parent::__construct([
'loadModule' => self::PERM_ANONYMOUS
'loadModule' => self::PERM_ANONYMOUS,
'setLanguage' => self::PERM_ANONYMOUS,
'getLanguage' => self::PERM_ANONYMOUS,
'getAllLanguages' => self::PERM_ANONYMOUS,
]);
$this->load->helper('hlp_language');
}
//------------------------------------------------------------------------------------------------------------------
@@ -43,4 +48,37 @@ class Phrasen extends FHCAPI_Controller
$this->load->library('PhrasesLib', [$module], 'pj');
$this->terminateWithSuccess(json_decode($this->pj->getJSON()));
}
}
public function setLanguage()
{
$postParams = $this->getPostJSON();
$language = $postParams->language;
$categories = $postParams->categories;
setUserLanguage($language);
$this->load->library('PhrasesLib', array($categories, $language), 'p');
$phrases = $this->p->setPhrases($categories, $language);
$this->terminateWithSuccess($phrases);
}
// gets the langauge of the currently logged in user session and otherwhise the system language
public function getLanguage()
{
$lang = getUserLanguage();
$this->terminateWithSuccess($lang);
}
// gets all languages that are set as active in the database
public function getAllLanguages()
{
$langs = getDBActiveLanguages();
$langs = $this->getDataOrTerminateWithError($langs);
$langs = array_map(function($lang){
return $lang->sprache;
}, $langs);
$this->terminateWithSuccess($langs);
}
}
@@ -0,0 +1,695 @@
<?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 Profil extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getView' => self::PERM_LOGGED,
'fotoSperre' => self::PERM_LOGGED,
'getGemeinden' => self::PERM_LOGGED,
'getAllNationen' => self::PERM_LOGGED,
'isMitarbeiter' => self::PERM_LOGGED,
]);
$this->load->library('PermissionLib');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
$this->load->model('ressource/Betriebsmittelperson_model', 'BetriebsmittelpersonModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Profil_update_model', 'ProfilUpdateModel');
$this->load->model('content/DmsVersion_model', 'DmsVersionModel');
//? put the uid and pid inside the controller for reusability
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* function that returns the data used for the corresponding view
* the client side parses the @param $uid and calls this function to get the data to the correct view
* @access public
* @param boolean $uid the userID used to identify which information should be retrieved for which view
* @return stdClass all the data corresponding to a view of a user
*/
public function getView($uid)
{
$res = new stdClass();
$editAllowed = getAuthUID() == $uid || $this->permissionlib->isBerechtigt('admin');
// if parsing the URL did not found a UID then the UID of the logged in user is used
if ($uid == "Profil" || $uid == $this->uid) {
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($this->uid);
if (isError($isMitarbeiter)) {
show_error("error while checking if UID: " . $this->uid . " is a mitarbeiter");
}
$isMitarbeiter = getData($isMitarbeiter);
if ($isMitarbeiter) {
$res->view = "MitarbeiterProfil";
$res->data = $this->mitarbeiterProfil();
$res->data->pid = $this->pid;
} else {
$res->view = "StudentProfil";
$res->data = $this->studentProfil();
$res->data->pid = $this->pid;
}
// editing your own profil - true
$editAllowed = true;
}
// UID is availabe when accessing Profil/View/:uid
else {
$this->PersonModel->addSelect(["person_id"]);
$pid = $this->PersonModel->getByUid($uid);
if (isError($pid)) {
show_error("error while trying to update table public.tbl_person while searching for a person with UID: " . $uid);
}
$pid = hasData($pid) ? getData($pid)[0] : null;
if (!$pid) {
show_error("Person with UID: " . $uid . " does not exist");
}
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($isMitarbeiter)) {
show_error("error while checking if UID: " . $uid . " is a mitarbeiter");
}
$isMitarbeiter = getData($isMitarbeiter);
if ($isMitarbeiter) {
$res->view = "ViewMitarbeiterProfil";
$res->data = $this->viewMitarbeiterProfil($uid);
} else {
$res->view = "ViewStudentProfil";
$res->data = $this->viewStudentProfil($uid);
}
}
$res->data->editAllowed = $editAllowed;
$this->terminateWithSuccess($res);
}
/**
* update column foto_sperre in public.tbl_person
* @access public
* @param boolean $value new value for the column
* @return boolean the new value added to the column in public.tbl_person
*/
public function fotoSperre($value)
{
if(!isset($value)){
$this->terminateWithError("Missing parameter", self::ERROR_TYPE_GENERAL);
}
$res = $this->PersonModel->update($this->pid, ["foto_sperre" => $value]);
if (isError($res)) {
show_error("error while trying to update table public.tbl_person");
}
$this->PersonModel->addSelect("foto_sperre");
$res = $this->PersonModel->load($this->pid);
if (isError($res)) {
show_error("error while trying to query table public.tbl_person");
}
$res = $this->getDataOrTerminateWithError($res);
$this->terminateWithSuccess(current($res));
}
/**
* gets all nations in the table bis.tbl_nation
*
* @access public
* @return array all the nations in table bis.tbl_nation
*/
public function getAllNationen()
{
// load the nationen from the database
$this->load->model('codex/Nation_model', "NationModel");
$this->NationModel->addSelect(["nation_code as code", "langtext"]);
$nation_res = $this->NationModel->load();
if (isError($nation_res)) {
$this->terminateWithError("error while trying to query table codex.tbl_nation", self::ERROR_TYPE_GENERAL);
}
$nation_res = $this->getDataOrTerminateWithError($nation_res);
$this->terminateWithSuccess($nation_res);
}
public function getGemeinden($nation, $zip)
{
if(!isset($nation) || !isset($zip)){
echo json_encode(error("Missing parameters"));
return;
}
$this->load->model('codex/Gemeinde_model', "GemeindeModel");
$gemeinde_res = $this->GemeindeModel->getGemeindeByPlz($zip);
if (isError($gemeinde_res)) {
$this->terminateWithError(getError($gemeinde_res),self::ERROR_TYPE_GENERAL);
}
$gemeinde_res = $this->getDataOrTerminateWithError($gemeinde_res);
/* $gemeinde_res = array_map(function ($obj) {
return $obj->ortschaftsname;
}, $gemeinde_res); */
$this->terminateWithSuccess($gemeinde_res);
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
/**
* function that returns the data used for viewing another mitarbeiter profile
* @access private
* @param integer $uid the userID to retrieve the mitarbeiter data
* @return stdClass restricted mitarbeiter data
*/
private function viewMitarbeiterProfil($uid)
{
$mailverteiler_res = $this->getMailverteiler($uid);
$benutzer_funktion_res = $this->getBenutzerFunktion($uid);
$benutzer_res = $this->getBenutzerAlias($uid);
$person_res = $this->getPersonInfo($uid);
$mitarbeiter_res = $this->getMitarbeiterInfo($uid);
$telefon_res = $this->getTelefonInfo($uid);
$res = new stdClass();
$res->username = $uid;
//? Person Info
foreach ($person_res as $key => $val) {
$res->$key = $val;
}
//? Mitarbeiter Info
foreach ($mitarbeiter_res as $key => $val) {
$res->$key = $val;
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $uid . "@" . DOMAIN;
$extern_email = array();
$extern_email["type"] = "alias";
$extern_email["email"] = $benutzer_res->alias . "@" . DOMAIN;
$res->emails = array($intern_email, $extern_email);
$res->funktionen = $benutzer_funktion_res;
$res->mailverteiler = $mailverteiler_res;
$res->standort_telefon = isset($telefon_res) ? $telefon_res->kontakt : null;
return $res;
}
/**
* function that returns the data used for viewing another student profile
* @access private
* @param integer $uid the userID to retrieve the student data
* @return stdClass restricted student data
*/
private function viewStudentProfil($uid)
{
$mailverteiler_res = $this->getMailverteiler($uid);
$person_res = $this->getPersonInfo($uid);
$student_res = $this->getStudentInfo($uid);
$matr_res = $this->getMatrikelNummer($uid);
$res = new stdClass();
$res->username = $uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Student Information
foreach ($student_res as $key => $value) {
$res->$key = $value;
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $uid . "@" . DOMAIN;
$res->emails = [$intern_email];
$res->matrikelnummer = $matr_res->matr_nr;
$res->mailverteiler = $mailverteiler_res;
return $res;
}
/**
* checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php)
* @access public
* @param $uid the userID used to check if it is a mitarbeiter
* @return boolean
*/
public function isMitarbeiter($uid)
{
if(!$uid) $this->terminateWithError("No uid provided", self::ERROR_TYPE_GENERAL);
$result = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($result)) {
$this->terminateWithError("error when calling Mitarbeiter_model function isMitarbeiter with uid " . $uid, self::ERROR_TYPE_GENERAL);
}
$result = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($result);
}
/**
* function that returns the data used for the mitarbeiter profile
* @access private
* @return stdClass mitarbeiter data
*/
private function mitarbeiterProfil()
{
$zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid);
$adresse_res = $this->getAdressenInfo($this->pid);
$kontakte_res = $this->getKontaktInfo($this->pid);
$mailverteiler_res = $this->getMailverteiler($this->uid);
$person_res = $this->getPersonInfo($this->uid, true);
$benutzer_funktion_res = $this->getBenutzerFunktion($this->uid);
$betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid);
$profilUpdates = $this->getProfilUpdates($this->uid);
$telefon_res = $this->getTelefonInfo($this->uid);
$mitarbeiter_res = $this->getMitarbeiterInfo($this->uid);
$res = new stdClass();
$res->username = $this->uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Mitarbeiter Information
foreach ($mitarbeiter_res as $key => $value) {
$res->$key = $value;
}
$res->adressen = $adresse_res;
$res->zutrittsdatum = $zutrittskarte_ausgegebenam;
$res->kontakte = $kontakte_res;
$res->mittel = $betriebsmittelperson_res;
$res->mailverteiler = $mailverteiler_res;
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $this->uid . "@" . DOMAIN;
$extern_email = array();
$extern_email["type"] = "alias";
$extern_email["email"] = $mitarbeiter_res->alias . "@" . DOMAIN;
$res->emails = [$intern_email, $extern_email];
$res->funktionen = $benutzer_funktion_res;
$res->standort_telefon = $telefon_res;
$res->profilUpdates = $profilUpdates;
return $res;
}
/**
* function that returns the data used for the student profile
* @access private
* @return stdClass student data
*/
private function studentProfil()
{
$betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid);
$kontakte_res = $this->getKontaktInfo($this->pid);
$zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid);
$adresse_res = $this->getAdressenInfo($this->pid);
$mailverteiler_res = $this->getMailverteiler($this->uid);
$person_res = $this->getPersonInfo($this->uid, true);
$zutrittsgruppe_res = $this->getZutrittsgruppen($this->uid);
$student_res = $this->getStudentInfo($this->uid);
$matr_res = $this->getMatrikelNummer($this->uid);
$profilUpdates = $this->getProfilUpdates($this->uid);
$res = new stdClass();
$res->username = $this->uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Student Information
foreach ($student_res as $key => $value) {
$res->$key = trim($value);
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $this->uid . "@" . DOMAIN;
$res->emails = [$intern_email];
$res->adressen = $adresse_res;
$res->zutrittsdatum = $zutrittskarte_ausgegebenam;
$res->kontakte = $kontakte_res;
$res->mittel = $betriebsmittelperson_res;
$res->matrikelnummer = $matr_res->matr_nr;
$res->zuttritsgruppen = $zutrittsgruppe_res;
$res->mailverteiler = $mailverteiler_res;
$res->profilUpdates = $profilUpdates;
return $res;
}
/**
* gets all the mailverteiler using the tables: tbl_benutzer, tbl_benutzergruppe, tbl_gruppe
* @access private
* @param integer $uid the userID used to retrieve the mailverteiler
* @return array returns the mailvertailer corresponding to a userID
*/
private function getMailverteiler($uid)
{
$this->PersonModel->addSelect('gruppe_kurzbz, beschreibung');
$this->PersonModel->addJoin('tbl_benutzer', 'person_id');
$this->PersonModel->addJoin('tbl_benutzergruppe', 'uid');
$this->PersonModel->addJoin('tbl_gruppe', 'gruppe_kurzbz');
$mailverteiler_res = $this->PersonModel->loadWhere(array('mailgrp' => true, 'uid' => $uid));
if (isError($mailverteiler_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($mailverteiler_res));
}
$mailverteiler_res = hasData($mailverteiler_res) ? getData($mailverteiler_res) : null;
$mailverteiler_res = array_map(function ($element) {
$element->mailto = "mailto:" . $element->gruppe_kurzbz . "@" . DOMAIN;
return $element;
}, $mailverteiler_res);
return $mailverteiler_res;
}
/**
* gets all the Benutzerfunktionen of a corresponding user
* @access private
* @param integer $uid the userID used to retrieve the Benutzerfunktionen
* @return array returns the Benutzerfunktionen corresponding to a userID
*/
private function getBenutzerFunktion($uid)
{
$this->BenutzerfunktionModel->addSelect(["tbl_benutzerfunktion.bezeichnung as Bezeichnung", "tbl_organisationseinheit.bezeichnung as Organisationseinheit", "datum_von as Gültig_von", "datum_bis as Gültig_bis", "wochenstunden as Wochenstunden"]);
$this->BenutzerfunktionModel->addJoin("tbl_organisationseinheit", "oe_kurzbz");
$benutzer_funktion_res = $this->BenutzerfunktionModel->loadWhere(array('uid' => $uid));
if (isError($benutzer_funktion_res)) {
show_error("was not able to query the table public.tbl_benutzerfunktion:" . getData($benutzer_funktion_res));
}
$benutzer_funktion_res = hasData($benutzer_funktion_res) ? getData($benutzer_funktion_res) : null;
return $benutzer_funktion_res;
}
/**
* gets all the Betriebsmittel of a corresponding user
* @access private
* @param integer $uid the userID used to retrieve the Betriebsmittel
* @return array returns the Betriebsmittel corresponding to a userID
*/
private function getBetriebsmittelInfo($pid)
{
$this->BetriebsmittelpersonModel->addSelect(["CONCAT(betriebsmitteltyp, ' ' ,beschreibung) as Betriebsmittel", "nummer as Nummer", "ausgegebenam as Ausgegeben_am"]);
//? betriebsmittel are not needed in a view
$betriebsmittelperson_res = $this->BetriebsmittelpersonModel->getBetriebsmittel($pid);
if (isError($betriebsmittelperson_res)) {
show_error("was not able to query the table public.tbl_betriebsmittelperson:" . getData($betriebsmittelperson_res));
}
$betriebsmittelperson_res = hasData($betriebsmittelperson_res) ? getData($betriebsmittelperson_res) : null;
return $betriebsmittelperson_res;
}
/**
* gets the alias of a corresponding user
* @access private
* @param integer $uid the userID used to get the alias
* @return string the alias of the userID
*/
private function getBenutzerAlias($uid)
{
$this->BenutzerModel->addSelect(["alias"]);
$benutzer_res = $this->BenutzerModel->load([$uid]);
if (isError($benutzer_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($benutzer_res));
} else {
$benutzer_res = hasData($benutzer_res) ? getData($benutzer_res)[0] : null;
}
return $benutzer_res;
}
/**
* gets the person information corresponding to a user
* @access private
* @param integer $uid the userID used to get the person information
* @param integer $geburtsInfo flag wether to add the columns gebort, gebdatum, foto_sperre or not
* @return array all the person informaion corresponding to a userID
*/
private function getPersonInfo($uid, $geburtsInfo = null)
{
$selectClause = ["foto", "foto_sperre", "anrede", "titelpost as postnomen", "titelpre as titel", "vorname", "nachname"];
/** @param integer $geburtsInfo */
if ($geburtsInfo) {
array_push($selectClause, "gebort");
array_push($selectClause, "gebdatum");
}
$this->BenutzerModel->addSelect($selectClause);
$this->BenutzerModel->addJoin("tbl_person", "person_id");
$person_res = $this->BenutzerModel->load([$uid]);
if (isError($person_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($person_res));
} else {
$person_res = hasData($person_res) ? getData($person_res)[0] : null;
}
if( ($person_res->foto === null) || (($this->uid !== $uid) && ($person_res->foto_sperre !== false)) )
{
$dummy_foto = base64_encode(file_get_contents(DOC_ROOT.'skin/images/profilbild_dummy.jpg'));
$person_res->foto = $dummy_foto;
}
return $person_res;
}
/**
* gets the mitarbeiter information corresponding to a user
* @access private
* @param integer $uid the userID used to get the mitarbeiter information
* @return array all the mitarbeiter informaion corresponding to a userID
*/
private function getMitarbeiterInfo($uid)
{
$this->MitarbeiterModel->addSelect(["kurzbz", "telefonklappe", "alias", "ort_kurzbz"]);
$this->MitarbeiterModel->addJoin("tbl_benutzer", "tbl_benutzer.uid = tbl_mitarbeiter.mitarbeiter_uid");
$mitarbeiter_res = $this->MitarbeiterModel->load($uid);
if (isError($mitarbeiter_res)) {
show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($mitarbeiter_res));
} else {
$mitarbeiter_res = hasData($mitarbeiter_res) ? getData($mitarbeiter_res)[0] : null;
}
return $mitarbeiter_res;
}
/**
* gets the telefon information corresponding to a user
* @access private
* @param integer $uid the userID used to get the telefon information
* @return array all the telefon informaion corresponding to a userID
*/
private function getTelefonInfo($uid)
{
$this->MitarbeiterModel->addSelect(["kontakt"]);
$this->MitarbeiterModel->addJoin("tbl_kontakt", "tbl_mitarbeiter.standort_id = tbl_kontakt.standort_id");
$this->MitarbeiterModel->addLimit(1);
$telefon_res = $this->MitarbeiterModel->loadWhere(["mitarbeiter_uid" => $uid, "kontakttyp" => "telefon"]);
if (isError($telefon_res)) {
show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($telefon_res));
}
$telefon_res = hasData($telefon_res) ? getData($telefon_res)[0] : null;
return $telefon_res;
}
/**
* gets the student information corresponding to a user
* @access private
* @param integer $uid the userID used to get the student information
* @return array all the student informaion corresponding to a userID
*/
private function getStudentInfo($uid)
{
$this->StudentModel->addSelect(['tbl_studiengang.bezeichnung as studiengang', 'tbl_student.semester', 'tbl_student.verband', 'tbl_student.gruppe', 'tbl_student.matrikelnr as personenkennzeichen']);
$this->StudentModel->addJoin('tbl_studiengang', "tbl_studiengang.studiengang_kz=tbl_student.studiengang_kz");
$student_res = $this->StudentModel->load([$uid]);
if (isError($student_res)) {
show_error("was not able to query the table public.tbl_student:" . getData($student_res));
}
$student_res = hasData($student_res) ? getData($student_res)[0] : null;
return $student_res;
}
/**
* gets the profil updates corresponding to a user
* @access private
* @param integer $uid the userID used to get the profil updates
* @return array all the profil updates corresponding to a userID
*/
private function getProfilUpdates($uid)
{
$profilUpdates = $this->ProfilUpdateModel->getProfilUpdatesWhere(['uid' => $uid]);
if (isError($profilUpdates)) {
show_error("was not able to query the table public.tbl_profil_update:" . getData($profilUpdates));
}
$profilUpdates = hasData($profilUpdates) ? getData($profilUpdates) : null;
return $profilUpdates;
}
/**
* gets the Matrikelnummer corresponding to a user
* @access private
* @param integer $uid the userID used to get the Matrikelnummer
* @return integer the Matrikelnummer corresponding to a userID
*/
private function getMatrikelNummer($uid)
{
$this->BenutzerModel->addSelect(["matr_nr"]);
$this->BenutzerModel->addJoin("tbl_person", "person_id");
$matr_res = $this->BenutzerModel->load([$uid]);
if (isError($matr_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($matr_res));
}
$matr_res = hasData($matr_res) ? getData($matr_res)[0] : [];
return $matr_res;
}
/**
* gets the Zutrittsgruppen corresponding to a user
* @access private
* @param integer $uid the userID used to get the Zutrittsgruppen
* @return array all the Zutrittsgruppen corresponding to a userID
*/
private function getZutrittsgruppen($uid)
{
$this->BenutzergruppeModel->addSelect(['bezeichnung']);
$this->BenutzergruppeModel->addJoin('tbl_gruppe', 'gruppe_kurzbz');
$zutrittsgruppe_res = $this->BenutzergruppeModel->loadWhere(array("uid" => $uid, "zutrittssystem" => true));
if (isError($zutrittsgruppe_res)) {
show_error("was not able to query the table public.tbl_benutzergruppe:" . getData($zutrittsgruppe_res));
}
$zutrittsgruppe_res = hasData($zutrittsgruppe_res) ? getData($zutrittsgruppe_res) : null;
return $zutrittsgruppe_res;
}
/**
* gets the address information corresponding to a user
* @access private
* @param integer $uid the userID used to get the address information
* @return array all the address information corresponding to a userID
*/
private function getAdressenInfo($pid)
{
$adresse_res = $this->AdresseModel->addSelect(["adresse_id", "strasse", "tbl_adressentyp.bezeichnung as typ", "plz", "ort", "zustelladresse", "gemeinde", "nation"]);
$adresse_res = $this->AdresseModel->addOrder("zustelladresse", "DESC");
$adresse_res = $this->AdresseModel->addJoin("tbl_adressentyp", "typ=adressentyp_kurzbz");
$adresse_res = $this->AdresseModel->loadWhere(["person_id" => $pid]);
if (isError($adresse_res)) {
show_error("was not able to query the table public.tbl_adresse:" . getData($adresse_res));
}
$adresse_res = hasData($adresse_res) ? getData($adresse_res) : null;
return $adresse_res;
}
/**
* gets the kontakt information corresponding to a user
* @access private
* @param integer $uid the userID used to get the kontakt information
* @return array all the kontakt information corresponding to a userID
*/
private function getKontaktInfo($pid)
{
$this->KontaktModel->addSelect(['kontakttyp', 'kontakt_id', 'kontakt', 'tbl_kontakt.anmerkung', 'tbl_kontakt.zustellung']);
$this->KontaktModel->addJoin('public.tbl_standort', 'standort_id', 'LEFT');
$this->KontaktModel->addJoin('public.tbl_firma', 'firma_id', 'LEFT');
$this->KontaktModel->addOrder('kontakttyp, kontakt, tbl_kontakt.updateamum, tbl_kontakt.insertamum');
$kontakte_res = $this->KontaktModel->loadWhere(['person_id' => $pid]);
if (isError($kontakte_res)) {
show_error("was not able to query the table public.tbl_kontakt:" . getData($kontakte_res));
}
$kontakte_res = hasData($kontakte_res) ? getData($kontakte_res) : null;
return $kontakte_res;
}
/**
* gets the date of issue of the FH access card corresponding to a user
* @access private
* @param integer $uid the userID used to get the date of issue of the FH access card
* @return string the date of issue of the FH access card corresponding to a userID
*/
private function getZutrittskarteDatum($uid)
{
$zutrittskarte_ausgegebenam = $this->BetriebsmittelpersonModel->getBetriebsmittelByUid($uid, "Zutrittskarte");
if (isError($zutrittskarte_ausgegebenam)) {
show_error("was not able to query the table wavi.tbl_bentriebsmittelperson:" . getData($zutrittskarte_ausgegebenam));
}
$zutrittskarte_ausgegebenam = hasData($zutrittskarte_ausgegebenam) ? getData($zutrittskarte_ausgegebenam)[0]->ausgegebenam : null;
//? formats date from 01-01-2000 to 01.01.2000
$zutrittskarte_ausgegebenam = str_replace("-", ".", $zutrittskarte_ausgegebenam);
return $zutrittskarte_ausgegebenam;
}
}
@@ -0,0 +1,837 @@
<?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 ProfilUpdate extends FHCAPI_Controller
{
public static $STATUS_PENDING = NULL;
public static $STATUS_ACCEPTED = NULL;
public static $STATUS_REJECTED = NULL;
public static $TOPICS = [];
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getStatus' => self::PERM_LOGGED,
'getTopic' => self::PERM_LOGGED,
'getProfilRequestFiles' => self::PERM_LOGGED,
'getProfilUpdateWithPermission' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
'denyProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'],
'acceptProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'],
'selectProfilRequest' => self::PERM_LOGGED,
'insertProfilRequest' => self::PERM_LOGGED,
'updateProfilRequest' => self::PERM_LOGGED,
'deleteProfilRequest' => self::PERM_LOGGED,
'insertFile' => self::PERM_LOGGED,
'show' => self::PERM_LOGGED,
]);
$this->load->config('cis');
// Load language phrases
$this->loadPhrases(
array(
'ui',
'global',
'person',
'profil',
'profilUpdate'
)
);
$this->load->model('person/Profil_update_model', 'ProfilUpdateModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->load->model('person/Adressentyp_model', 'AdressenTypModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('system/Sprache_model', 'SpracheModel');
$this->load->model('person/Profil_update_status_model', 'ProfilUpdateStatusModel');
$this->load->model('person/Profil_update_topic_model', 'ProfilUpdateTopicModel');
$this->load->library('DmsLib');
$this->load->library('PermissionLib');
//? put the uid and pid inside the controller for reusability
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
// setup the ProfilUpdate states
$this->ProfilUpdateStatusModel->addSelect(['status_kurzbz']);
$status_kurzbz = $this->ProfilUpdateStatusModel->load();
if (hasData($status_kurzbz)) {
list($status_pending, $status_accepted, $status_rejected) = getData($status_kurzbz);
self::$STATUS_PENDING = $status_pending->status_kurzbz;
self::$STATUS_ACCEPTED = $status_accepted->status_kurzbz;
self::$STATUS_REJECTED = $status_rejected->status_kurzbz;
}
// setup the ProfilUpdate topics
$this->ProfilUpdateTopicModel->addSelect(['topic_kurzbz']);
$topic_kurzbz = $this->ProfilUpdateTopicModel->load();
if (hasData($topic_kurzbz)) {
foreach (getData($topic_kurzbz) as $topic) {
self::$TOPICS[$topic->topic_kurzbz] = $topic->topic_kurzbz;
}
}
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getStatus()
{
$this->terminateWithSuccess([self::$STATUS_PENDING => self::$STATUS_PENDING, self::$STATUS_ACCEPTED => self::$STATUS_ACCEPTED, self::$STATUS_REJECTED => self::$STATUS_REJECTED]);
}
public function getTopic()
{
if(!count(self::$TOPICS)){
$this->terminateWithError('No topics found');
}
$this->terminateWithSuccess(self::$TOPICS);
}
public function show($dms_id)
{
$profil_update = $this->ProfilUpdateModel->loadWhere(['attachment_id' => $dms_id]);
$profil_update = hasData($profil_update) ? getData($profil_update)[0] : null;
//? checks if an profil update exists with the dms_id requested from the user
if ($profil_update) {
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($profil_update->uid));
$is_student_profil_update = getData($this->StudentModel->isStudent($profil_update->uid));
if (
$this->permissionlib->isBerechtigt('student/stammdaten:r') && $is_student_profil_update ||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten:r') && $is_mitarbeiter_profil_update ||
$this->uid == $profil_update->uid
) {
// Get file to be downloaded from DMS
$download = $this->dmslib->download($dms_id);
$download = $this->getDataOrTerminateWithError($download);
// Download file
$this->outputFile($download);
} else {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
}
} else {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_dms_error'));
}
}
public function selectProfilRequest()
{
$uid = $this->input->get('uid',true);
$id = $this->input->get('id',true);
$whereClause = ['uid' => $this->uid];
if (isset($uid))
$whereClause['uid'] = $uid;
if (isset($id))
$whereClause['id'] = $id;
$res = $this->ProfilUpdateModel->getProfilUpdatesWhere($whereClause);
$res = $this->getDataOrTerminateWithError($res);
$this->terminateWithSuccess($res);
}
public function insertProfilRequest()
{
$payload = $this->input->post('payload');
$topic = $this->input->post('topic',true);
$fileID = $this->input->post('fileID',true);
if(!isset($payload) || !isset($topic)){
$this->terminateWithError("required parameters are missing");
}
$identifier = array_key_exists("kontakt_id", $payload) ? "kontakt_id" : (array_key_exists("adresse_id", $payload) ? "adresse_id" : null);
$data = ["topic" => $topic, "uid" => $this->uid, "requested_change" => json_encode($payload), "insertamum" => "NOW()", "insertvon" => $this->uid, "status" => self::$STATUS_PENDING ?: 'Pending'];
//? insert fileID in the dataset if sent with post request
if (isset($fileID)) {
$data['attachment_id'] = $fileID;
}
//? loops over all updateRequests from a user to validate if the new request is valid
$res = $this->ProfilUpdateModel->getProfilUpdatesWhere(["uid" => $this->uid]);
$res = $this->getDataOrTerminateWithError($res);
//? the user cannot delete a zustelladresse/kontakt
if (isset($payload["delete"]) && $payload[$identifier == "kontakt_id" ? "zustellung" : "zustelladresse"]) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error'));
}
//? if the user tries to delete a adresse, checks whether the adresse is a heimatadresse, if so an error is raised
if (isset($payload["delete"]) && $identifier == "adresse_id") {
$adr = $this->AdresseModel->load($payload[$identifier]);
$adr = $this->getDataOrTerminateWithError($adr)[0];
if ($adr->heimatadresse) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error'));
}
}
if ($res) {
$pending_changes = array_filter($res, function ($element) {
return $element->status == (self::$STATUS_PENDING ?: "Pending");
});
foreach ($pending_changes as $update_request) {
$existing_change = $update_request->requested_change;
//? the user can add as many new kontakte/adressen as he likes
if (!isset($payload["add"]) && property_exists($existing_change, $identifier) && array_key_exists($identifier,$payload) && $existing_change->$identifier == $payload[$identifier]) {
//? the kontakt_id / adresse_id of a change has to be unique
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_changeTwice_error'));
}
//? if it is not updating any kontakt/adresse, the topic has to be unique
elseif (!$identifier && $update_request->topic == $topic) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_changeTopicTwice_error', ['0' => $update_request->topic]));
}
}
}
$insertID = $this->ProfilUpdateModel->insert($data);
if (isError($insertID)) {
$this->terminateWithError(getError($insertID));
} else {
$insertID = hasData($insertID) ? getData($insertID) : null;
//? sends emails to the correspondents of the $uid
$this->sendEmail_onProfilUpdate_insertion($this->uid, $insertID, $topic);
$this->terminateWithSuccess(success($insertID));
}
}
public function updateProfilRequest()
{
$topic = $this->input->post('topic', true);
$payload = $this->input->post('payload', true);
$ID = $this->input->post('ID', true);
$fileID = $this->input->post('fileID', true);//optional
if(!isset($topic) || !isset($payload) || !isset($ID)){
$this->terminateWithError("required parameters are missing");
}
$updateData = ["requested_change" => json_encode($payload), "updateamum" => "NOW()", "updatevon" => $this->uid];
if (isset($fileID)) {
$updateData['attachment_id'] = json_decode($fileID);
}
$updateID = $this->ProfilUpdateModel->update([$ID], $updateData);
//? insert fileID in the dataset if sent with post request
if (isError($updateID)) {
$this->terminateWithError(getError($updateID));
}
$updateID = $this->getDataOrTerminateWithError($updateID)[0];
$this->terminateWithSuccess(success($updateID));
}
public function deleteProfilRequest()
{
$requestID = $this->input->post('requestID', true);
$result = $this->ProfilUpdateModel->delete([$requestID]);
if (isError($result)) {
$this->terminateWithError(getError($result));
}
$this->terminateWithSuccess($result);
}
public function getProfilRequestFiles($id)
{
if(!$id){
$this->terminateWithError("parameter id is missing");
}
$this->ProfilUpdateModel->addSelect(["attachment_id"]);
$attachmentID = $this->ProfilUpdateModel->load([$id]);
if (isError($attachmentID)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_loading_error'),self::ERROR_TYPE_GENERAL);
}
//? get the attachmentID
$dms_id = $this->getDataOrTerminateWithError($attachmentID)[0]->attachment_id;
//? get the name to the file
$this->DmsVersionModel->addSelect(["name", "dms_id"]);
$attachment = $this->DmsVersionModel->load([$dms_id, 0]);
if (isError($attachment)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error'),self::ERROR_TYPE_GENERAL);
}
$attachment = $this->getDataOrTerminateWithError($attachment);
//? returns {name:..., dms_id:...}
$this->terminateWithSuccess($attachment);
}
public function denyProfilRequest()
{
$id = $this->input->post('profil_update_id', true);
$uid = $this->input->post('uid', true);
$topic = $this->input->post('topic', true);
$status_message = $this->input->post('status_message', true); //optional
if(!isset($id) || !isset($uid) || !isset($topic)){
$this->terminateWithError("parameter id, uid, topic or status_message is missing");
}
$is_mitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid);
$is_mitarbeiter = $this->getDataOrTerminateWithError($is_mitarbeiter);
$is_student = $this->StudentModel->isStudent($uid);
$is_student = $this->getDataOrTerminateWithError($is_student);
if (
$is_student && $this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) ||
$is_mitarbeiter && $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid")
) {
$this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_REJECTED);
$this->terminateWithSuccess($this->setStatusOnUpdateRequest($id, self::$STATUS_REJECTED, $status_message));
} else {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_permission_error'),self::ERROR_TYPE_GENERAL);
}
}
public function acceptProfilRequest()
{
$id = $this->input->post('profil_update_id', true);
$uid = $this->input->post('uid', true);
$topic = $this->input->post('topic', true);
$requested_change = $this->input->post('requested_change');
$status_message = $this->input->post('status_message', true); //optional
//? fetching person_id using UID
$personID = $this->PersonModel->getByUid($uid);
$personID = $this->getDataOrTerminateWithError($personID)[0]->person_id;
//! check for required information
if (!isset($id) || !isset($uid) || !isset($personID) || !isset($requested_change) || !isset($topic)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_requiredInformation_error'));
}
$is_mitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid);
$is_mitarbeiter = $this->getDataOrTerminateWithError($is_mitarbeiter);
$is_student = $this->StudentModel->isStudent($uid);
$is_student = $this->getDataOrTerminateWithError($is_student);
//? check if the permissions are set correctly
if (
$is_student && $this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) ||
$is_mitarbeiter && $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid")
) {
if (is_array($requested_change) && array_key_exists("adresse_id", $requested_change)) {
$insertID = $this->handleAdresse($requested_change, $personID);
$insertID = getData($insertID);
if (isset($insertID)) {
$requested_change['adresse_id'] = $insertID;
$update_res = $this->updateRequestedChange($id, $requested_change);
if (isError($update_res)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_address_error', [$insertID]));
}
}
} else if (is_array($requested_change) && array_key_exists("kontakt_id", $requested_change)) {
$insertID = $this->handleKontakt($requested_change, $personID);
$insertID = getData($insertID);
if (isset($insertID)) {
$requested_change['kontakt_id'] = $insertID;
$update_res = $this->updateRequestedChange($id, $requested_change);
if (isError($update_res)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_kontakt_error', [$insertID]));
}
}
} else {
switch ($topic) {
// mapping phrasen to database columns to make the update with the correct column names
case self::$TOPICS['Titel']:
$topic = "titelpre";
break;
case self::$TOPICS['Postnomen']:
$topic = "titelpost";
break;
case self::$TOPICS['Vorname']:
$topic = "vorname";
break;
case self::$TOPICS['Nachname']:
$topic = "nachname";
break;
default:
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_topic_error', [$topic]));
}
$result = $this->PersonModel->update($personID, [$topic => $requested_change["value"]]);
if (isError($result)) $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_insert_error'));
}
$this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_ACCEPTED);
$this->terminateWithSuccess($this->setStatusOnUpdateRequest($id, self::$STATUS_ACCEPTED, $status_message, $requested_change));
} else {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
}
}
public function insertFile($replace)
{
$replace = json_decode($replace);
if (!count($_FILES)) {
$this->terminateWithError("No file available for upload");
}
//? if replace is set it contains the profil_update_id in which the attachment_id has to be replaced
if (isset($replace)) {
$this->ProfilUpdateModel->addSelect(["attachment_id"]);
$profilUpdate = $this->ProfilUpdateModel->load([$replace]);
if (isError($profilUpdate)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_loading_error'));
}
//? get the attachmentID
$dms_id = $this->getDataOrTerminateWithError($profilUpdate)[0]->attachment_id;
//? delete old dms_file of Profil Update
$deleteOldFile_result = $this->deleteOldVersionFile($dms_id);
if(!$deleteOldFile_result){
$this->terminateWithError("error while deleting the old file");
}
}
$files = $_FILES['files'];
$file_count = count($files['name']);
$res = [];
for ($i = 0; $i < $file_count; $i++) {
$_FILES['files']['name'] = $files['name'][$i];
$_FILES['files']['type'] = $files['type'][$i];
$_FILES['files']['tmp_name'] = $files['tmp_name'][$i];
$_FILES['files']['error'] = $files['error'][$i];
$_FILES['files']['size'] = $files['size'][$i];
$dms = [
"kategorie_kurzbz" => "profil_aenderung",
"version" => 0,
"name" => $_FILES['files']['name'],
"mimetype" => $_FILES['files']['type'],
"beschreibung" => $this->uid . " Profil Änderung",
"insertvon" => $this->uid,
"insertamum" => "NOW()",
];
$tmp_res = $this->dmslib->upload($dms, 'files', array("jpg", "png", "pdf"));
if(isError($tmp_res)){
$this->addError(getError($tmp_res));
}
$tmp_res = $this->getDataOrTerminateWithError($tmp_res);
array_push($res, $tmp_res);
}
$this->terminateWithSuccess($res);
}
public function getProfilUpdateWithPermission($status = null)
{
// early return if no status has been passed as argument
if (!isset($status)) {
echo json_encode($this->ProfilUpdateModel->getProfilUpdateWithPermission());
return;
}
// get the sprache of the user
$sprachenIndex = $this->SpracheModel->loadWhere(["sprache" => getUserLanguage()]);
$sprachenIndex = hasData($sprachenIndex) ? getData($sprachenIndex)[0]->index : null;
if (isset($sprachenIndex) && isset($status)) {
// get the corresponding status kurz_bz primary key out of the translation
$status = $this->ProfilUpdateStatusModel->execReadOnlyQuery("select * from public.tbl_profil_update_status where ? = ANY(bezeichnung_mehrsprachig)", [$status]);
$status = hasData($status) ? getData($status)[0]->status_kurzbz : null;
$res = $this->ProfilUpdateModel->getProfilUpdateWithPermission(isset($status) ? ['status' => $status] : null);
echo json_encode($res);
}
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
private function sendEmail_onProfilUpdate_insertion($uid, $profil_update_id, $topic)
{
if($this->config->item('cis_send_profil_update_mails') === false)
{
return;
}
$this->load->helper('hlp_sancho_helper');
$emails = [];
$is_mitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($is_mitarbeiter)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error'));
}
$is_mitarbeiter = $this->getDataOrTerminateWithError($is_mitarbeiter);
//! if the $uid is a mitarbeiter and student, only the hr is notified by email
if ($is_mitarbeiter) {
//? user is not a student therefore he is a mitarbeiter, send email to Personalverwaltung
//? use constant variable MAIL_GST to mail to the personalverwaltung
$this->MitarbeiterModel->addSelect([TRUE]);
$this->MitarbeiterModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid");
//? check if the the userID is a mitarbeiter and if the benutzer is active
$res = $this->MitarbeiterModel->loadWhere(["public.tbl_mitarbeiter.mitarbeiter_uid" => $uid, "public.tbl_benutzer.aktiv" => TRUE]);
if (isError($res)) {
$this->terminateWithError("was not able to query the mitarbeiter and benutzer by the uid: " . $uid);
}
if (hasData($res)) {
array_push($emails, MAIL_GST);
} else {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error'));
}
} else {
//? if it is not a mitarbeiter, check whether it is a student and send email to studiengang
$is_student = $this->StudentModel->isStudent($uid);
if (isError($is_student)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_studentCheck_error'));
}
$is_student = $this->getDataOrTerminateWithError($is_student);
if ($is_student) {
//? Send email to the Studiengangsassistentinnen
$this->StudentModel->addSelect(["public.tbl_studiengang.email"]);
$this->StudentModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_student.student_uid");
$this->StudentModel->addJoin("public.tbl_prestudent", "public.tbl_benutzer.person_id = public.tbl_prestudent.person_id");
$this->StudentModel->addJoin("public.tbl_prestudentstatus", "public.tbl_prestudentstatus.prestudent_id = public.tbl_prestudent.prestudent_id");
$this->StudentModel->addJoin("public.tbl_studiengang", "public.tbl_studiengang.studiengang_kz = public.tbl_prestudent.studiengang_kz");
//* check if the benutzer itself is active
//* check if the student status is Student or Diplomand (active students)
$this->StudentModel->db->where_in("public.tbl_prestudentstatus.status_kurzbz", ['Student', 'Diplomand']);
$res = $this->StudentModel->loadWhere(["public.tbl_benutzer.aktiv" => TRUE, "public.tbl_student.student_uid" => $uid]);
if (isError($res)) {
$this->terminateWithError(getError($res));
} else {
$res = $this->getDataOrTerminateWithError($res);
foreach ($res as $emailObj) {
array_push($emails, $emailObj->email);
}
}
}
}
$mail_res = [];
//? sending email
foreach ($emails as $email) {
array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => APP_ROOT . 'Cis/ProfilUpdate/id/' . $profil_update_id], $email, ("Profil Änderung von " . $uid)));
}
foreach ($mail_res as $m_res) {
if (!$m_res) {
$this->addError($this->p->t('profilUpdate', 'profilUpdate_email_error'));
}
}
}
private function sendEmail_onProfilUpdate_response($uid, $topic, $status)
{
if($this->config->item('cis_send_profil_update_mails') === false)
{
return;
}
$this->load->helper('hlp_sancho_helper');
$email = $uid . "@" . DOMAIN;
function languageQuery($language)
{
return "select index from public.tbl_sprache where sprache = '" + $language + "'";
}
$this->ProfilUpdateStatusModel->addSelect(["bezeichnung_mehrsprachig[(" . languageQuery('German') . ")] as status_de", "bezeichnung_mehrsprachig[(" . languageQuery('English') . ")] as status_en"]);
$status_translation = $this->ProfilUpdateStatusModel->loadWhere(["status_kurzbz" => $status]);
if (isError($status_translation)) {
$this->terminateWithError($this->p->t('profilUpdate', 'ProfilUpdateStatusTranslationError'));
}
$status_translation = hasData($status_translation) ? getData($status_translation)[0] : null;
if (isset($status_translation)) {
$mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => APP_ROOT . 'Cis/Profil'], $email, ("Profil Änderung " . $this->p->t('profilUpdate', 'pending')));
if (!$mail_res) {
$this->addError($this->p->t('profilUpdate', 'profilUpdate_email_error'));
}
}
}
private function setStatusOnUpdateRequest($id, $status, $status_message)
{
return $this->ProfilUpdateModel->update([$id], ["status" => $status, "status_timestamp" => "NOW()", "status_message" => $status_message]);
}
private function updateRequestedChange($id, $requested_change)
{
return $this->ProfilUpdateModel->update([$id], ['requested_change' => json_encode($requested_change)]);
}
private function deleteOldVersionFile($dms_id)
{
// starting the transaction
$this->db->trans_start();
if (!isset($dms_id)) {
return;
}
//? delete the file from the profilUpdate first
$profilUpdateFileDelete = $this->ProfilUpdateModel->removeFileFromProfilUpdate($dms_id);
if(isError($profilUpdateFileDelete)){
$this->terminateWithError(getError($profilUpdateFileDelete));
}
//? delete all the different versions of the dms_file
$dmsVersions = $this->DmsVersionModel->loadWhere(["dms_id" => $dms_id]);
$dmsVersions = $this->getDataOrTerminateWithError($dmsVersions);
$dms_versions = array_map(function ($item) {
return $item->version;
}, $dmsVersions);
$test_array = array();
foreach ($dms_versions as $version) {
$delete_result = $this->dmslib->removeVersion($dms_id, $version);
array_push($test_array, $delete_result);
if(isError($delete_result)){
$this->addError(getError($delete_result));
}
}
// transaction complete
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
return false;
}
else
{
return true;
}
}
private function getOE_from_student($student_uid)
{
//? returns the oe_einheit eines Studenten
$query = "SELECT public.tbl_studiengang.oe_kurzbz
FROM public.tbl_student
JOIN public.tbl_studiengang ON tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
WHERE public.tbl_student.student_uid = ?;";
$res = $this->StudentModel->execReadOnlyQuery($query, [$student_uid]);
$res = $this->getDataOrTerminateWithError($res, $this->p->t('profilUpdate', 'profilUpdate_loadingOE_error'));
$res = array_map(
function ($item) {
return $item->oe_kurzbz;
},
$res
);
return $res;
}
private function handleAdresse($requested_change, $personID)
{
$this->AdressenTypModel->addSelect(["adressentyp_kurzbz"]);
$adr_kurzbz = $this->AdressenTypModel->loadWhere(["bezeichnung" => $requested_change['typ']]);
$adr_kurzbz = $this->getDataOrTerminateWithError($adr_kurzbz)[0]->adressentyp_kurzbz;
//? replace the address_typ with its correct kurzbz foreign key
$requested_change['typ'] = $adr_kurzbz;
$adresse_id = $requested_change["adresse_id"];
//? removes the adresse_id because we don't want to update the kontakt_id in the database
unset($requested_change["adresse_id"]);
//! ADD
if (array_key_exists('add', $requested_change) && $requested_change['add']) {
//? removes add flag
unset($requested_change['add']);
$requested_change['insertamum'] = "NOW()";
$requested_change['insertvon'] = getAuthUID();
$requested_change['person_id'] = $personID;
//TODO: zustelladresse, heimatadresse, rechnungsadresse und nation werden nicht beachtet
$insertID = $this->AdresseModel->insert($requested_change);
$insert_adresse_id = $insertID;
$insert_adresse_id = $this->getDataOrTerminateWithError($insert_adresse_id, $this->p->t('profilUpdate', 'profilUpdate_insertAdresse_error'));
if ($insert_adresse_id) {
$this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $insert_adresse_id);
}
}
//! DELETE
elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) {
$result = $this->AdresseModel->delete($adresse_id);
if (isError($result)) {
$this->terminateWithError(getError($result));
}
}
//! UPDATE
else {
$requested_change['updateamum'] = "NOW()";
$requested_change['updatevon'] = getAuthUID();
$update_adresse_id = $this->AdresseModel->update($adresse_id, $requested_change);
$update_adresse_id = $this->getDataOrTerminateWithError($update_adresse_id, $this->p->t('profilUpdate', 'profilUpdate_updateAdresse_error'));
$this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $update_adresse_id);
}
return $insertID ?? null;
}
private function handleKontakt($requested_change, $personID)
{
$kontakt_id = $requested_change["kontakt_id"];
//? removes the kontakt_id because we don't want to update the kontakt_id in the database
unset($requested_change["kontakt_id"]);
//! ADD
if (array_key_exists('add', $requested_change) && $requested_change['add']) {
//? removes add flag
unset($requested_change['add']);
$requested_change['person_id'] = $personID;
$requested_change['insertamum'] = "NOW()";
$requested_change['insertvon'] = getAuthUID();
$insertID = $this->KontaktModel->insert($requested_change);
$insert_kontakt_id = $insertID;
$insert_kontakt_id = $this->getDataOrTerminateWithError($insert_kontakt_id, $this->p->t('profilUpdate', 'profilUpdate_insertKontakt_error'));
if ($insert_kontakt_id) {
$this->handleDupplicateZustellKontakte($requested_change['zustellung'], $insert_kontakt_id);
}
}
//! DELETE
elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) {
$result = $this->KontaktModel->delete($kontakt_id);
if (isError($result)) {
$this->terminateWithError(getError($result));
}
}
//! UPDATE
else {
$requested_change['updateamum'] = "NOW()";
$requested_change['updatevon'] = getAuthUID();
$update_kontakt_id = $this->KontaktModel->update($kontakt_id, $requested_change);
$update_kontakt_id = $this->getDataOrTerminateWithError($update_kontakt_id, $this->p->t('profilUpdate', 'profilUpdate_updateKontakt_error'));
if ($update_kontakt_id) {
$this->handleDupplicateZustellKontakte($requested_change['zustellung'], $update_kontakt_id);
}
}
return isset($insertID) ? $insertID : null;
}
private function handleDupplicateZustellAdressen($zustellung, $adresse_id)
{
if ($zustellung) {
$this->PersonModel->addSelect("public.tbl_adresse.adresse_id");
$this->PersonModel->addJoin("public.tbl_adresse", "public.tbl_adresse.person_id = public.tbl_person.person_id");
$zustellAdressenArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustelladresse" => TRUE]);
if (isError($zustellAdressenArray)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_loadingZustellAdressen_error'));
}
$zustellAdressenArray = $this->getDataOrTerminateWithError($zustellAdressenArray);
if (count($zustellAdressenArray) > 0) {
$zustellAdressenArray = array_filter($zustellAdressenArray, function ($adresse) use ($adresse_id) {
return $adresse->adresse_id != $adresse_id;
});
// remove the zustelladresse from all other zustelladressen
foreach ($zustellAdressenArray as $adresse) {
$this->AdresseModel->update($adresse->adresse_id, ["zustelladresse" => FALSE]);
}
}
}
}
private function handleDupplicateZustellKontakte($zustellung, $kontakt_id)
{
if ($zustellung) {
$this->PersonModel->addSelect("public.tbl_kontakt.kontakt_id");
$this->PersonModel->addJoin("public.tbl_kontakt", "public.tbl_kontakt.person_id = public.tbl_person.person_id");
$zustellKontakteArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustellung" => TRUE]);
if (!isSuccess($zustellKontakteArray)) {
return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellkontakte_error'));
}
$zustellKontakteArray = hasData($zustellKontakteArray) ? getData($zustellKontakteArray) : null;
if ($zustellung && count($zustellKontakteArray) > 0) {
$zustellKontakteArray = array_filter($zustellKontakteArray, function ($kontakt) use ($kontakt_id) {
return $kontakt->kontakt_id != $kontakt_id;
});
foreach ($zustellKontakteArray as $kontakt) {
$this->KontaktModel->update($kontakt->kontakt_id, ["zustellung" => FALSE]);
}
}
}
}
}
@@ -0,0 +1,564 @@
<?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 Stundenplan extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getRoomplan' => self::PERM_LOGGED,
'Stunden' => self::PERM_LOGGED,
'Reservierungen' => self::PERM_LOGGED,
'getStundenplan' => self::PERM_LOGGED,
'getLehreinheitStudiensemester' => self::PERM_LOGGED,
]);
$this->load->library('LogLib');
$this->loglib->setConfigs(array(
'classIndex' => 5,
'functionIndex' => 5,
'lineIndex' => 4,
'dbLogType' => 'API', // required
'dbExecuteUser' => 'RESTful API'
));
$this->load->library('form_validation');
//load models
$this->load->model('ressource/Stundenplan_model', 'StundenplanModel');
$this->load->model('ressource/Reservierung_model', 'ReservierungModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* fetches Stunden layout from database
* @access public
*
*/
public function Stunden()
{
$this->load->model('ressource/Stunde_model', 'StundeModel');
$stunden = $this->StundeModel->load();
$stunden = $this->getDataOrTerminateWithError($stunden);
$this->terminateWithSuccess($stunden);
}
/**
* fetches room events from a certain date
* @access public
*
*/
public function getRoomplan()
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('ort_kurzbz',"Ort","required");
$this->form_validation->set_rules('start_date',"start_date","required");
$this->form_validation->set_rules('end_date',"end_date","required");
if($this->form_validation->run() === FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the get parameter in local variables
$ort_kurzbz = $this->input->get('ort_kurzbz', TRUE);
$start_date = $this->input->get('start_date', TRUE);
$end_date = $this->input->get('end_date', TRUE);
$roomplan_data = $this->StundenplanModel->stundenplanGruppierung($this->StundenplanModel->getRoomQuery($ort_kurzbz, $start_date, $end_date));
$roomplan_data = $this->getDataOrTerminateWithError($roomplan_data);
$this->expand_object_information($roomplan_data);
$this->terminateWithSuccess($roomplan_data);
}
/**
* fetches stundenplan events from a UID and start/end date
* @access public
*
*/
//TODO: getStundenplan fuer Mitarbeiter anpassen
public function getStundenplan(){
$this->load->model('ressource/Mitarbeiter_model','MitarbeiterModel');
$this->load->model('organisation/Studiensemester_model','StudiensemesterModel');
$this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->load->model('person/Benutzergruppe_model','BenutzergruppeModel');
// form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('start_date', "start_date", "required");
$this->form_validation->set_rules('end_date', "end_date", "required");
if ($this->form_validation->run() === FALSE)
$this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the get parameter in local variables
$start_date = $this->input->get('start_date', TRUE);
$end_date = $this->input->get('end_date', TRUE);
$student_uid = getAuthUID();
if(is_null($student_uid))
{
$this->terminateWithError("No UID");
}
$is_mitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter($student_uid));
if($is_mitarbeiter)
{
$this->terminateWithError("Not possible to look at the Student Calendar as a Mitarbeiter");
}
$semester_range = $this->studienSemesterErmitteln($start_date,$end_date);
$this->sortStudienSemester($semester_range);
$this->applyLoadUeberSemesterHaelfte($semester_range);
// getting the gruppen_kurzbz of the student in the different studiensemester
$benutzer_gruppen = $this->fetchBenutzerGruppenFromStudiensemester($semester_range);
// getting the student_lehrverbaende of the student in the different studiensemester
$student_lehrverband = $this->fetchStudentlehrverbandFromStudiensemester($semester_range);
$stundenplan_query = $this->StundenplanModel->getStundenplanQuery($start_date, $end_date, $semester_range, $benutzer_gruppen, $student_lehrverband);
if(!$stundenplan_query)
{
$this->terminateWithSuccess([]);
}
$stundenplan_data = $this->StundenplanModel->stundenplanGruppierung($stundenplan_query);
$stundenplan_data = $this->getDataOrTerminateWithError($stundenplan_data) ?? [];
$this->expand_object_information($stundenplan_data);
$this->terminateWithSuccess($stundenplan_data);
}
// gets the reservierungen of a room if the ort_kurzbz parameter is supplied otherwise gets the reservierungen of the stundenplan of a student
public function Reservierungen($ort_kurzbz = null)
{
//form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('start_date', "StartDate", "required");
$this->form_validation->set_rules('end_date', "EndDate", "required");
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the get parameter in local variables
$start_date = $this->input->get('start_date', TRUE);
$end_date = $this->input->get('end_date', TRUE);
// querying the reservierungen
$reservierungen = $this->ReservierungModel->getReservierungen($start_date, $end_date, $ort_kurzbz);
$reservierungen = $this->getDataOrTerminateWithError($reservierungen) ?? [];
$this->expand_object_information($reservierungen);
$this->terminateWithSuccess($reservierungen);
}
public function getLehreinheitStudiensemester($lehreinheit_id){
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->LehreinheitModel->addSelect(["studiensemester_kurzbz"]);
$result = $this->LehreinheitModel->load($lehreinheit_id);
$result = current($this->getDataOrTerminateWithError($result))->studiensemester_kurzbz;
$this->terminateWithSuccess($result);
}
// ################# Private Functions
private function expand_object_information($data){
foreach ($data as $item)
{
$lektor_obj_array = array();
$gruppe_obj_array = array();
// load lektor object
foreach ($item->lektor as $lv_lektor)
{
$this->StundenplanModel->addLimit(1);
$lektor_object = $this->StundenplanModel->execReadOnlyQuery("
SELECT mitarbeiter_uid, vorname, nachname, kurzbz
FROM public.tbl_mitarbeiter
JOIN public.tbl_benutzer benutzer ON benutzer.uid = mitarbeiter_uid
JOIN public.tbl_person person ON person.person_id = benutzer.person_id
WHERE kurzbz = ?", [$lv_lektor]);
if (isError($lektor_object)) {
$this->show_error(getError($lektor_object));
}
$lektor_object = $this->getDataOrTerminateWithError($lektor_object);
if(count($lektor_object) == 0)
{
$this->terminateWithError("No lektor object");
}
$lektor_object = current($lektor_object);
// only provide needed information of the mitarbeiter object
$lektor_obj_array[] = $lektor_object;
}
// load gruppe object
foreach ($item->gruppe as $lv_gruppe)
{
$lv_gruppe = strtr($lv_gruppe, ['(' => '', ')' => '', '"' => '']);
$lv_gruppe_array = explode(",", $lv_gruppe);
list($gruppe, $verband, $semester, $studiengang_kz, $gruppen_kuerzel) = $lv_gruppe_array;
$lv_gruppe_object = new stdClass();
$lv_gruppe_object->gruppe = $gruppe;
$lv_gruppe_object->verband = $verband;
$lv_gruppe_object->semester = $semester;
$lv_gruppe_object->studiengang_kz = $studiengang_kz;
$lv_gruppe_object->kuerzel = $gruppen_kuerzel;
$gruppe_obj_array[] = $lv_gruppe_object;
}
$item->gruppe = $gruppe_obj_array;
$item->lektor = $lektor_obj_array;
}
}
// function used to sort an array of studiensemester strings
private function sortStudienSemester(&$semester_range){
usort(
$semester_range,
function($first,$second)
{
$sem_first = null;
$year_first = null;
$match_first = null;
$sem_second = null;
$year_second = null;
$match_second = null;
preg_match('/([WS]+)([0-9]+)/',$first,$match_first);
preg_match('/([WS]+)([0-9]+)/',$second,$match_second);
$sem_first = $match_first[1];
$year_first = intval($match_first[2]);
$sem_second = $match_second[1];
$year_second = intval($match_second[2]);
if($year_first < $year_second)
{
return -1;
}
else if($year_first > $year_second)
{
return 1;
}
else if($year_first == $year_second && $sem_first > $sem_second)
{
return 1;
}
else if($year_first == $year_second && $sem_first < $sem_second)
{
return -1;
}
return 0;
}
);
}
private function fetchBenutzerGruppenFromStudiensemester($semester_range){
$student_uid = getAuthUID();
$benutzer_gruppen = [];
// for each studiensemester fetch the benutzer gruppen and add them to an associate $bentuzer_gruppen array
/*
[
['WS2023'] => [['gruppe1_SS2023','gruppe2_SS2023'],['gruppe1_WS2023','gruppe2_WS2023']],
['SS2024'] => [['gruppe1_WS2023','gruppe2_WS2023'],['gruppe1_SS2024','gruppe2_SS2024']],
['WS2024'] => [['gruppe1_SS2024','gruppe2_SS2024'],['gruppe1_WS2024','gruppe2_WS2024']],
]
*/
foreach($semester_range as $semester_key => $semester_array)
{
$benutzer_gruppen[$semester_key] = [];
// each semester could have ajoint semesters that need to be checked
foreach($semester_array as $semester=>$semester_date_range)
{
// for each active semester query the benutzer_gruppen associated to the semester
$benutzer_query = $this->BenutzergruppeModel->execReadOnlyQuery("
SELECT * FROM tbl_benutzergruppe where uid = ? AND studiensemester_kurzbz = ?",[$student_uid, $semester]);
$benutzer_query_result = $this->getDataOrTerminateWithError($benutzer_query);
array_push(
$benutzer_gruppen[$semester_key],
array_map(
function($item)
{
return "'".$item->gruppe_kurzbz. "'";
},
$benutzer_query_result
)
);
}
}
// merge the gruppen of each studiensemester together for the original studiensemester
/*
[
['WS2023'] => ['gruppe1_SS2023','gruppe2_SS2023','gruppe1_WS2023','gruppe2_WS2023'],
['SS2024'] => ['gruppe1_WS2023','gruppe2_WS2023','gruppe1_SS2024','gruppe2_SS2024'],
['WS2024'] => ['gruppe1_SS2024','gruppe2_SS2024','gruppe1_WS2024','gruppe2_WS2024'],
]
*/
$benutzer_gruppen = array_map(
function($gruppe)
{
$merged_gruppe = [];
foreach($gruppe as $gruppen_array)
{
$merged_gruppe = array_merge($merged_gruppe, $gruppen_array);
}
return $merged_gruppe;
},
$benutzer_gruppen
);
return $benutzer_gruppen;
}
private function fetchStudentlehrverbandFromStudiensemester($semester_range){
$student_uid = getAuthUID();
$student_lehrverband = [];
// for each studiensemester fetch the studentlehrverbaende and add them to an associate $student_lehrverband array
/*
[
['WS2023'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ] ],
['SS2024'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ] ],
['WS2024'] => [ [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ] ],
]
*/
foreach($semester_range as $semester_key => $semester_array)
{
$student_lehrverband[$semester_key] = [];
foreach($semester_array as $semester=>$semester_date_range)
{
// for each active semester query the student_lehrverband associated to the semester
$lehrverband_query = $this->BenutzergruppeModel->execReadOnlyQuery("
SELECT * FROM tbl_studentlehrverband where student_uid = ? AND studiensemester_kurzbz = ?", [$student_uid, $semester]);
$lehrverband_query_result = $this->getDataOrTerminateWithError($lehrverband_query);
array_push($student_lehrverband[$semester_key], array_map(
function ($item)
{
$result = new stdClass();
$result->studiengang_kz = $item->studiengang_kz;
$result->semester = $item->semester;
$result->verband = $item->verband;
$result->gruppe = $item->gruppe;
return $result;
},
$lehrverband_query_result));
}
}
// merge the studentlehrverband of each studiensemester together for the original studiensemester
/*
[
['WS2023'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ],
['SS2024'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ],
['WS2024'] => [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ],
]
*/
$student_lehrverband = array_map(
function($studentlehrverband)
{
$merged_studentlehrverband = [];
foreach($studentlehrverband as $studentlehrverband_array)
{
$merged_studentlehrverband = array_merge($merged_studentlehrverband, $studentlehrverband_array);
}
return $merged_studentlehrverband;
},
$student_lehrverband
);
return $student_lehrverband;
}
private function applyLoadUeberSemesterHaelfte(&$semester_range){
/*
@var($semester_collection)
convert the array of studiensemester into an associative array with the studiensemester as the key
and the values of each key are the studiensemester needed for the query associated to that studiensemester
example:
#INPUT:
['WS2023','SS2024','WS2024']
#OUTPUT:
[
'WS2023' => ['SS2023','WS2023']
'SS2024' => ['WS2023','SS2024']
'WS2024' => ['SS2024','WS2024']
]
*/
$semester_collection = [];
foreach($semester_range as $studiensemester)
{
$previous_studiensemester = $this->StudiensemesterModel->getPreviousFrom($studiensemester);
$previous_studiensemester = $this->getDataOrTerminateWithError($previous_studiensemester);
if (count($previous_studiensemester) == 0) {
$this->terminateWithError("No previous semester");
}
$previous_studiensemester = current($previous_studiensemester)->studiensemester_kurzbz;
$semester_collection[$studiensemester] = [$previous_studiensemester, $studiensemester];
}
/*
@var($studienSemesterDateRanges)
fetches for each studiensemester the start and end date, (SS) summer studiensemester are extended by 1 month to cover the summerbreak
based on the LVPLAN_LOAD_UEBER_SEMESTERHAELFTE constant it will load both the semester and the previous semester with the full date range
or the semester with the full date range and the previous semester with the half date range:
#INPUT:
[
'WS2023' => ['SS2023','WS2023']
'SS2024' => ['WS2023','SS2024']
'WS2024' => ['SS2024','WS2024']
]
#OUTPUT: depends whether LVPLAN_LOAD_UEBER_SEMESTERHAELFTE is true or false
~ if LVPLAN_LOAD_UEBER_SEMESTERHAELFTE == true
[
"SS2024": [
"WS2023": [
"start"=> "2024-02-03",
"ende"=> "2024-08-31"
],
"SS2024": [
"start"=> "2024-02-03",
"ende"=> "2024-08-31"
]
]
]
~ if LVPLAN_LOAD_UEBER_SEMESTERHAELFTE == false
[
"SS2024": [
"WS2023": [
"start"=> "2024-02-03",
"ende"=> "2024-05-17"
],
"SS2024": [
"start"=> "2024-02-03",
"ende"=> "2024-08-31"
]
]
]
*/
$studienSemesterDateRanges=[];
foreach($semester_collection as $semester_original => $semester_adjoint)
{
$semester_start_ende = $this->StudiensemesterModel->getStartEndeFromStudiensemester($semester_original);
$semester_start_ende = current($this->getDataOrTerminateWithError($semester_start_ende));
// initialize empty arrays to add key value pairs
$studienSemesterDateRanges[$semester_original] = [];
// check if the studiensemester is a summer semester and add 1 month to bridge the school summer break
$match = null;
preg_match("/^(SS)([0-9]+)/",$semester_original,$match);
if(count($match) >0)
{
$one_month = new DateInterval('P1M');
$one_day = DateInterval::createFromDateString('1 days');
$summer_studiensemester_end_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->ende);
$summer_studiensemester_end_date->add($one_month);
$summer_studiensemester_end_date->sub($one_day);
$semester_start_ende->ende = date_format($summer_studiensemester_end_date,'Y-m-d');
}
if (defined('LVPLAN_LOAD_UEBER_SEMESTERHAELFTE') && LVPLAN_LOAD_UEBER_SEMESTERHAELFTE === true)
{
foreach($semester_adjoint as $adjoint)
{
$studienSemesterDateRanges[$semester_original][$adjoint]=$semester_start_ende;
}
}
else
{
//TODO: half of a DateInterval might not be correctly calculated
// calculate the half of the studiensemester
$studiensemester_start_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->start);
$studiensemester_end_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->ende);
$studiensemester_time_difference = $studiensemester_start_date->diff($studiensemester_end_date);
$half_dateNumber = ceil($studiensemester_time_difference->d/2)+ceil(($studiensemester_time_difference->m*30)/2);
$half_dateInterval = new DateInterval('P'.strval($half_dateNumber) .'D');
$studiensemester_half = date_format($studiensemester_start_date->add($half_dateInterval),'Y-m-d');
$first_half = new stdClass();
$first_half->start = $semester_start_ende->start;
$first_half->ende = $studiensemester_half;
$studienSemesterDateRanges[$semester_original][$semester_adjoint[0]] = $first_half;
$studienSemesterDateRanges[$semester_original][$semester_adjoint[1]] = $semester_start_ende;
}
$semester_range = $studienSemesterDateRanges;
}
}
private function studienSemesterErmitteln($start_date,$end_date){
// gets all studiensemester from the student from start_date to end_date
$semester_range = $this->StudiensemesterModel->getByDate($start_date,$end_date);
$semester_range = array_map(
function($sem)
{
return $sem->studiensemester_kurzbz;
},
$this->getDataOrTerminateWithError($semester_range)
);
// if no studiensemester is found for the given timespan, get the nearest studiensemester
if(count($semester_range) == 0)
{
$aktuelle_studiensemester = $this->StudiensemesterModel->getNearest();
$aktuelle_studiensemester = $this->getDataOrTerminateWithError($aktuelle_studiensemester);
if (count($aktuelle_studiensemester) == 0) {
$this->terminateWithError("No aktuelles semester");
}
$aktuelle_studiensemester = current($aktuelle_studiensemester)->studiensemester_kurzbz;
// push aktuelles semester in active semester array
array_push($semester_range, $aktuelle_studiensemester);
}
return $semester_range;
}
}
@@ -0,0 +1,213 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Mylv extends Auth_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'Student' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Studiensemester' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Lvs' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Info' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Pruefungen' => ['student/anrechnung_beantragen:r','user:r'] // TODO(chris): permissions?
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
*/
public function Student()
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
/**
*/
public function Studiensemester()
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$result = $this->StudiensemesterModel->getWhereStudentHasLvs(getAuthUID());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
/**
*/
public function Lvs($studiensemester_kurzbz)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID(), $studiensemester_kurzbz, getUserLanguage());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
/**
*/
public function Info($studiensemester_kurzbz, $lehrveranstaltung_id)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
if (isError($result))
return $this->outputJsonError(getError($result));
$lv = current(getData($result) ?: []);
if (!$lv)
return $this->outputJsonError('Could\'t find Lehrveranstaltung with id: ' . $lehrveranstaltung_id);
$this->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
$result = $this->LehreinheitmitarbeiterModel->getForLv($lehrveranstaltung_id, $studiensemester_kurzbz);
if (isError($result))
return $this->outputJsonError(getError($result));
$lvinfo = [];
$lvinfo['lektoren'] = getData($result) ?: [];
$kollisionsfreie_user = unserialize(KOLLISIONSFREIE_USER);
$lvinfo['lektoren'] = array_values(array_filter($lvinfo['lektoren'], function ($v) use ($kollisionsfreie_user) {
return !in_array($v->uid, $kollisionsfreie_user);
}));
$lvinfo['lvLeitung'] = array_values(array_filter($lvinfo['lektoren'], function ($v) {
return $v->lehrfunktion_kurzbz == 'LV-Leitung';
}));
$this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
$result = $this->OrganisationseinheitModel->getWithType($lv->oe_kurzbz);
if (isError($result))
return $this->outputJsonError(getError($result));
$lvinfo['oe'] = current(getData($result) ?: []);
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$result = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('Leitung', $lv->oe_kurzbz);
if (isError($result))
return $this->outputJsonError(getError($result));
$lvinfo['oeLeitung'] = getData($result) ?: [];
$result = $this->LehrveranstaltungModel->getKoordinator($lehrveranstaltung_id, $studiensemester_kurzbz);
if (isError($result))
return $this->outputJsonError(getError($result));
$lvinfo['koordinator'] = getData($result) ?: [];
if (defined('ACTIVE_ADDONS') && in_array('lvinfo', explode(';', ACTIVE_ADDONS)) && file_exists(FHCPATH . 'addons/lvinfo/include/lvinfo.class.php'))
{
require_once(FHCPATH . 'addons/lvinfo/include/lvinfo.class.php');
$lvinfoObj = new lvinfo();
$lvinfoObj->loadLVinfo($lehrveranstaltung_id, $studiensemester_kurzbz, null, true);
if (is_array($lvinfoObj->result))
{
$oldP = property_exists($this, 'p') ? $this->p : null;
$result = [];
$lvinfos = $lvinfoObj->result;
$lvinfoSet = new lvinfo();
$lvinfoSet->load_lvinfo_set($studiensemester_kurzbz);
foreach ($lvinfos as $lvi)
{
$this->p = null;
$this->loadPhrases('ui', $lvi->sprache);
$result[$lvi->sprache] = [];
foreach ($lvinfoSet->result as $set)
{
$key = $set->lvinfo_set_kurzbz;
if (!isset($lvi->data[$key]))
continue;
$info = [
'header' => $set->lvinfo_set_bezeichnung[$lvi->sprache]
];
if (isset($set->einleitungstext[$lvi->sprache]))
$info['subheader'] = $set->einleitungstext[$lvi->sprache];
switch ($set->lvinfo_set_typ)
{
case 'boolean':
$info['body'] = $this->p->t('ui', $lvi->data[$key] === true ? 'ja' : 'nein');
break;
case 'array':
$info['body'] = array_map('htmlspecialchars', $lvi->data[$key]);
break;
case 'editor':
$info['body'] = $lvi->data[$key];
break;
default:
$info['body'] = htmlspecialchars($lvi->data[$key]);
}
if ($info['body'])
$result[$lvi->sprache][] = $info;
}
}
if ($result)
{
$lvinfo['lvinfo'] = $result;
$lvinfo['lvinfoDefaultLang'] = getUserLanguage();
$this->load->model('system/Sprache_model', 'SpracheModel');
$result = $this->SpracheModel->loadMultiple(array_keys($result));
if (!isError($result))
{
$result = getData($result);
$lvinfo['sprachen'] = [];
foreach ($result as $sprache) {
$lvinfo['sprachen'][$sprache->sprache] = $sprache;
}
}
}
$this->p = $oldP;
}
}
$this->outputJsonSuccess($lvinfo);
}
/**
*/
public function Pruefungen($lehrveranstaltung_id)
{
$this->load->model('education/Pruefung_model', 'PruefungModel');
$result = $this->PruefungModel->getByStudentAndLv(getAuthUID(), $lehrveranstaltung_id, getUserLanguage());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
}
@@ -0,0 +1,73 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Stundenplan extends Auth_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'index' => ['basis/cis'],
'Reservierungen' => ['basis/cis'],
'Stunden' => ['basis/cis'],
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
*/
public function index()
{
$this->load->model('ressource/Stundenplan_model', 'StundenplanModel');
/* $result = $this->StundenplanModel->loadForUid(getAuthUID());
if (isError($result))
return $this->outputJsonError(getError($result));
*/
$res = $this->StundenplanModel->stundenplanGruppierung($this->StundenplanModel->getStundenplanQuery(getAuthUID()));
$res = getData($res);
$this->outputJsonSuccess($res);
}
/**
*/
public function Reservierungen()
{
$this->load->model('ressource/Reservierung_model', 'ReservierungModel');
$result = $this->ReservierungModel->loadForUid(getAuthUID());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
/**
*/
public function Stunden()
{
$this->load->model('ressource/Stunde_model', 'StundeModel');
$result = $this->StundeModel->load();
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
}
+76
View File
@@ -0,0 +1,76 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
class Api extends Auth_Controller
{
public function __construct()
{
parent::__construct(
array(
'index' => 'dashboard/admin:rw',
'getNews' => 'dashboard/benutzer:r',
'getAmpeln' => 'dashboard/benutzer:r',
)
);
$this->load->library('AuthLib', null, 'AuthLib');
$this->_setAuthUID();
}
public function index()
{
echo 'Dashboard API Controller';
}
/**
* Get News.
*/
public function getNews()
{
$limit = $this->input->get('limit');
$this->load->model('content/News_model', 'NewsModel');
$result = $this->NewsModel->getAll($limit);
if (hasData($result))
{
$this->outputJson(getData($result), REST_Controller::HTTP_OK);
}
else
{
$this->terminateWithJsonError('fehler entdeckt');
}
}
/**
* Get Ampeln.
*/
public function getAmpeln()
{
$this->load->model('content/Ampel_model', 'AmpelModel');
$result = $this->AmpelModel->getByUser($this->_uid);
if (hasData($result))
{
$this->outputJson(getData($result), REST_Controller::HTTP_OK);
}
else
{
$this->terminateWithJsonError('fehler entdeckt');
}
}
/**
* Retrieve the UID of the logged user and checks if it is valid
*/
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid) show_error('User authentification failed');
}
}
@@ -0,0 +1,216 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
/**
* Description of Config
*
* @author bambi
*/
class Config extends Auth_Controller
{
public function __construct()
{
parent::__construct(
array(
'index' => 'dashboard/benutzer:r',
'dummy' => 'dashboard/benutzer:r',
'genWidgetId' => 'dashboard/benutzer:rw',
'addWidgetsToPreset' => 'dashboard/admin:rw',
'removeWidgetFromPreset' => 'dashboard/admin:rw',
'addWidgetsToUserOverride' => 'dashboard/benutzer:rw',
'removeWidgetFromUserOverride' => 'dashboard/benutzer:rw',
'funktionen' => 'dashboard/admin:r',
'preset' => 'dashboard/admin:r',
'presetBatch' => 'dashboard/admin:r'
)
);
$this->load->library('dashboard/DashboardLib', null, 'DashboardLib');
$this->load->library('AuthLib', null, 'AuthLib');
$this->load->model('ressource/Funktion_model', 'FunktionModel');
}
public function index()
{
$dashboard_kurzbz = $this->input->get('db');
$uid = $this->AuthLib->getAuthObj()->username;
$dashboard = $this->DashboardLib->getDashboardByKurzbz($dashboard_kurzbz);
if(!$dashboard) {
http_response_code(404);
$this->terminateWithJsonError(array(
'error' => 'Dashboard ' . $dashboard_kurzbz . ' not found.'
));
}
$mergedconfig = $this->DashboardLib->getMergedConfig($dashboard->dashboard_id, $uid);
$this->outputJsonSuccess($mergedconfig);
}
public function genWidgetId()
{
$dashboard_kurzbz = $this->input->get('db');
$widgetid = $this->DashboardLib->generateWidgetId($dashboard_kurzbz);
$this->outputJsonSuccess(array(
'widgetid' => $widgetid
));
}
public function addWidgetsToPreset()
{
$input = json_decode($this->input->raw_input_stream);
$dashboard_kurzbz = $input->db;
$funktion_kurzbz = $input->funktion_kurzbz;
$preset = $this->DashboardLib->getPresetOrCreateEmptyPreset($dashboard_kurzbz, $funktion_kurzbz);
$preset_decoded = json_decode($preset->preset, true);
$this->DashboardLib->addWidgetsToWidgets($preset_decoded['widgets'], $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$preset->preset = json_encode($preset_decoded);
$result = $this->DashboardLib->insertOrUpdatePreset($preset);
if (isError($result)) {
http_response_code(500);
$this->terminateWithJsonError('preset could not be saved');
}
$this->outputJsonSuccess(array('msg' => 'preset successfully stored.', 'data' => $preset_decoded));
}
public function removeWidgetFromPreset()
{
$input = json_decode($this->input->raw_input_stream);
$dashboard_kurzbz = $input->db;
$funktion_kurzbz = $input->funktion_kurzbz;
$widgetid = $input->widgetid;
$preset = $this->DashboardLib->getPreset($dashboard_kurzbz, $funktion_kurzbz);
if ($preset === null) {
http_response_code(404);
$this->terminateWithJsonError('preset for dashboard ' . $dashboard_kurzbz . ' and funktion ' . $funktion_kurzbz . ' not found.');
}
$preset_decoded = json_decode($preset->preset, true);
if (!$this->DashboardLib->removeWidgetFromWidgets($preset_decoded['widgets'], $funktion_kurzbz, $widgetid))
{
http_response_code(404);
$this->terminateWithJsonError('widgetid ' . $widgetid . ' not found');
}
$preset->preset = json_encode($preset_decoded);
$result = $this->DashboardLib->insertOrUpdatePreset($preset);
if (isError($result))
{
http_response_code(500);
$this->terminateWithJsonError('failed to remove widget');
}
$this->outputJsonSuccess(array('msg' => 'preset successfully updated.'));
}
public function addWidgetsToUserOverride()
{
$input = json_decode($this->input->raw_input_stream);
$dashboard_kurzbz = $input->db;
$funktion_kurzbz = $input->funktion_kurzbz;
$uid = $this->AuthLib->getAuthObj()->username;
$override = $this->DashboardLib->getOverrideOrCreateEmptyOverride($dashboard_kurzbz, $uid);
$override_decoded = json_decode($override->override, true);
$this->DashboardLib->addWidgetsToWidgets($override_decoded['widgets'], $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$override->override = json_encode($override_decoded);
$result = $this->DashboardLib->insertOrUpdateOverride($override);
if (isError($result)) {
http_response_code(500);
$this->terminateWithJsonError('override could not be saved');
}
$this->outputJsonSuccess(array('msg' => 'override successfully stored.', 'data' => $override_decoded));
}
public function removeWidgetFromUserOverride()
{
$input = json_decode($this->input->raw_input_stream);
$dashboard_kurzbz = $input->db;
$funktion_kurzbz = $input->funktion_kurzbz;
$uid = $this->AuthLib->getAuthObj()->username;
$widgetid = $input->widgetid;
$override = $this->DashboardLib->getOverride($dashboard_kurzbz, $uid);
if (empty($override)) {
http_response_code(404);
$this->terminateWithJsonError('userconfig for dashboard ' . $dashboard_kurzbz . ' not found.');
}
$override_decoded = json_decode($override->override, true);
if (!$this->DashboardLib->removeWidgetFromWidgets($override_decoded['widgets'], $funktion_kurzbz, $widgetid))
{
http_response_code(404);
$this->terminateWithJsonError('widgetid ' . $widgetid . ' not found');
}
$override->override = json_encode($override_decoded);
$result = $this->DashboardLib->insertOrUpdateOverride($override, $uid);
if (isError($result))
{
http_response_code(500);
$this->terminateWithJsonError('failed to remove widget');
}
$this->outputJsonSuccess(array('msg' => 'override successfully updated.'));
}
public function funktionen()
{
$funktionen = $this->FunktionModel->load();
if (isError($funktionen)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($funktionen)
]);
}
return $this->outputJsonSuccess(getData($funktionen) ?: []);
}
public function preset()
{
$db = $this->input->get('db');
$funktion = $this->input->get('funktion');
$conf = $this->DashboardLib->getPreset($db, $funktion);
if (!$conf)
return $this->outputJsonSuccess(['widgets' => [$funktion => []]]);
return $this->outputJsonSuccess(json_decode($conf->preset, true));
}
public function presetBatch()
{
$db = $this->input->get('db');
$funktionen = $this->input->get('funktionen');
$result = [];
foreach ($funktionen as $funktion) {
$conf = $this->DashboardLib->getPreset($db, $funktion);
if ($conf)
{
$preset = json_decode($conf->preset, true);
if (!isset($preset['widgets']) || !isset($preset['widgets'][$funktion]))
$result[$funktion] = [];
else
$result[$funktion] = $preset['widgets'][$funktion];
}
else
$result[$funktion] = [];
}
return $this->outputJsonSuccess($result);
}
}
@@ -0,0 +1,86 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
/**
* Description of Widget
*
* @author chris
*/
class Dashboard extends Auth_Controller
{
public function __construct()
{
parent::__construct(
array(
'index' => 'dashboard/admin:r',
'create' => 'dashboard/admin:rw',
'update' => 'dashboard/admin:rw',
'delete' => 'dashboard/admin:rw'
)
);
$this->load->library('dashboard/DashboardLib', null, 'DashboardLib');
$this->load->model('dashboard/Dashboard_model', 'DashboardModel');
}
public function index()
{
$result = $this->DashboardModel->load();
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result) ?: []);
}
public function create()
{
$input = $this->getPostJSON();
$result = $this->DashboardModel->insert($input);
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result) ?: []);
}
public function update()
{
$input = $this->getPostJSON();
$result = $this->DashboardModel->update($input->dashboard_id, $input);
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result) ?: []);
}
public function delete()
{
$input = $this->getPostJSON();
$result = $this->DashboardModel->delete($input->dashboard_id);
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result) ?: []);
}
}
@@ -0,0 +1,58 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*/
class DashboardDemo extends Auth_Controller
{
private $_uid; // uid of the logged user
/**
* Constructor
*/
public function __construct()
{
// Set required permissions
parent::__construct(
array(
'index' => 'dashboard/benutzer:r',
'admin' => 'dashboard/admin:rw'
)
);
$this->load->library('AuthLib');
$this->load->library('WidgetLib');
$this->_setAuthUID(); // sets property uid
$this->setControllerId(); // sets the controller id
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
public function index()
{
$this->load->view('dashboard/dashboard_demo.php', []);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
public function admin()
{
$this->load->view('dashboard/dashboard_demo_admin.php', []);
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
/**
* Retrieve the UID of the logged user and checks if it is valid
*/
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid) show_error('User authentification failed');
}
}
@@ -0,0 +1,109 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
/**
* Description of Widget
*
* @author chris
*/
class Widget extends Auth_Controller
{
public function __construct()
{
parent::__construct(
array(
'index' => ['dashboard/benutzer:r', 'dashboard/admin:r'],
'getAll' => 'dashboard/admin:r',
'getWidgetsForDashboard' => ['dashboard/benutzer:rw', 'dashboard/admin:r'],
'setAllowed' => 'dashboard/admin:rw'
)
);
$this->load->library('dashboard/DashboardLib', null, 'DashboardLib');
$this->load->model('dashboard/Widget_model', 'WidgetModel');
$this->load->model('dashboard/Dashboard_Widget_model', 'DashboardWidgetModel');
}
public function index()
{
$widget_id = $this->input->get('id');
$widget = $this->WidgetModel->load($widget_id);
if (isError($widget) || !getData($widget))
return $this->outputJsonSuccess([
"widget_id" => 0,
"widget_kurzbz" => "notfound",
"arguments" => json_encode([
"className" => 'alert-danger',
"title" => 'Widget Not Found',
"msg" => 'The widget with the id ' . $widget_id . ' could not be found'
]),
"setup" => json_encode([
"name" => 'Widget Not Found',
"file" => 'DashboardWidget/Default.js',
"width" => 1,
"height" => 1
])
]);
return $this->outputJsonSuccess(current(getData($widget)));
}
public function getAll()
{
$dashboard_id = $this->input->get('dashboard_id');
$result = $this->WidgetModel->getWithAllowedForDashboard($dashboard_id);
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result) ?: []);
}
public function getWidgetsForDashboard()
{
$db = $this->input->get('db');
$result = $this->WidgetModel->getForDashboard($db);
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
$this->outputJsonSuccess(getData($result) ?: []);
}
public function setAllowed()
{
$input = $this->getPostJSON();
$dashboard_id = $input->dashboard_id;
$widget_id = $input->widget_id;
$action = $input->action;
if ($action == 'add') {
$result = $this->DashboardWidgetModel->insert([
'dashboard_id' => $dashboard_id,
'widget_id' => $widget_id
]);
} elseif ($action == 'delete') {
$result = $this->DashboardWidgetModel->delete([
'dashboard_id' => $dashboard_id,
'widget_id' => $widget_id
]);
} else {
http_response_code(404); // TODO(chris): 400?
$this->terminateWithJsonError([
'error' => 'action value invalid'
]);
}
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result));
}
}
@@ -1,114 +0,0 @@
<?php
if (!defined("BASEPATH")) exit("No direct script access allowed");
use vertragsbestandteil\VertragsbestandteilFactory;
/**
* Description of VertragsbestandteilTest
*
* @author bambi
*/
class VertragsbestandteilTest extends JOB_Controller
{
public function __construct()
{
parent::__construct();
$this->load->library('vertragsbestandteil/VertragsbestandteilLib',
null, 'VertragsbestandteilLib');
$this->load->library('vertragsbestandteil/GehaltsbestandteilLib',
null, 'GehaltsbestandteilLib');
}
public function testFetch()
{
$dienstverhaeltnis_id = 1;
$stichtag = null;
foreach($this->VertragsbestandteilLib->fetchVertragsbestandteile(
$dienstverhaeltnis_id, $stichtag) as $vertragsbestandteil)
{
//print_r($vertragsbestandteil);
echo $vertragsbestandteil . "\n";
}
}
public function testUpdate()
{
$now = new DateTime();
$data = new stdClass();
$data->vertragsbestandteil_id = 32;
$data->von = '2022-12-05';
$data->wochenstunden = 45.0;
$data->vertragsbestandteiltyp_kurzbz = VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_STUNDEN;
$vb = VertragsbestandteilFactory::getVertragsbestandteil($data);
try
{
$this->VertragsbestandteilLib->storeVertragsbestandteil($vb);
echo "Update successful.\n";
}
catch( Exception $ex )
{
echo "Update failed.\n";
}
}
public function testInsert()
{
$now = new DateTime();
$data = new stdClass();
$data->dienstverhaeltnis_id = 1;
$data->von = '2022-12-01';
$data->insertamum = $now->format(DateTime::ATOM);
$data->insertvon = 'ma0080';
$data->vertragsbestandteiltyp_kurzbz = VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_FUNKTION;
$data->benutzerfunktion_id = 112667;
$data->anmerkung = 'test funkton';
$data->kuendigungsrelevant = false;
$vb = VertragsbestandteilFactory::getVertragsbestandteil($data);
try
{
$this->VertragsbestandteilLib->storeVertragsbestandteil($vb);
echo "Insert successful.\n";
}
catch( Exception $ex )
{
echo "Insert failed.\n";
}
}
public function testGehaltsbestandteilInsert()
{
$data = new stdClass();
$data->gehaltsbestandteil_id = 2;
/*
$data->dienstverhaeltnis_id = 39;
$data->vertragsbestandteil_id = 123;
$data->gehaltstyp_kurzbz = 'zulage';
$data->von = '2023-04-01';
$data->bis = '2023-08-31';
$data->anmerkung = 'test anmerkung';
$data->grundbetrag = 100;
$data->betrag_valorisiert = 100;
$data->valorisierung = true;
*/
$data->auszahlungen = 12;
$gb = new \vertragsbestandteil\Gehaltsbestandteil();
$gb->hydrateByStdClass($data);
print_r($gb->toStdClass());
$this->GehaltsbestandteilLib->storeGehaltsbestandteil($gb);
}
}
@@ -6,58 +6,59 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
*/
class Pruefungsprotokoll extends Auth_Controller
{
private $_uid; // uid of the logged user
private $_uid; // uid of the logged user
/**
* Constructor
*/
public function __construct()
{
// Set required permissions
parent::__construct(
array(
'index' => 'lehre/pruefungsbeurteilung:r',
'Protokoll' => 'lehre/pruefungsbeurteilung:r',
'saveProtokoll' => 'lehre/pruefungsbeurteilung:rw',
)
);
/**
* Constructor
*/
public function __construct()
{
// Set required permissions
parent::__construct(
array(
'index' => 'lehre/pruefungsbeurteilung:r',
'Protokoll' => 'lehre/pruefungsbeurteilung:r',
'showProtokoll' => 'lehre/pruefungsbeurteilung:r',
'saveProtokoll' => 'lehre/pruefungsbeurteilung:rw',
)
);
// Load models
$this->load->model('education/Abschlusspruefung_model', 'AbschlusspruefungModel');
$this->load->model('education/Abschlussbeurteilung_model', 'AbschlussbeurteilungModel');
// Load models
$this->load->model('education/Abschlusspruefung_model', 'AbschlusspruefungModel');
$this->load->model('education/Abschlussbeurteilung_model', 'AbschlussbeurteilungModel');
$this->load->library('PermissionLib');
$this->load->library('AuthLib');
$this->load->library('PermissionLib');
$this->load->library('AuthLib');
// Load language phrases
$this->loadPhrases(
array(
'ui',
'global',
'person',
'abschlusspruefung',
// Load language phrases
$this->loadPhrases(
array(
'ui',
'global',
'person',
'abschlusspruefung',
'password',
'lehre'
)
);
)
);
$this->_setAuthUID(); // sets property uid
$this->_setAuthUID(); // sets property uid
$this->setControllerId(); // sets the controller id
}
$this->setControllerId(); // sets the controller id
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
// -----------------------------------------------------------------------------------------------------------------
// Public methods
public function index()
{
$this->load->library('WidgetLib');
// Protokolle anzeigen seit heute / letzte Woche / alle
$period = $this->input->post('period');
$period = (!is_null($period)) ? $period : 'today';
$data = array('period' => $period);
$this->load->view('lehre/pruefungsprotokollUebersicht.php', $data);
}
@@ -66,47 +67,15 @@ class Pruefungsprotokoll extends Auth_Controller
*/
public function Protokoll()
{
$abschlusspruefung_id = $this->input->get('abschlusspruefung_id');
$this->load->view('lehre/pruefungsprotokoll.php', $this->_getPruefungsprotokollData());
}
if (!is_numeric($abschlusspruefung_id))
show_error('invalid abschlusspruefung');
$abschlusspruefung_saved = false;
$abschlusspruefung = $this->_getAbschlusspruefungBerechtigt($abschlusspruefung_id);
if (isError($abschlusspruefung))
show_error(getError($abschlusspruefung));
else
{
$abschlusspruefung = getData($abschlusspruefung);
$abschlusspruefung_saved = isset($abschlusspruefung->protokoll) && isset($abschlusspruefung->abschlussbeurteilung_kurzbz);
}
$this->AbschlussbeurteilungModel->addOrder("sort", "ASC");
$this->AbschlussbeurteilungModel->addOrder("(CASE WHEN abschlussbeurteilung_kurzbz = 'ausgezeichnet' THEN 1
WHEN abschlussbeurteilung_kurzbz = 'gut' THEN 2
WHEN abschlussbeurteilung_kurzbz = 'bestanden' THEN 3
WHEN abschlussbeurteilung_kurzbz = 'angerechnet' THEN 4
ELSE 5
END
)");
$abschlussbeurteilung = $this->AbschlussbeurteilungModel->load();
if (isError($abschlussbeurteilung))
show_error(getError($abschlussbeurteilung));
else
$abschlussbeurteilung = getData($abschlussbeurteilung);
$language = getUserLanguage();
$data = array(
'abschlusspruefung' => $abschlusspruefung,
'abschlussbeurteilung' => $abschlussbeurteilung,
'abschlusspruefung_saved' => $abschlusspruefung_saved,
'language' => $language
);
$this->load->view('lehre/pruefungsprotokoll.php', $data);
/**
* Show Pruefungsprotokoll.
*/
public function showProtokoll()
{
$this->load->view('lehre/pruefungsprotokoll.php', array_merge($this->_getPruefungsprotokollData(), array('readonly' => true)));
}
/**
@@ -168,18 +137,66 @@ class Pruefungsprotokoll extends Auth_Controller
$this->outputJsonError($this->p->t('ui', 'ungueltigeParameter'));
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
// -----------------------------------------------------------------------------------------------------------------
// Private methods
/**
* Retrieve the UID of the logged user and checks if it is valid
*/
private function _setAuthUID()
{
$this->_uid = getAuthUID();
/**
* Retrieve the UID of the logged user and checks if it is valid
*/
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid) show_error('User authentification failed');
}
if (!$this->_uid) show_error('User authentification failed');
}
/**
*
* @param
* @return object success or error
*/
private function _getPruefungsprotokollData()
{
$abschlusspruefung_id = $this->input->get('abschlusspruefung_id');
if (!is_numeric($abschlusspruefung_id))
show_error('invalid abschlusspruefung');
$abschlusspruefung_saved = false;
$abschlusspruefung = $this->_getAbschlusspruefungBerechtigt($abschlusspruefung_id);
if (isError($abschlusspruefung))
show_error(getError($abschlusspruefung));
else
{
$abschlusspruefung = getData($abschlusspruefung);
$abschlusspruefung_saved = isset($abschlusspruefung->protokoll) && isset($abschlusspruefung->abschlussbeurteilung_kurzbz);
}
$this->AbschlussbeurteilungModel->addOrder("sort", "ASC");
$this->AbschlussbeurteilungModel->addOrder("(CASE WHEN abschlussbeurteilung_kurzbz = 'ausgezeichnet' THEN 1
WHEN abschlussbeurteilung_kurzbz = 'gut' THEN 2
WHEN abschlussbeurteilung_kurzbz = 'bestanden' THEN 3
WHEN abschlussbeurteilung_kurzbz = 'angerechnet' THEN 4
ELSE 5
END
)");
$abschlussbeurteilung = $this->AbschlussbeurteilungModel->load();
if (isError($abschlussbeurteilung))
show_error(getError($abschlussbeurteilung));
else
$abschlussbeurteilung = getData($abschlussbeurteilung);
$language = getUserLanguage();
return array(
'abschlusspruefung' => $abschlusspruefung,
'abschlussbeurteilung' => $abschlussbeurteilung,
'abschlusspruefung_saved' => $abschlusspruefung_saved,
'language' => $language
);
}
/**
* Retrieves an Abschlussprüfung, with permission check
@@ -187,7 +204,7 @@ class Pruefungsprotokoll extends Auth_Controller
* @param $abschlusspruefung_id
* @return object success or error
*/
private function _getAbschlusspruefungBerechtigt($abschlusspruefung_id)
private function _getAbschlusspruefungBerechtigt($abschlusspruefung_id)
{
$result = error('Error when getting Abschlusspruefung');
@@ -29,6 +29,7 @@ class Gruppenmanagement extends Auth_Controller
$this->load->model('person/benutzer_model', 'BenutzerModel');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('person/benutzergruppe_model', 'BenutzergruppeModel');
$this->load->model('person/gruppe_manager_model', 'GruppemanagerModel');
$this->load->model('system/Log_model', 'LogModel');
$this->load->library('WidgetLib');
@@ -117,6 +118,27 @@ class Gruppenmanagement extends Auth_Controller
$result = error('Uid missing');
else
{
$this->GruppemanagerModel->addSelect('1');
$isManagerRes = $this->GruppemanagerModel->loadWhere(
array(
'uid' => $this->_uid,
'gruppe_kurzbz' => $gruppe_kurzbz
)
);
if (isError($isManagerRes))
{
$this->outputJsonError(getError($isManagerRes));
return;
}
if (!hasData($isManagerRes))
{
$this->outputJsonError($this->p->t('gruppenmanagement', 'nichtZumEditierenDerGruppeBerechtigt'));
return;
}
$this->BenutzergruppeModel->addSelect('1');
$benutzerExistsRes = $this->BenutzergruppeModel->loadWhere(
array(
'uid' => $uid,
@@ -170,6 +192,26 @@ class Gruppenmanagement extends Auth_Controller
$result = error('Uid missing');
else
{
$this->GruppemanagerModel->addSelect('1');
$isManagerRes = $this->GruppemanagerModel->loadWhere(
array(
'uid' => $this->_uid,
'gruppe_kurzbz' => $gruppe_kurzbz
)
);
if (isError($isManagerRes))
{
$this->outputJsonError(getError($isManagerRes));
return;
}
if (!hasData($isManagerRes))
{
$this->outputJsonError($this->p->t('gruppenmanagement', 'nichtZumEditierenDerGruppeBerechtigt'));
return;
}
$result = $this->BenutzergruppeModel->delete(
array(
'uid' => $uid,
@@ -1,44 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Test Search Vue Component
*/
class TestSearch extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'index' => 'system/developer:r'
)
);
// Loads WidgetLib
$this->load->library('WidgetLib');
// Loads phrases system
$this->loadPhrases(
array(
'global',
'ui',
'filter'
)
);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Everything has a beginning
*/
public function index()
{
$this->load->view('system/logs/testSearch.php');
}
}
+14
View File
@@ -46,6 +46,20 @@ class CI3_Events
* NOTE(chris): Autoload Events config
*/
require_once(APPPATH.'config/Events.php');
$active_addons_array = explode(";", ACTIVE_ADDONS);
foreach (scandir(APPPATH.'config/extensions') as $dir)
if ($dir[0] != '.' && file_exists(APPPATH.'config/extensions/'.$dir.'/Events.php'))
require_once APPPATH.'config/extensions/'.$dir.'/Events.php';
foreach (scandir(FHCPATH.'addons') as $dir)
if ($dir[0] != '.' && file_exists(FHCPATH.'addons/'.$dir.'/Events.php'))
{
// only includes the Events of the addon if the addon is one of the active addons in the cis config
if(in_array($dir,$active_addons_array))
{
require_once FHCPATH . 'addons/' . $dir . '/Events.php';
}
}
+54 -5
View File
@@ -60,6 +60,9 @@ class DB_Model extends CI_Model
protected $pk; // Name of the PrimaryKey for DB-Update, Load, ...
protected $hasSequence; // False if this table has a composite primary key that is not using a sequence
// True if this table has a primary key that uses a sequence
//protected $paginationOptions; // $page and $page_size together in an associative array
protected $page;
protected $page_size;
private $executedQueryMetaData;
private $executedQueryListFields;
@@ -531,7 +534,7 @@ class DB_Model extends CI_Model
if (!is_numeric($start) || (is_numeric($start) && $start <= 0))
return error('The start parameter is not valid', EXIT_MODEL);
if (is_numeric($end) && $end > $start)
if (is_numeric($end))
{
$this->db->limit($start, $end);
}
@@ -988,8 +991,8 @@ class DB_Model extends CI_Model
// Find and replace all the occurrences of the provided encrypted columns
// with the postgresql decryption function
$query = str_replace(
$encryptedColumn,
$query = preg_replace(
'/\b' . $encryptedColumn . '\b/',
sprintf(
self::CRYPT_WHERE_TEMPLATE,
$encryptedColumn,
@@ -1103,8 +1106,8 @@ class DB_Model extends CI_Model
{
// Find and replace all the occurrences of the provided encrypted columns
// with the postgresql decryption function
$where = str_replace(
$encryptedColumn,
$where = preg_replace(
'/\b' . $encryptedColumn . '\b/',
sprintf(
self::CRYPT_WHERE_TEMPLATE,
$encryptedColumn,
@@ -1359,5 +1362,51 @@ class DB_Model extends CI_Model
return $udfs;
}
/**
* addPagination
* adds a limit and an optional offset depending on the arguments passed to the function
* @param int $page page to be queried
* @param int $page_size page_size used to calculate the offset of the pagination
* @param int | null $num_rows used to calculate the total amout of pages that are available with the $page and $page_size arguments
*
* @return void
*/
function addPagination( $page, $page_size, $num_rows=null)
{
if (isset($page) && is_numeric($page) && isset($page_size) && is_numeric($page_size) && $page > 0 && $page_size > 0) {
if (isset($num_rows) && is_numeric($num_rows) && $num_rows > 0) {
$floatMaxPageCount = $num_rows / $page_size;
$maxPageCount = ceil($floatMaxPageCount);
if($page > $maxPageCount){
$page = $maxPageCount;
}
}
$offset = (($page-1) * $page_size);
$this->addLimit($page_size, $offset);
} else {
$this->addLimit($page_size);
}
}
/**
* getQueryNumRows
* returns the number of rows of the current build query of the codeigniter query builder instance
* @param bool $reset resets the select of the query
*
* @return Result_object $num_rows
*/
function getNumRows($reset=false)
{
// returns the number of rows when executing the current query without reseting the select statement of the query
$num_rows = $this->db->count_all_results($this->dbTable,$reset);
if($num_rows){
return success($num_rows);
}else{
return error($this->db->error(), EXIT_DATABASE);
}
}
}
+15 -2
View File
@@ -146,6 +146,19 @@ class FHCAPI_Controller extends Auth_Controller
$this->returnObj['meta'][$key] = $value;
}
/**
* @param string $key
* @return mixed
*/
public function getMeta($key)
{
if (!isset($this->returnObj['meta']))
return null;
if (!isset($this->returnObj['meta'][$key]))
return null;
return $this->returnObj['meta'][$key];
}
/**
* @param string $status
* @return void
@@ -184,7 +197,7 @@ class FHCAPI_Controller extends Auth_Controller
}
/**
* @param array $error
* @param string|array|object $error
* @param string $type (optional)
* @param integer $status (optional)
* @return void
@@ -200,7 +213,7 @@ class FHCAPI_Controller extends Auth_Controller
/**
* @param stdclass $result
* @param string $errortype
* @return void
* @return mixed
*/
protected function getDataOrTerminateWithError($result, $errortype = self::ERROR_TYPE_GENERAL)
{
+187
View File
@@ -0,0 +1,187 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Tag_Controller extends FHCAPI_Controller
{
private $_uid;
const BERECHTIGUNG_KURZBZ = 'admin:rw';
public function __construct($permissions)
{
$default_permissions = [
'getTag' => self::BERECHTIGUNG_KURZBZ,
'getTags' => self::BERECHTIGUNG_KURZBZ,
'addTag' => self::BERECHTIGUNG_KURZBZ,
'updateTag' => self::BERECHTIGUNG_KURZBZ,
'doneTag' => self::BERECHTIGUNG_KURZBZ,
'deleteTag' => self::BERECHTIGUNG_KURZBZ,
];
$merged_permissions = array_merge($default_permissions, $permissions);
parent::__construct($merged_permissions);
$this->_setAuthUID();
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('system/Notiztyp_model', 'NotiztypModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
}
public function getTag()
{
$id = $this->input->get('id');
$this->NotizModel->addSelect(
'tbl_notiz.titel,
tbl_notiz.text,
array_to_json(bezeichnung_mehrsprachig::varchar[])->>0 as bezeichnung,
tbl_notiz.notiz_id,
tbl_notiz_typ.style,
tbl_notiz.erledigt as done,
tbl_notiz.insertamum,
tbl_notiz.updateamum,
tbl_notiz.insertvon,
tbl_notiz.updatevon
'
);
$this->NotizModel->addJoin('public.tbl_notiz_typ', 'public.tbl_notiz.typ = public.tbl_notiz_typ.typ_kurzbz');
$notiz = $this->NotizModel->loadWhere(array('notiz_id' => $id));
$this->terminateWithSuccess(hasData($notiz) ? getData($notiz)[0] : array());
}
public function getTags()
{
$this->NotiztypModel->addSelect(
'typ_kurzbz as tag_typ_kurzbz,
array_to_json(bezeichnung_mehrsprachig::varchar[])->>0 as bezeichnung,
style,
beschreibung,
tag
'
);
$this->NotiztypModel->addOrder('prioritaet');
$notiztypen = $this->NotiztypModel->loadWhere(array('aktiv' => true));
$this->terminateWithSuccess(hasData($notiztypen) ? getData($notiztypen) : array());
}
public function addTag($withZuordnung = true)
{
$postData = $this->getPostJson();
$checkTyp = $this->NotiztypModel->loadWhere(array('typ_kurzbz' => $postData->tag_typ_kurzbz));
if (!hasData($checkTyp))
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
if ($withZuordnung)
{
$return = array();
$checkZuordnungType = $this->NotizzuordnungModel->isValidType($postData->zuordnung_typ);
if (!isSuccess($checkZuordnungType))
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$values = array_unique($postData->values);
foreach ($values as $value)
{
$insertResult = $this->addNotiz($postData);
if (isError($insertResult))
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$insertZuordnung = $this->NotizzuordnungModel->insert(array(
'notiz_id' => $insertResult->retval,
$postData->zuordnung_typ => $value
));
if (isError($insertZuordnung))
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$return[] = [$postData->zuordnung_typ => $value, 'id' => $insertResult->retval];
}
$this->terminateWithSuccess($return);
}
else
{
$insertResult = $this->addNotiz($postData);
if (isError($insertResult))
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
return $insertResult->retval;
}
}
private function addNotiz($postData)
{
return $this->NotizModel->insert(array(
'titel' => 'TAG', //TODO klären
'text' => $postData->notiz,
'verfasser_uid' => $this->_uid,
'erledigt' => false,
'insertamum' => date('Y-m-d H:i:s'),
'insertvon' => $this->_uid,
'typ' => $postData->tag_typ_kurzbz
));
}
public function updateTag()
{
$postData = $this->getPostJson();
$updateData = $this->NotizModel->update(array('notiz_id' => $postData->id),
array('text' => $postData->notiz)
);
$this->terminateWithSuccess($updateData);
}
public function doneTag()
{
$postData = $this->getPostJson();
$updateData = $this->NotizModel->update(array('notiz_id' => $postData->id),
array('erledigt' => !$postData->done)
);
$this->terminateWithSuccess($updateData);
}
public function deleteTag($withZuordnung = true)
{
$postData = $this->getPostJson();
$deleteNotiz = "";
if ($withZuordnung)
{
$deleteZuordnung = $this->NotizzuordnungModel->delete(array(
'notiz_id' => $postData->id
));
if (isSuccess($deleteZuordnung))
{
$deleteNotiz = $this->NotizModel->delete(array(
'notiz_id' => $postData->id
));
}
}
else
{
$deleteNotiz = $this->NotizModel->delete(array(
'notiz_id' => $postData->id
));
}
$this->terminateWithSuccess($deleteNotiz);
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid)
show_error('User authentification failed');
}
}
@@ -25,6 +25,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Used to create a return object, should not be used directly
* @return stdClass
*/
function _createReturnObject($code, $error, $retval)
{
@@ -39,7 +40,7 @@ function _createReturnObject($code, $error, $retval)
/**
* Success
*
* @return array
* @return stdClass
*/
function success($retval = null, $code = null)
{
@@ -49,7 +50,7 @@ function success($retval = null, $code = null)
/**
* Error
*
* @return array
* @return stdClass
*/
function error($retval = null, $code = null)
{
+297
View File
@@ -0,0 +1,297 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
use \DateTime as DateTime;
use \DOMDocument as DOMDocument;
use \XSLTProcessor as XSLTProcessor;
/**
* TODO(chris): NEWS: edit & delete button links and confirm
* TODO(chris): NEWS: news_infoscreen xlst
*/
class CmsLib
{
/**
* @var object
*/
protected $ci;
/**
* Constructor
*/
public function __construct()
{
$this->ci =& get_instance();
// Load Models
$this->ci->load->model('content/Content_model', 'ContentModel');
$this->ci->load->model('content/Contentgruppe_model', 'ContentgruppeModel');
$this->ci->load->model('content/Template_model', 'TemplateModel');
if (defined('LOG_CONTENT') && LOG_CONTENT)
$this->ci->load->model('system/Webservicelog_model', 'WebservicelogModel');
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @param int $content_id
* @param int $version
* @param string $sprache
* @param boolean $sichtbar
*
* @return void
*/
public function getContent($content_id, $version = null, $sprache = null, $sichtbar = true)
{
if (!is_numeric($content_id))
return error('ContentID ist ungueltig');
if ($sprache === null)
$sprache = getUserLanguage();
$islocked = $this->ci->ContentgruppeModel->loadWhere(['content_id' => $content_id]);
if (isError($islocked))
return $islocked;
if (getData($islocked)) {
$uid = getAuthUID();
$isberechtigt = $this->ci->ContentgruppeModel->berechtigt($content_id, $uid);
if (isError($isberechtigt))
return $isberechtigt;
if (!getData($isberechtigt))
return error('global/keineBerechtigungFuerDieseSeite');
}
$content = $this->ci->ContentModel->getContent($content_id, $sprache, $version, $sichtbar, true);
if (isError($content))
return $content;
// Legt einen Logeintrag für die Klickstatistik an
if (defined('LOG_CONTENT') && LOG_CONTENT) {
// Nur eingeloggte User werden geloggt, das sonst auch alle Infoscreenaufrufe und dgl. mitgeloggt werden
if (isLogged()) {
$request_data = 'content_id=' . $content_id;
if ($version !== null)
$request_data .= '&version=' . $version;
if ($sichtbar !== true)
$request_data .= '&sichtbar=' . $sichtbar;
$this->ci->WebservicelogModel->insert([
'webservicetyp_kurzbz' => 'content',
'request_id' => $content_id,
'beschreibung' => 'content',
'request_data' => $request_data . '&sprache=' . $sprache,
'execute_time' => 'now()',
'execute_user' => getAuthUID()
]);
}
}
$content = getData($content);
//XSLT Vorlage laden
$template = $this->ci->TemplateModel->load($content->template_kurzbz);
if (isError($template))
return $template;
$template = current(getData($template));
$XML = new DOMDocument();
$XML->loadXML($content->content);
if($content->titel){
$betreff = $content->titel;
}else{
$betreff = $XML->getElementsByTagName('betreff');
}
$xsltemplate = new DOMDocument();
$xsltemplate->loadXML($template->xslt_xhtml_c4);
//Transformation
$processor = new XSLTProcessor();
$processor->importStylesheet($xsltemplate);
$transformed_content = $processor->transformToXML($XML);
//replaces all the dms.php with the new CIS4 Controller
$transformed_content = str_replace('dms.php', APP_ROOT . 'cms/dms.php', $transformed_content);
//replaces all the cms.php with the new CIS4 Controller
$transformed_content = preg_replace('/content\.php\?content\_id\=([0-9]+)/', APP_ROOT.'cis.php/CisVue/Cms/content/$1', $transformed_content);
return success([
"betreff"=>$betreff,
"type"=>$content->template_kurzbz,
"content"=>$transformed_content
]);
}
/**
* @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
*
* @return array queried studiengang_kz and semester
*/
public function getStgAndSem($studiengang_kz, $semester)
{
$this->ci->load->model('crm/Student_model', 'StudentModel');
//Zum anzeigen der Studiengang-Details neben den News
$student = $this->ci->StudentModel->loadWhere(['student_uid' => getAuthUID()]);
if (isError($student))
return $student;
if (getData($student)) {
$student = current(getData($student));
if ($studiengang_kz === null)
$studiengang_kz = $student->studiengang_kz;
if ($semester === null)
$semester = $student->semester;
}
return [$studiengang_kz, $semester];
}
/**
* @param boolean $infoscreen
* @param string | null $studiengang_kz
* @param int | null $semester
* @param boolean $mischen
* @param string $titel
* @param boolean $edit
* @param boolean $sichtbar
*
* @return void
*/
public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true, $page = 1, $page_size = 10)
{
$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(getSprache(), $studiengang_kz, $semester, null, $sichtbar, 0, $page, $page_size, $all, $mischen);
if (isError($news))
return $news;
$news = getData($news);
//var_dump($news->maxPageCount);
foreach ($news as $newsobj) {
if ($studiengang_kz && $edit && !$newsobj->studiengang_kz)
continue;
$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>";
}
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) ?: []);
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 != '') {
$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);
//Transformation
$processor = new XSLTProcessor();
$processor->importStylesheet($xsltemplate);
$content = $processor->transformToDoc($XML);
$content->formatOutput = true;
$content = $content->saveHTML();
$content = str_replace('dms.php', APP_ROOT . 'cms/dms.php', $content);
return success($content);
}
}
+2 -2
View File
@@ -565,6 +565,7 @@ class FilterCmptLib
getAuthPersonId()
);
// If filters were loaded
if (hasData($filters))
{
@@ -1172,5 +1173,4 @@ class FilterCmptLib
return $filterName;
}
}
}
+27
View File
@@ -95,6 +95,33 @@ class PermissionLib
return $isBerechtigt;
}
/**
* Prueft ob die Berechtigung zumindest fuer eine der angegebenen OE vorhanden ist.
* @param $berechtigung_kurzbz
* @param $oe_kurzbz
* @param $art
* @param $kostenstelle_id
* @return boolean
*/
public function isBerechtigtMultipleOe($berechtigung_kurzbz, $oe_kurzbz, $art=null, $kostenstelle_id=null)
{
$results = array();
foreach($oe_kurzbz as $value)
{
$results[] = $this->isBerechtigt($berechtigung_kurzbz, $value, $art, $kostenstelle_id);
}
if(!in_array(true, $results))
{
return false;
}
else
{
return true;
}
}
/**
* Checks if the caller is allowed to access to this content with the given permissions
* - if it's called from command line than it's trusted
+13 -1
View File
@@ -200,6 +200,17 @@ class PhrasesLib
return '<< PHRASE '.$phrase.' >>';
}
/**
* Workaround to reload the phrases array on an already constructed library.
* @parameters -> look for _setPhrases docs
*/
public function setPhrases($categories, $language)
{
if (count($categories) > 0) $this->_setPhrases($categories, $language);
return $this->_phrases;
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
@@ -319,6 +330,7 @@ class PhrasesLib
{
$this->_phrases = $phrases->retval;
}
}
/**
@@ -329,4 +341,4 @@ class PhrasesLib
{
return json_encode($this->_phrases);
}
}
}
+141 -8
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', 'prestudent', 'document', 'cms'];
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=';
@@ -178,6 +178,7 @@ class SearchBarLib
protected function buildSearchClause(DB_Model $dbModel, array $columns, $searchstr)
{
$searchstr = preg_replace('/[[:punct:]]/', ' ', $searchstr);
$document = implode(' || \' \' || ', $columns);
$query = '\'' . implode(':* & ', explode(' ', trim($searchstr))) . ':*\'';
$reversequery = '\'*:' . implode(' & *:', explode(' ', trim($searchstr))) . '\'';
@@ -297,13 +298,15 @@ EOSC;
AND (datum_bis IS NULL OR datum_bis >= NOW())
AND b.aktiv = TRUE
) bfLeader ON(bfLeader.oe_kurzbz = o.oe_kurzbz)
WHERE ' .
WHERE
o.aktiv = true
AND (' .
$this->buildSearchClause(
$dbModel,
array('o.oe_kurzbz', 'o.bezeichnung', 'ot.bezeichnung'),
$searchstr
) .
'
')
GROUP BY type, o.oe_kurzbz, o.bezeichnung, ot.bezeichnung, oParent.oe_kurzbz, oParent.bezeichnung, otParent.bezeichnung
');
@@ -359,17 +362,26 @@ EOSC;
private function _student($searchstr, $type)
{
$dbModel = new DB_Model();
$gesperrtes_foto = base64_encode(file_get_contents(DOC_ROOT.'skin/images/profilbild_dummy.jpg'));
$students = $dbModel->execReadOnlyQuery('
SELECT
\''.$type.'\' AS type,
s.student_uid AS uid,
CONCAT(s.student_uid,\'@'.DOMAIN.'\') AS email,
s.matrikelnr,
CONCAT(UPPER(stg.typ),UPPER(stg.kurzbz),\'-\',s.semester,s.verband) as verband,
stg.bezeichnung AS studiengang,
p.person_id AS person_id,
p.vorname || \' \' || p.nachname AS name,
k.kontakt as email ,
p.foto
CASE
when s.student_uid = \''.getAuthUID().'\' then p.foto
when p.foto IS NULL then \''.$gesperrtes_foto.'\'
when p.foto_sperre = false then p.foto
else \''.$gesperrtes_foto.'\'
end as foto,
b.aktiv
FROM public.tbl_student s
JOIN public.tbl_studiengang stg USING(studiengang_kz)
JOIN public.tbl_benutzer b ON(b.uid = s.student_uid)
JOIN public.tbl_person p USING(person_id)
LEFT JOIN (
@@ -377,10 +389,57 @@ EOSC;
FROM public.tbl_kontakt
WHERE kontakttyp = \'email\'
) as k USING(person_id)
WHERE b.uid ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\'
WHERE
b.aktiv = TRUE
AND (b.uid ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\'
OR p.vorname ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\'
OR p.nachname ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\')
GROUP BY type, s.student_uid, s.matrikelnr, p.person_id, name,
email, p.foto, s.verband, s.semester, stg.bezeichnung,
stg.typ, stg.kurzbz, b.aktiv
ORDER BY b.aktiv DESC, p.nachname ASC, p.vorname ASC
');
// If something has been found then return it
if (hasData($students)) return getData($students);
// Otherwise return an empty array
return array();
}
private function _studentStv($searchstr, $type)
{
$dbModel = new DB_Model();
$students = $dbModel->execReadOnlyQuery('
SELECT
\''.$type.'\' AS type,
s.student_uid AS uid,
s.matrikelnr,
CONCAT(UPPER(stg.typ),UPPER(stg.kurzbz),\'-\',s.semester,s.verband) as verband,
stg.bezeichnung AS studiengang,
p.person_id AS person_id,
p.vorname || \' \' || p.nachname AS name,
k.kontakt AS email,
p.foto,
b.aktiv
FROM public.tbl_student s
JOIN public.tbl_studiengang stg USING(studiengang_kz)
JOIN public.tbl_benutzer b ON(b.uid = s.student_uid)
JOIN public.tbl_person p USING(person_id)
LEFT JOIN (
SELECT kontakt, person_id
FROM public.tbl_kontakt
WHERE kontakttyp = \'email\'
) as k USING(person_id)
WHERE
b.uid ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\'
OR p.vorname ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\'
OR p.nachname ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\'
GROUP BY type, s.student_uid, s.matrikelnr, p.person_id, name, email, p.foto
GROUP BY type, s.student_uid, s.matrikelnr, p.person_id, name,
k.kontakt, p.foto, s.verband, s.semester, stg.bezeichnung,
stg.typ, stg.kurzbz, b.aktiv
ORDER BY b.aktiv DESC, p.nachname ASC, p.vorname ASC
');
// If something has been found then return it
@@ -454,6 +513,80 @@ EOSC;
*/
private function _raum($searchstr, $type)
{
$dbModel = new DB_Model();
$rooms = $dbModel->execReadOnlyQuery('
SELECT
\''.$type.'\' AS type,
COALESCE(ort.ort_kurzbz, \'N/A\') as ort_kurzbz,
COALESCE(ort.gebteil, \'N/A\') as building,
COALESCE(ort.ausstattung, \'N/A\') as austattung,
COALESCE(CAST(ort.stockwerk AS VARCHAR), \'N/A\') as floor,
COALESCE(CAST(ort.dislozierung AS VARCHAR), \'N/A\') as room_number,
COALESCE(CAST(ort.content_id AS VARCHAR), \'N/A\') as content_id,
CASE
WHEN standort.plz IS NULL OR standort.ort IS NULL THEN
CASE
WHEN standort.strasse IS NULL THEN
CASE
WHEN ort.stockwerk IS NULL THEN \'N/A\'
ELSE CONCAT(ort.stockwerk,\' Stockwerk\')
END
ELSE
CASE
WHEN ort.stockwerk IS NULL THEN standort.strasse
ELSE CONCAT(standort.strasse,\' / \',ort.stockwerk,\' Stockwerk\')
END
END
ELSE
CASE
WHEN standort.strasse IS NULL THEN
CASE
WHEN ort.stockwerk IS NULL THEN CONCAT(standort.plz,\' \',standort.ort)
ELSE CONCAT(standort.plz,\' \',standort.ort,\' / \',ort.stockwerk,\' Stockwerk\')
END
ELSE
CASE
WHEN ort.stockwerk IS NULL THEN CONCAT(standort.plz,\' \',standort.ort,\' / \',standort.strasse)
ELSE CONCAT(standort.plz,\' \',standort.ort,\', \',standort.strasse,\' / \',ort.stockwerk,\' Stockwerk\')
END
END
END as standort,
CASE
WHEN ort.max_person IS NULL OR ort.arbeitsplaetze IS NULL THEN \'N/A\'
ELSE CONCAT(ort.max_person,\', davon \',ort.arbeitsplaetze,\' PC-Plätze\')
END as sitzplaetze
FROM public.tbl_ort as ort
LEFT JOIN (
select ort,standort_id,strasse, plz
FROM public.tbl_standort
LEFT JOIN public.tbl_adresse USING(adresse_id)
) standort USING(standort_id)
WHERE
ort.aktiv = true
AND
ort.lehre = true
AND (' .
$this->buildSearchClause(
$dbModel,
array('ort.ort_kurzbz', 'ort.bezeichnung'),
$searchstr
) .
')'
);
// If something has been found
if (hasData($rooms))
{
// Returns the dataset
return getData($rooms);
}
// Otherwise return an empty array
return array();
}
}
+2
View File
@@ -26,6 +26,8 @@ class TableWidgetLib
{
const TABLE_UNIQUE_ID = 'tableUniqueId'; // TableWidget unique id
const TABLE_BOOTSTRAP_VERSION = 'bootstrapVersion'; // TableWidget bootstrap version
// TableWidget session name
const SESSION_NAME = 'FHC_TABLE_WIDGET';
@@ -0,0 +1,232 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
use \stdClass as stdClass;
/**
* Description of DashboardLib
*
* @author bambi
*/
class DashboardLib
{
const WIDGET_ID_RANDOM_BYTES = 16;
const DEFAULT_DASHBOARD_KURZBZ = 'fhcomplete';
const SECTION_IF_FUNKTION_KURZBZ_IS_NULL = 'general';
const USEROVERRIDE_SECTION = 'custom';
private $_ci; // CI instance
public function __construct()
{
// Loads CI instance
$this->_ci =& get_instance();
$this->_ci->load->model('dashboard/Dashboard_model', 'DashboardModel');
$this->_ci->load->model('dashboard/Dashboard_Preset_model', 'DashboardPresetModel');
$this->_ci->load->model('dashboard/Dashboard_Override_model', 'DashboardOverrideModel');
}
public function generateWidgetId($dashboard_kurzbz = '')
{
$dashboard_kurzbz = (!empty($dashboard_kurzbz)) ? $dashboard_kurzbz : self::DEFAULT_DASHBOARD_KURZBZ;
$widgetid_input = time() . '_' . $dashboard_kurzbz . '_' . bin2hex(random_bytes(self::WIDGET_ID_RANDOM_BYTES));
$widgetid = md5($widgetid_input);
return $widgetid;
}
public function getDashboardByKurzbz($dashboard_kurzbz)
{
$result = $this->_ci->DashboardModel->getDashboardByKurzbz($dashboard_kurzbz);
if (hasData($result))
{
return current(getData($result));
}
return null;
}
public function getMergedConfig($dashboard_id, $uid)
{
$defaultconfig = $this->getDefaultConfig($dashboard_id, $uid);
$userconfig = $this->getUserConfig($dashboard_id, $uid);
$mergedconfig = array_replace_recursive($defaultconfig, $userconfig);
return $mergedconfig;
}
public function getDefaultConfig($dashboard_id, $uid)
{
$res_presets = $this->_ci->DashboardPresetModel->getPresets($dashboard_id, $uid);
$defaultconfig = array();
if (hasData($res_presets))
{
$presets = getData($res_presets);
foreach ($presets as $presetobj)
{
$preset = json_decode($presetobj->preset, true);
if (null !== $preset)
{
$defaultconfig = array_replace_recursive($defaultconfig, $preset);
}
}
}
return $defaultconfig;
}
public function getUserConfig($dashboard_id, $uid)
{
$res_userconfig = $this->_ci->DashboardOverrideModel->getOverride($dashboard_id, $uid);
if (hasData($res_userconfig))
{
$data = getData($res_userconfig);
$decodedconfig = json_decode(current($data)->override, true);
if (null !== $decodedconfig)
{
return $decodedconfig;
}
}
return [];
}
public function getOverrideOrCreateEmptyOverride($dashboard_kurzbz, $uid)
{
$override = $this->getOverride($dashboard_kurzbz, $uid);
if (null !== $override) {
return $override;
}
$dashboard = $this->getDashboardByKurzbz($dashboard_kurzbz);
$emptyoverride = new stdClass();
$emptyoverride->dashboard_id = $dashboard->dashboard_id;
$emptyoverride->uid = $uid;
$emptyoverride->override = '{"widgets": {"' . self::USEROVERRIDE_SECTION . '": {}}}';
return $emptyoverride;
}
public function getPresetOrCreateEmptyPreset($dashboard_kurzbz, $funktion_kurzbz)
{
if ($funktion_kurzbz === self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL)
$funktion_kurzbz = null;
$preset = $this->getPreset($dashboard_kurzbz, $funktion_kurzbz);
if (null !== $preset) {
return $preset;
}
$dashboard = $this->getDashboardByKurzbz($dashboard_kurzbz);
$emptypreset = new stdClass();
$emptypreset->dashboard_id = $dashboard->dashboard_id;
$emptypreset->funktion_kurzbz = $funktion_kurzbz;
$section = ($funktion_kurzbz !== null) ? $funktion_kurzbz : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL;
$emptypreset->preset = '{"widgets": {"' . $section . '": {}}}';
return $emptypreset;
}
public function getPreset($dashboard_kurzbz, $section)
{
$dashboard = $this->getDashboardByKurzbz($dashboard_kurzbz);
$funktion_kurzbz = ($section === self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL) ? null : $section;
$result = $this->_ci->DashboardPresetModel
->getPresetByDashboardAndFunktion($dashboard->dashboard_id, $funktion_kurzbz);
if (hasData($result))
{
return current(getData($result));
}
return null;
}
public function getOverride($dashboard_kurzbz, $uid)
{
$dashboard = $this->getDashboardByKurzbz($dashboard_kurzbz);
$result = $this->_ci->DashboardOverrideModel
->getOverride($dashboard->dashboard_id, $uid);
if (hasData($result))
{
return current(getData($result));
}
return null;
}
public function insertOrUpdatePreset($preset)
{
if (isset($preset->preset_id) && $preset->preset_id > 0)
{
$result = $this->_ci->DashboardPresetModel->update($preset->preset_id, $preset);
}
else
{
$result = $this->_ci->DashboardPresetModel->insert($preset);
}
return $result;
}
public function insertOrUpdateOverride($override)
{
if (isset($override->override_id) && $override->override_id > 0)
{
$result = $this->_ci->DashboardOverrideModel->update($override->override_id, $override);
}
else
{
$result = $this->_ci->DashboardOverrideModel->insert($override);
}
return $result;
}
public function addWidgetsToWidgets(&$widgets, $dashboard_kurzbz, $section, $addwigets)
{
foreach ($addwigets as $widget)
{
if(!isset($widget->widgetid))
{
$widget->widgetid = $this->generateWidgetId($dashboard_kurzbz);
}
$this->addWidgetToWidgets($widgets, $section, $widget, $widget->widgetid);
}
}
public function addWidgetToWidgets(&$widgets, $section, $widget, $widgetid)
{
$section = ($section !== null) ? $section : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL;
if (!isset($widgets[$section]) || !is_array($widgets[$section]))
{
$widgets[$section] = array();
}
$widgets[$section][$widgetid] = $widget;
}
public function removeWidgetFromWidgets(&$widgets, $section, $widgetid)
{
$section = ($section !== null) ? $section : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL;
if (isset($widgets[$section]) && isset($widgets[$section][$widgetid]))
{
unset($widgets[$section][$widgetid]);
if(empty($widgets[$section]) && $section !== self::USEROVERRIDE_SECTION) {
unset($widgets[$section]);
}
return true;
}
else {
return false;
}
}
}
@@ -201,6 +201,10 @@ class Gehaltsbestandteil extends AbstractBestandteil implements \JsonSerializabl
public function setGrundbetrag($grundbetrag)
{
if(is_float($grundbetrag))
{
$grundbetrag = number_format($grundbetrag, 2, '.', '');
}
$this->markDirty('grundbetrag', $this->grundbetrag, $grundbetrag);
$this->grundbetrag = $grundbetrag;
return $this;
@@ -208,6 +212,10 @@ class Gehaltsbestandteil extends AbstractBestandteil implements \JsonSerializabl
public function setBetrag_valorisiert($betrag_valorisiert)
{
if(is_float($betrag_valorisiert))
{
$betrag_valorisiert = number_format($betrag_valorisiert, 2, '.', '');
}
$this->markDirty('betrag_valorisiert', $this->betrag_valorisiert, $betrag_valorisiert);
$this->betrag_valorisiert = $betrag_valorisiert;
return $this;
@@ -299,6 +299,91 @@ class Vertrag_model extends DB_Model
}
}
/**
* Prueft ob ein Mitarbeiter einen erteilten Vertrag zu einer Lehrveranstaltung besitzt.
* @param $lehrveranstaltung_id ID der Lehrveranstaltung
* @param $studiensemester_kurzbz Studiensemester das geprueft wird
* @param $mitarbeiter_uid UID des Mitarbeiters
*/
public function isVertragErteiltLV($lehrveranstaltung_id, $studiensemester_kurzbz, $mitarbeiter_uid)
{
if (defined('CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON')
&& CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON != '')
{
// Liegt das Studiensemester vor dem Pruefdatum, wird die LV immer als Erteilt angezeigt
$stsemquery = "
SELECT
tbl_studiensemester.start
FROM
public.tbl_studiensemester
WHERE
studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz)."
AND tbl_studiensemester.start < (
SELECT
start
FROM
public.tbl_studiensemester stsem
WHERE
stsem.studiensemester_kurzbz = " . $this->escape(CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON)."
)";
if ($stsemresult = $this->execReadOnlyQuery($stsemquery))
{
$stsemdata = getData($stsemresult);
if ($stsemdata && count($stsemdata) > 0)
{
// Wenn das Studiensemester vor dem Pruefdatum liegt, gilt der Vertrag immer als erteilt.
return true;
}
}
else
{
return false;
}
}
$query = "
SELECT
1
FROM
lehre.tbl_lehreinheitmitarbeiter
JOIN lehre.tbl_lehreinheit USING(lehreinheit_id)
JOIN lehre.tbl_vertrag USING(vertrag_id)
JOIN lehre.tbl_vertrag_vertragsstatus USING(vertrag_id)
WHERE
tbl_lehreinheitmitarbeiter.mitarbeiter_uid = " . $this->escape($mitarbeiter_uid) . "
AND tbl_lehreinheit.studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . "
AND tbl_lehreinheit.lehrveranstaltung_id = " . $this->escape(intval($lehrveranstaltung_id)) . "
AND tbl_vertrag_vertragsstatus.vertragsstatus_kurzbz='erteilt'
AND NOT EXISTS(
SELECT
1
FROM
lehre.tbl_vertrag_vertragsstatus vstatus
WHERE
vstatus.vertrag_id = tbl_vertrag.vertrag_id
AND vstatus.vertragsstatus_kurzbz = 'storno'
)
";
if ($result = $this->execReadOnlyQuery($query))
{
$data = getData($result);
if ($data && count($data) > 0)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
+26 -1
View File
@@ -20,6 +20,31 @@ class Gemeinde_model extends DB_Model
return $this->loadWhere(array("plz" => $plz));
}
public function getGemeindeByNation($nation, $zip)
{
$this->addSelect(["name"]);
if ($nation == "A")
{
if (isset($zip) && $zip > 999 && $zip < 32000)
{
$gemeinde_res = $this->GemeindeModel->loadWhere(['plz' => $zip]);
if (isError($gemeinde_res))
{
show_error("error while trying to query bis.tbl_gemeinde");
}
$gemeinde_res = hasData($gemeinde_res) ? getData($gemeinde_res) : null;
$gemeinde_res = array_map(function ($obj) {
return $obj->name;
}, $gemeinde_res);
echo json_encode($gemeinde_res);
} else {
echo json_encode(error("ortschaftskennziffer code was not valid"));
}
}
}
public function checkLocation($plz, $gemeinde, $ort)
{
$this->db->where('ortschaftsname', $ort);
@@ -28,4 +53,4 @@ class Gemeinde_model extends DB_Model
return (boolean)$this->db->count_all_results($this->dbTable);
}
}
}
@@ -0,0 +1,14 @@
<?php
class Ampel_Benutzer_Bestaetigt_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'public.tbl_ampel_benutzer_bestaetigt';
$this->pk = 'ampel_benutzer_bestaetigt_id';
}
}
+175 -20
View File
@@ -16,37 +16,95 @@ class Ampel_model extends DB_Model
* 1. not after the deadline date
* 2. not before the vorlaufszeit
* @param bool $email If true, then only ampeln are retrieved that are marked to be sent by mail.
* @return array Returns array of objects.
* @return stdClass Returns array of objects.
*/
public function active($email = false)
public function active($email = false, $uid = null)
{
$parametersArray = null;
$query = '
SELECT *
FROM public.tbl_ampel
WHERE';
if ($email === true)
{
$parametersArray['email'] = $email;
$query .= ' email = ? AND';
$userLanguage = getUserLanguage();
$selectStatement='*,beschreibung[('.$this->getLanguageIndex($this->escape($userLanguage)).')] as beschreibung_trans, buttontext[('.$this->getLanguageIndex($this->escape($userLanguage)).')] as buttontext_trans';
if($uid != null ){
$selectStatement .= ',
COALESCE((
SELECT true
FROM public.tbl_ampel_benutzer_bestaetigt a
WHERE a.ampel_id = ' . $this->dbTable . '.ampel_id
AND uid = ' . $this->escape($uid) . ' LIMIT 1), false) as bestaetigt';
}
$query .= '(
(NOW()<(deadline+(COALESCE(verfallszeit,0) || \' days\')::interval)::date)
OR (verfallszeit IS NULL)
AND (NOW()>(deadline-(COALESCE(vorlaufzeit,0) || \' days\')::interval)::date)
OR (vorlaufzeit IS NULL AND NOW() < deadline))';
$this->addSelect($selectStatement);
$whereStatement='';
$query .= ' ORDER BY deadline DESC';
if ($email === true) {
$whereStatement .= ' email = '.$this->escape($email).' AND';
}
$whereStatement .=
'(
(
(NOW()<(deadline+(COALESCE(verfallszeit,0) || \' days\')::interval)::date)
OR (verfallszeit IS NULL)
)
AND
(
(NOW()>(deadline-(COALESCE(vorlaufzeit,0) || \' days\')::interval)::date)
OR (vorlaufzeit IS NULL AND NOW() < deadline)
)
)';
$this->addOrder('deadline', 'DESC');
return $this->loadWhere($whereStatement);
}
public function openActive($uid, $email = false)
{
$userLanguage = getUserLanguage();
$selectStatement = '*,beschreibung[(' . $this->getLanguageIndex($this->escape($userLanguage)) . ')] as beschreibung_trans, buttontext[(' . $this->getLanguageIndex($this->escape($userLanguage)) . ')] as buttontext_trans';
$selectStatement .= ',
COALESCE((
SELECT true
FROM public.tbl_ampel_benutzer_bestaetigt a
WHERE a.ampel_id = ' . $this->dbTable . '.ampel_id
AND uid = ' . $this->escape($uid) . ' LIMIT 1), false) as bestaetigt';
$this->addSelect($selectStatement);
$whereStatement = '';
if ($email === true) {
$whereStatement .= ' email = ' . $this->escape($email) . ' AND';
}
$whereStatement .=
'
(COALESCE((
SELECT true
FROM public.tbl_ampel_benutzer_bestaetigt a
WHERE a.ampel_id = ' . $this->dbTable . '.ampel_id
AND uid = ' . $this->escape($uid) . ' LIMIT 1), false) = FALSE) AND
(
(
(NOW()<(deadline+(COALESCE(verfallszeit,0) || \' days\')::interval)::date)
OR (verfallszeit IS NULL)
)
AND
(
(NOW()>(deadline-(COALESCE(vorlaufzeit,0) || \' days\')::interval)::date)
OR (vorlaufzeit IS NULL AND NOW() < deadline)
)
)';
$this->addOrder('deadline', 'DESC');
return $this->loadWhere($whereStatement);
return $this->execQuery($query, $parametersArray);
}
/**
* Returns all Ampel-receiver of a specific Ampel.
* @param string $benutzer_select SQL Statement which defines the Ampel-receiver.
* @return array Returns array of objects with property 'uid'.
* @return stdClass Returns array of objects with property 'uid'.
*/
public function execBenutzerSelect($benutzer_select)
{
@@ -90,4 +148,101 @@ class Ampel_model extends DB_Model
else
return $result; //will contain the error-msg from execQuery
}
/**
* checks if a user is assigned to an ampel
* @param string $uid userID
* @param string $benutzer_select the select query which gets all the user that are assigned to an ampel
* @return stdClass
*/
public function isZugeteilt($uid, $benutzer_select){
$zugeteilt = $this->execReadOnlyQuery("
SELECT
CASE WHEN ? IN (".$benutzer_select.")
THEN true
ELSE false
END as zugeteilt
", [$uid]);
if(isError($zugeteilt)){
return $zugeteilt;
}
$zugeteilt = getData($zugeteilt);
return success(current($zugeteilt)->zugeteilt);
}
// THIS FUNCTION IS NOT IN USE
// fetches all ampeln that were assigned to the user after the working start_date
function alleAmpeln($uid){
$userLanguage = getUserLanguage();
$zugeteile_ampeln = [];
$datum = new datum();
$now = $datum->mktime_fromdate(date('Y-m-d'));
// start date of user
$benutzerStartDate = $this->execReadOnlyQuery("
SELECT insertamum FROM public.tbl_benutzer WHERE uid = ?", [$uid]);
$benutzerStartDate = $datum->mktime_fromdate(date(current(getData($benutzerStartDate))->insertamum));
$allAmpeln = $this->execReadOnlyQuery("
SELECT *, beschreibung[(".$this->getLanguageIndex($this->escape($userLanguage)).")] as beschreibung_trans, buttontext[(".$this->getLanguageIndex($this->escape($userLanguage)).")] as buttontext_trans FROM
public.tbl_ampel");
if(isError($allAmpeln)) return error(getError($allAmpeln));
$allAmpeln = getData($allAmpeln);
foreach($allAmpeln as $ampel){
// check if the ampel is assigned to the user
$zugeteilt = $this->execReadOnlyQuery("
SELECT
CASE WHEN ? IN (".$ampel->benutzer_select.")
THEN true
ELSE false
END as zugeteilt
", [$uid]);
if(isError($zugeteilt)) return error(getError($zugeteilt));
$zugeteilt = current(getData($zugeteilt))->zugeteilt;
// abgelaufen check
// $now > strtotime('+' . $ampel->verfallszeit . ' day', $ampel->deadline)
if(
// aktuelles datum liegt vor der Vorlaufzeit der Ampel
(isset($ampel->vorlaufzeit) && $now < strtotime('-' . $ampel->vorlaufzeit . ' day', $datum->mktime_fromdate($ampel->deadline)))
||
// ampel ist vor Arbeitsstart abgelaufen
(isset($ampel->verfallszeit) && $benutzerStartDate > strtotime('+' . $ampel->verfallszeit . ' day', $datum->mktime_fromdate($ampel->deadline)))
||
// ampel ist vor Arbeitsstart abgelaufen (verfallszeit nicht vorhanden)
($benutzerStartDate > strtotime('+' . $ampel->verfallszeit . ' day', $datum->mktime_fromdate($ampel->deadline)))
){
// continue iteration if ampel is expired before work start or shouldn't be visible yet
continue;
}
$ampel->zugeteilt = $zugeteilt;
if($zugeteilt) $zugeteile_ampeln[] = $ampel;
}
return success($zugeteile_ampeln);
}
private function getLanguageIndex($userLanguage)
{
return "
SELECT index
FROM public.tbl_sprache
WHERE sprache = " . $userLanguage;
}
}
@@ -11,4 +11,316 @@ class Content_model extends DB_Model
$this->dbTable = 'campus.tbl_content';
$this->pk = 'content_id';
}
/**
* Laedt den Content in der angegebenen Sprache
* Sollte der Content in dieser Sprache nicht vorhanden sein, wird der Content in der Default Sprache geladen
*
* @param integer $content_id
* @param string $sprache optional
* @param integer $version optional
* @param boolean | null $sichtbar optional
*
* @return stdClass
*/
public function getContent($content_id, $sprache = DEFAULT_LANGUAGE, $version = null, $sichtbar = null, $load_default_language = false)
{
$this->load->model('content/Contentsprache_model', 'ContentspracheModel');
$spracheExists = $this->ContentspracheModel->exists($content_id, $sprache, $version, $sichtbar);
if (isError($spracheExists))
return $spracheExists;
if(!getData($spracheExists))
{
if($load_default_language)
$sprache = DEFAULT_LANGUAGE;
else
return error('Der Content existiert in dieser Sprache nicht ');
}
$condition = ['content_id' => $content_id, 'sprache' => $sprache];
if ($sichtbar === true || $sichtbar === false)
$condition['sichtbar'] = $sichtbar;
if ($version)
$condition['version'] = $version;
$this->addSelect([
'*',
'tbl_contentsprache.insertamum',
'tbl_contentsprache.insertvon',
'tbl_contentsprache.updateamum',
'tbl_contentsprache.updatevon'
]);
$this->addJoin('campus.tbl_contentsprache', 'content_id');
$this->addOrder('version', 'DESC');
$this->addLimit(1);
$result = $this->loadWhere($condition);
if (isError($result))
return $result;
if (!getData($result))
return error('Dieser Eintrag wurde nicht gefunden');
return success(current(getData($result)));
}
/**
* Sucht die content_id fuer den CIS4_Root Menu content
*
* @return integer|null content_id of the Cis4_Root Menu
*/
public function getMenuContentID(){
// early return if the CIS4_MENU_ENTRY constant is defined
if(defined('CIS4_MENU_ENTRY'))
{
return CIS4_MENU_ENTRY;
}
// load the CIS4 Menu content_id from the database using the column 'beschreibugn' of the campus.tbl_content table
$CIS4_ROOT_CONTENT = $this->loadWhere(["beschreibung"=>"CIS4_ROOT"]);
if(isError($CIS4_ROOT_CONTENT))
{
return null;
}
$CIS4_ROOT_CONTENT = getData($CIS4_ROOT_CONTENT);
if(count($CIS4_ROOT_CONTENT) > 0)
{
return current($CIS4_ROOT_CONTENT)->content_id ?? null;
}
else
{
return null;
}
}
/**
* Laedt alle Content Eintraege unterhalb eines Contents
* (Ohne Newseintraege)
*
* @param integer $root_content_id
* @param string $uid
* @param string $sprache optional
*
* @return stdClass on success an array with menu objects
*/
public function getMenu($root_content_id, $uid, $sprache = DEFAULT_LANGUAGE)
{
/*,
{
"content_id": 1000007,
"template_kurzbz": "redirect",
"titel": "Anrechnung",
"content": "<content><url><![CDATA[' . site_url('/lehre/anrechnung/RequestAnrechnung') . ']]></url><target><![CDATA[]]></target></content>",
"menu_open": false,
"aktiv": true,
"childs": []
}
*/
/*
{
"content_id": 1000003,
"template_kurzbz": "redirect",
"titel": "COVID-19",
"content": "<content><url><![CDATA[' . site_url('/CisVue/Cms/content/10012') . ']]></url><target><![CDATA[]]></target></content>",
"menu_open": false,
"aktiv": true,
"childs": []
},
*/
if ($root_content_id === null) {
$res = json_decode('{
"content_id": 1000000,
"template_kurzbz": "contentmittitel",
"titel": "CIS4",
"content": "<content></content>",
"menu_open": true,
"aktiv": true,
"childs": [
{
"content_id": 1000001,
"template_kurzbz": "redirect",
"titel": "News",
"content": "<content><url><![CDATA[' . site_url('/CisVue/Cms/news') . ']]></url><target><![CDATA[]]></target></content>",
"menu_open": false,
"aktiv": true,
"childs": []
},
{
"content_id": 1000002,
"template_kurzbz": "redirect",
"titel": "Profil",
"content": "<content><url><![CDATA[' . site_url('/Cis/Profil') . ']]></url><target><![CDATA[]]></target></content>",
"menu_open": false,
"aktiv": true,
"childs": []
},
{
"content_id": 1000004,
"template_kurzbz": "redirect",
"titel": "Meine LV",
"content": "<content><url><![CDATA[' . site_url('/Cis/MyLv') . ']]></url><target><![CDATA[]]></target></content>",
"menu_open": false,
"aktiv": true,
"childs": []
},
{
"content_id": 1000005,
"template_kurzbz": "redirect",
"titel": "Stundenplan",
"content": "<content><url><![CDATA[' . site_url('/Cis/Stundenplan') . ']]></url><target><![CDATA[]]></target></content>",
"menu_open": false,
"aktiv": true,
"childs": []
},
{
"content_id": 1000006,
"template_kurzbz": "redirect",
"titel": "Dokumente",
"content": "<content><url><![CDATA[' . site_url('/Cis/Documents') . ']]></url><target><![CDATA[]]></target></content>",
"menu_open": false,
"aktiv": true,
"childs": []
},
{
"content_id": 1000007,
"template_kurzbz": "redirect",
"titel": "Studierendenstatus",
"content": "<content><url><![CDATA[' . site_url('/lehre/Studierendenantrag') . ']]></url><target><![CDATA[]]></target></content>",
"menu_open": false,
"aktiv": true,
"childs": []
}
]
}');
return success($res);
}
$sql = "
SELECT
c.content_id,
c.template_kurzbz,
s.titel,
s.content,
c.menu_open,
c.aktiv,
k.child_content_id,
k.sort FROM (
SELECT
c.content_id,
s.contentsprache_id
FROM
campus.tbl_content c
JOIN (
SELECT
s5.content_id,
s5.contentsprache_id
FROM (
SELECT
content_id,
sprache,
MAX(version) AS version
FROM (
SELECT
c1.content_id,
COALESCE(s1.sprache, ?) AS sprache
FROM
campus.tbl_content c1
LEFT JOIN
campus.tbl_contentsprache s1 ON c1.content_id=s1.content_id AND s1.sprache=?
WHERE
sichtbar=true
) s2
LEFT JOIN
campus.tbl_contentsprache s3 USING(content_id, sprache)
WHERE
sichtbar=true
GROUP BY
content_id,
sprache
) s4
LEFT JOIN
campus.tbl_contentsprache s5 USING(content_id, sprache, version)
WHERE
version IS NOT NULL
) t USING (content_id)
JOIN
campus.tbl_contentsprache s USING (contentsprache_id)
WHERE
c.template_kurzbz<>'news'
AND
c.content_id IN (
WITH RECURSIVE childs(content_id, child_content_id) as
(
SELECT content_id, child_content_id FROM campus.tbl_contentchild
WHERE content_id=?
UNION ALL
SELECT cc.child_content_id, null FROM campus.tbl_contentchild cc, childs
WHERE cc.content_id=childs.content_id
)
SELECT content_id
FROM childs
GROUP BY content_id
)
GROUP BY c.content_id,
s.contentsprache_id
) m
JOIN
campus.tbl_content c USING(content_id)
JOIN
campus.tbl_contentsprache s USING(contentsprache_id)
LEFT JOIN
campus.tbl_contentchild k ON(m.content_id=k.content_id)
WHERE EXISTS (
SELECT 1
FROM campus.tbl_contentgruppe
JOIN public.vw_gruppen USING(gruppe_kurzbz)
WHERE (
tbl_contentgruppe.content_id=c.content_id
OR NOT EXISTS (
SELECT 1
FROM campus.tbl_contentgruppe
WHERE content_id=c.content_id
)
)
AND vw_gruppen.uid=?
)
ORDER BY content_id, sort";
$result = $this->execQuery($sql, [DEFAULT_LANGUAGE, $sprache, $root_content_id, $uid]);
if (isError($result))
return $result;
$contents = getData($result) ?? [];
$result = [];
foreach ($contents as $content) {
if (!isset($result[$content->content_id])) {
$result[$content->content_id] = clone($content);
unset($result[$content->content_id]->child_content_id);
unset($result[$content->content_id]->sort);
$result[$content->content_id]->childs = [];
}
if ($content->child_content_id !== null)
$result[$content->content_id]->childs[] = $content->child_content_id;
}
foreach ($result as $content) {
foreach ($content->childs as $k => $v) {
if (isset($result[$v])) {
$content->childs[$k] = $result[$v];
} else {
unset($content->childs[$k]);
}
}
}
return success(isset($result[$root_content_id]) ? $result[$root_content_id] : null);
}
}
@@ -11,4 +11,50 @@ class Contentgruppe_model extends DB_Model
$this->dbTable = 'campus.tbl_contentgruppe';
$this->pk = array('gruppe_kurzbz', 'content_id');
}
/**
* Prueft ob der Zugriff auf den Content eingeschraenkt ist auf
* eine bestimmte Benutzergruppe
*
* @param int $content_id
*
* @return stdClass success(true) wenn eingeschraenkt sonst success(false)
*/
public function islocked($content_id)
{
$islocked = $this->loadWhere(['content_id' => $content_id]);
if (isError($islocked))
return $islocked;
return success(!!getData($islocked));
}
/**
* Prueft ob ein User die Berechtigung fuer das Anzeigen des
* Contents besitzt
*
* @param int $content_id ID des Contents
* @param string $uid User der versucht auf den Content zuzugreifen
*
* @return stdClass
*/
public function berechtigt($content_id, $uid)
{
$islocked = $this->islocked($content_id);
if (isError($islocked))
return $islocked;
$condition = ['uid' => $uid];
if (getData($islocked)) {
$condition['content_id'] = $content_id;
}
$this->addJoin('public.vw_gruppen', 'gruppe_kurzbz');
$result = $this->loadWhere($condition);
if (isError($result))
return $result;
return success(!!getData($result));
}
}
@@ -11,4 +11,32 @@ class Contentsprache_model extends DB_Model
$this->dbTable = 'campus.tbl_contentsprache';
$this->pk = 'contentsprache_id';
}
/**
* Prueft ob der Content in der angegeben Sprache vorhanden ist
*
* @param int $content_id
* @param string $sprache
* @param int | null $version (optional)
* @param boolean | null $sichtbar (optional)
* @return stdClass
*/
public function exists($content_id, $sprache, $version=null, $sichtbar=null)
{
$condition = ['content_id' => $content_id, 'sprache' => $sprache];
if ($version)
$condition['version'] = $version;
if ($sichtbar !== null)
$condition['sichtbar'] = $sichtbar;
$result = $this->loadWhere($condition);
if (isError($result))
return $result;
return success(!!getData($result));
}
}
+120
View File
@@ -11,4 +11,124 @@ class News_model extends DB_Model
$this->dbTable = 'campus.tbl_news';
$this->pk = 'news_id';
}
/**
* Get all News ordered by date. (most actual on top)
* @param null $limit Amount of news.
* @return array
*/
public function getAll($limit = null)
{
$this->addJoin("campus.tbl_content","content_id");
return $this->execReadOnlyQuery('
SELECT *
FROM campus.tbl_news
JOIN campus.tbl_content content ON content.content_id = campus.tbl_news.content_id
WHERE
--text IS NOT NULL AND
datum <= NOW() AND (datum_bis IS NULL OR datum_bis >= now()::date)
ORDER BY datum DESC
LIMIT ' . $this->escape($limit)
);
}
public function getNewsContentIDs($limit=10){
$this->addSelect(['content_id']);
return $this->loadWhere("datum <= NOW() AND (datum_bis IS NULL OR datum_bis >= now()::date)
ORDER BY datum DESC
LIMIT " . $this->escape($limit));
}
/**
* @param string $sprache
* @param string $studiengang_kz
* @param integer | null $semester
* @param string $fachbereich_kurzbz
* @param boolean $sichtbar
* @param integer $maxalter
* @param integer $page
* @param integer $page_size
* @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, $maxalter = 0, $page = 1, $page_size = 10, $all = false, $mischen = true)
{
$this->addOrder('datum', 'DESC');
$studiengang_kz = trim($studiengang_kz);
$fachbereich_kurzbz = trim($fachbereich_kurzbz);
$where = [];
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 == '') {
$where[] = "fachbereich_kurzbz IS NULL";
} else {
$where[] = "fachbereich_kurzbz = " . $this->db->escape($fachbereich_kurzbz);
}
}
if ($studiengang_kz == '0') {
$where[] = "studiengang_kz = " . $this->db->escape($studiengang_kz);
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 . ")";
}
$this->addJoin('campus.tbl_contentsprache cs', 'content_id');
$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))";
$where = implode(" AND ", $where);
$this->db->where($where, NULL, FALSE);
}
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, $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, $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();
}
}
+51
View File
@@ -193,4 +193,55 @@ class Akte_model extends DB_Model
return success($dokumente->retval);
}
/**
* Liefert die Archivdokumente einer Person
*
* @param integer $person_id
* @param boolean|null $signiert Wenn true werden nur Dokumente geliefert die digital signiert wurden.
* @param boolean|null $stud_selfservice Wenn true werden nur Dokumente geliefert die Studierende selbst herunterladen duerfen.
*
* @return stdClass
*/
public function getArchiv($person_id, $signiert = null, $stud_selfservice = null)
{
$this->addSelect('akte_id');
$this->addSelect('person_id');
$this->addSelect('dokument_kurzbz');
$this->addSelect('mimetype');
$this->addSelect('erstelltam');
$this->addSelect('gedruckt');
$this->addSelect('titel_intern');
$this->addSelect('anmerkung_intern');
$this->addSelect('titel');
$this->addSelect('bezeichnung');
$this->addSelect('updateamum');
$this->addSelect('insertamum');
$this->addSelect('updatevon');
$this->addSelect('insertvon');
$this->addSelect('uid');
$this->addSelect('dms_id');
$this->addSelect('anmerkung');
$this->addSelect('nachgereicht');
$this->addSelect('CASE WHEN inhalt is not null THEN true ELSE false END as inhalt_vorhanden', false);
$this->addSelect('nachgereicht_am');
$this->addSelect('ausstellungsnation');
$this->addSelect('formal_geprueft_amum');
$this->addSelect('archiv');
$this->addSelect('signiert');
$this->addSelect('stud_selfservice');
$this->addSelect('akzeptiertamum');
if ($signiert !== null)
$this->db->where('signiert', (boolean)$signiert);
if ($stud_selfservice !== null)
$this->db->where('stud_selfservice', (boolean)$stud_selfservice);
$this->addOrder('erstelltam', 'DESC');
return $this->loadWhere([
'person_id' => $person_id,
'archiv' => true
]);
}
}
+28
View File
@@ -340,6 +340,34 @@ class Konto_model extends DB_Model
}
/**
* @param integer $prestudent_id
* @param string $stsem
* @param array $buchungstypen
*
* @return stdClass
*/
public function checkStudienbeitragFromPrestudent($prestudent_id, $stsem, $buchungstypen)
{
$this->addSelect($this->dbTable . '.buchungsnr');
$this->addSelect($this->dbTable . '.buchungsdatum');
$this->addJoin('public.tbl_prestudent s', $this->dbTable . '.person_id=s.person_id AND ' . $this->dbTable . '.studiengang_kz=s.studiengang_kz');
$this->db->where_in('buchungstyp_kurzbz', $buchungstypen);
$this->db->where('0 >= (
SELECT sum(betrag)
FROM ' . $this->dbTable . ' skonto
WHERE skonto.buchungsnr = ' . $this->dbTable . '.buchungsnr_verweis
OR skonto.buchungsnr_verweis = ' . $this->dbTable . '.buchungsnr_verweis
)', null, false);
return $this->loadWhere([
'prestudent_id' => $prestudent_id,
'studiensemester_kurzbz' => $stsem
]);
}
/*
* check if student has paid studienbeitrag for certain semester
*
* @param $person_id person_id
@@ -26,6 +26,77 @@ class Prestudentstatus_model extends DB_Model
$this->hasSequence = false;
}
/**
* loadWhereUid
*
* loads all rows for a student_uid
*
* @param string $uid
* @param array $where Optional. Default empty array
* @param boolean $withPrestudent Optional. Default true
*
* @return stdClass
*/
public function loadWhereUid($uid, $where = null, $withPrestudent = false)
{
$this->addSelect($this->dbTable . '.*');
$this->addJoin('public.tbl_student', 'prestudent_id');
if ($withPrestudent) {
$this->addJoin('public.tbl_prestudent s', 'prestudent_id');
$this->addSelect('s.aufmerksamdurch_kurzbz');
$this->addSelect('s.person_id');
$this->addSelect('s.studiengang_kz');
$this->addSelect('s.berufstaetigkeit_code');
$this->addSelect('s.ausbildungcode');
$this->addSelect('s.zgv_code');
$this->addSelect('s.zgvort');
$this->addSelect('s.zgvdatum');
$this->addSelect('s.zgvmas_code');
$this->addSelect('s.zgvmaort');
$this->addSelect('s.zgvmadatum');
$this->addSelect('s.aufnahmeschluessel');
$this->addSelect('s.facheinschlberuf');
$this->addSelect('s.reihungstest_id');
$this->addSelect('s.anmeldungreihungstest');
$this->addSelect('s.reihungstestangetreten');
$this->addSelect('s.rt_gesamtpunkte');
$this->addSelect('s.bismelden');
$this->addSelect('s.dual');
$this->addSelect('s.rt_punkte1');
$this->addSelect('s.rt_punkte2');
$this->addSelect('s.ausstellungsstaat');
$this->addSelect('s.rt_punkte3');
$this->addSelect('s.zgvdoktor_code');
$this->addSelect('s.zgvdoktorort');
$this->addSelect('s.zgvdoktordatum');
$this->addSelect('s.mentor');
$this->addSelect('s.zgvnation');
$this->addSelect('s.zgvmanation');
$this->addSelect('s.zgvdoktornation');
$this->addSelect('s.gsstudientyp_kurzbz');
$this->addSelect('s.aufnahmegruppe_kurzbz');
$this->addSelect('s.udf_values');
$this->addSelect('s.priorisierung');
$this->addSelect('s.foerderrelevant');
$this->addSelect('s.standort_code');
$this->addSelect('s.zgv_erfuellt');
$this->addSelect('s.zgvmas_erfuellt');
$this->addSelect('s.zgvdoktor_erfuellt');
}
$this->addOrder('datum');
$this->addOrder('insertamum');
if (!$where)
$where = [];
$where['student_uid'] = $uid;
return $this->loadWhere($where);
}
/**
* getLastStatus
*/
+22
View File
@@ -17,6 +17,28 @@ class Student_model extends DB_Model
$this->hasSequence = false;
}
/**
* Checks if the user is a Student.
* @param string $uid
* @return array
*/
public function isStudent($uid)
{
$this->addSelect('1');
$result = $this->loadWhere(array('student_uid' => $uid));
if(hasData($result))
{
return success(true);
}
else
{
return success(false);
}
}
// ****
// * Generiert die Matrikelnummer
// * FORMAT: 0710254001
@@ -0,0 +1,18 @@
<?php
class Bookmark_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'dashboard.tbl_bookmark';
$this->pk = 'bookmark_id';
}
}
@@ -0,0 +1,26 @@
<?php
class Dashboard_Override_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'dashboard.tbl_dashboard_benutzer_override';
$this->pk = 'override_id';
}
/**
* Get Overrides of given uid.
* @param integer dashboard_id
* @param string $uid
* @return array
*/
public function getOverride($dashboard_id, $uid)
{
return $this->loadWhere(array('dashboard_id' => $dashboard_id, 'uid'=> $uid));
}
}
@@ -0,0 +1,67 @@
<?php
class Dashboard_Preset_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'dashboard.tbl_dashboard_preset';
$this->pk = 'preset_id';
}
/**
* Get Presets of given uid.
* @param integer dashboard_id
* @param string $uid
* @return array
*/
public function getPresets($dashboard_id, $uid)
{
// TODO: get Funktionen for uid and load all preset for all funktionen for uid
//return $this->loadWhere(array('dashboard_id' => $dashboard_id, 'funktion_kurzbz'=> null));
$sql = <<<EOSQL
SELECT
*
FROM
dashboard.tbl_dashboard_preset
WHERE
dashboard_id = ?
AND (
funktion_kurzbz IN (
SELECT
DISTINCT funktion_kurzbz
FROM
public.tbl_benutzerfunktion
WHERE
uid = ?
AND
NOW()::date
BETWEEN
COALESCE(datum_von, '1970-01-01')
AND
COALESCE(datum_bis, '2170-12-31')
)
OR
funktion_kurzbz IS NULL
)
ORDER BY
funktion_kurzbz DESC
EOSQL;
return $this->execQuery($sql, array($dashboard_id, $uid));
}
/**
* Get Preset by Dashboard and Funktion
* @param integer dashboard_id
* @param string funktion_kurzbz
* @return array
*/
public function getPresetByDashboardAndFunktion($dashboard_id, $funktion_kurzbz)
{
return $this->loadWhere(array('dashboard_id' => $dashboard_id, 'funktion_kurzbz' => $funktion_kurzbz));
}
}
@@ -0,0 +1,15 @@
<?php
class Dashboard_Widget_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'dashboard.tbl_dashboard_widget';
$this->pk = ['dashboard_id', 'widget_id'];
$this->hasSequence = false;
}
}
@@ -0,0 +1,25 @@
<?php
class Dashboard_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'dashboard.tbl_dashboard';
$this->pk = 'dashboard_id';
}
/**
* Get Dashboard by kurzbz.
* @param string dashboard_kurzbz
* @return array
*/
public function getDashboardByKurzbz($dashboard_kurzbz)
{
return $this->loadWhere(array('dashboard_kurzbz' => $dashboard_kurzbz));
}
}
@@ -0,0 +1,32 @@
<?php
class Widget_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'dashboard.tbl_widget';
$this->pk = 'widget_id';
}
public function getWithAllowedForDashboard($dashboard_id)
{
$this->addSelect($this->dbTable . '.*');
$this->addSelect('CASE WHEN dashboard_id IS NULL THEN 0 ELSE 1 END AS allowed', false);
$this->db->join('dashboard.tbl_dashboard_widget dw', $this->dbTable . '.widget_id=dw.widget_id AND dashboard_id = ?', 'LEFT', false);
return $this->execQuery($this->db->get_compiled_select($this->dbTable), [$dashboard_id]);
}
public function getForDashboard($db)
{
$this->addSelect($this->dbTable . '.*');
$this->addJoin('dashboard.tbl_dashboard_widget', 'widget_id');
$this->addJoin('dashboard.tbl_dashboard', 'dashboard_id');
return $this->loadWhere(['dashboard_kurzbz' => $db]);
}
}
@@ -113,4 +113,135 @@ class Lehreinheit_model extends DB_Model
return $this->execQuery($query, array($lehreinheit_id));
}
/**
* Gets emails of all Studierende in a lehrveranstaltung
* @param int $lehreinheit_id
* @return array
*/
public function getStudentenMail($lehreinheit_id)
{
// logic used from cis_menu_lv.inc.php line 335
return $this->execReadOnlyQuery("
SELECT
gruppe_kurzbz,
CASE
WHEN nomail = TRUE THEN 'nomail'
WHEN gruppe_kurzbz !='' THEN LOWER(gruppe_kurzbz || '@' || ?)
ELSE LOWER(stg_typ || stg_kurzbz || semester || TRIM(verband) || TRIM(gruppe) || '@' || ?)
END AS mail
FROM
(
SELECT
distinct vw_lehreinheit.studiensemester_kurzbz, vw_lehreinheit.stg_kurzbz, vw_lehreinheit.stg_typ, vw_lehreinheit.semester,
COALESCE(vw_lehreinheit.verband,'') as verband, COALESCE(vw_lehreinheit.gruppe,'') as gruppe, vw_lehreinheit.gruppe_kurzbz, tbl_gruppe.mailgrp,
CASE
WHEN mailgrp = TRUE OR mailgrp IS NULL THEN FALSE
ELSE TRUE
END as nomail
FROM campus.vw_lehreinheit
LEFT JOIN public.tbl_gruppe USING(gruppe_kurzbz)
WHERE
vw_lehreinheit.lehrveranstaltung_id=
(select distinct lehrveranstaltung_id from campus.vw_lehreinheit where lehreinheit_id=?)
AND
vw_lehreinheit.studiensemester_kurzbz =
(select distinct studiensemester_kurzbz from campus.vw_lehreinheit where lehreinheit_id=?)
AND (vw_lehreinheit.gruppe_kurzbz IS NULL OR
(vw_lehreinheit.gruppe_kurzbz IS NOT NULL AND (SELECT COUNT(*) FROM public.tbl_benutzergruppe where gruppe_kurzbz = vw_lehreinheit.gruppe_kurzbz AND studiensemester_kurzbz = vw_lehreinheit.studiensemester_kurzbz) > 0))
) AS subquery
",[DOMAIN,DOMAIN,$lehreinheit_id,$lehreinheit_id ]);
}
public function getLehreinheitenForStudentAndStudienSemester($lehrveranstaltung_id, $student_uid, $studiensemester_kurzbz)
{
$query = <<<EOSQL
SELECT
le.*
FROM
lehre.tbl_lehreinheit le
JOIN
campus.vw_student_lehrveranstaltung vslv USING(lehreinheit_id)
WHERE
vslv.lehrveranstaltung_id = {$this->escape($lehrveranstaltung_id)} AND
vslv.uid = {$this->escape($student_uid)} AND
vslv.studiensemester_kurzbz = {$this->escape($studiensemester_kurzbz)}
EOSQL;
$res = $this->execReadOnlyQuery($query);
return $res;
}
public function getLehrfachIdMitarbeiter($angezeigtes_stsem,$user,$lvid)
{
$query = "
SELECT
distinct lehrfach_id
FROM
lehre.tbl_lehreinheit
JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id)
WHERE
studiensemester_kurzbz=" . $this->escape($angezeigtes_stsem) . "
AND mitarbeiter_uid=" . $this->escape($user)."
AND lehrveranstaltung_id=" . $this->escape(intval($lvid));
$res = $this->execReadOnlyQuery($query);
return $res;
}
public function getLehrfachIdStudierender($angezeigtes_stsem,$user,$lvid)
{
$query = "
SELECT
distinct lehrfach_id
FROM
campus.vw_student_lehrveranstaltung
WHERE
lehrveranstaltung_id=" . $this->escape(intval($lvid))."
AND studiensemester_kurzbz=" . $this->escape($angezeigtes_stsem)."
AND uid=" . $this->escape($user);
$res = $this->execReadOnlyQuery($query);
return $res;
}
public function getLehreinheitInfo($lvid, $angezeigtes_stsem, $lehrfach_id)
{
$query = "
SELECT
*
FROM (
SELECT
distinct on(uid) vorname, nachname, tbl_benutzer.uid as uid,
CASE
WHEN lehrfunktion_kurzbz='LV-Leitung' THEN true
ELSE false
END as lvleiter
FROM
lehre.tbl_lehreinheit, lehre.tbl_lehreinheitmitarbeiter,
public.tbl_benutzer, public.tbl_person
WHERE
tbl_lehreinheit.lehreinheit_id = tbl_lehreinheitmitarbeiter.lehreinheit_id
AND tbl_lehreinheitmitarbeiter.mitarbeiter_uid = tbl_benutzer.uid
AND tbl_person.person_id = tbl_benutzer.person_id
AND lehrveranstaltung_id = " . $this->escape(intval($lvid)) . "
AND tbl_lehreinheitmitarbeiter.mitarbeiter_uid NOT like '_Dummy%'
AND tbl_benutzer.aktiv = true
AND tbl_person.aktiv = true
AND studiensemester_kurzbz = " . $this->escape($angezeigtes_stsem);
if($lehrfach_id != '')
{
$query .= " AND tbl_lehreinheit.lehrfach_id = " . $this->escape(intval($lehrfach_id));
}
$query .= " ORDER BY uid, lvleiter desc) as a ORDER BY lvleiter desc, nachname, vorname";
$res = $this->execReadOnlyQuery($query);
return $res;
}
}
@@ -41,4 +41,38 @@ class Lehreinheitmitarbeiter_model extends DB_Model
return error ('Incorrect parameter type');
}
}
/**
* @param integer $lehrveranstaltung_id
* @param string $studiensemester_kurzbz
*
* @return stdClass
*/
public function getForLv($lehrveranstaltung_id, $studiensemester_kurzbz)
{
$this->addSelect('ma.uid, ma.vorname, ma.nachname, ma.titelpre, ma.titelpost, lehrfunktion_kurzbz');
$this->addGroupBy('ma.uid, ma.vorname, ma.nachname, ma.titelpre, ma.titelpost, lehrfunktion_kurzbz');
$this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id');
$this->addJoin('campus.vw_mitarbeiter ma', $this->dbTable . '.mitarbeiter_uid=ma.uid');
$this->addOrder('nachname');
$this->addOrder('vorname');
if (defined('CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON') && CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON != '')
{
$this->addJoin('(SELECT vertrag_id, CASE WHEN vertragsstatus_kurzbz=\'storno\' THEN 0 WHEN vertragsstatus_kurzbz=\'erteilt\' THEN 1 ELSE 2 END AS vertragsstatus_kurzbz FROM lehre.tbl_vertrag_vertragsstatus) v', 'vertrag_id', 'LEFT');
$having = $this->db->compile_binds('(EXISTS (SELECT 1 FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=? AND tbl_studiensemester.start < (SELECT start FROM public.tbl_studiensemester stsem WHERE stsem.studiensemester_kurzbz=?)) OR MIN(vertragsstatus_kurzbz)=1)', [
$studiensemester_kurzbz,
CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON
]);
$this->db->having($having);
}
return $this->loadWhere([
'lehrveranstaltung_id' => $lehrveranstaltung_id,
'studiensemester_kurzbz' => $studiensemester_kurzbz
]);
}
}
@@ -0,0 +1,14 @@
<?php
class LehrveranstaltungFaktor_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'lehre.tbl_lehrveranstaltung_faktor';
$this->pk = 'lehrveranstaltung_faktor_id';
}
}
@@ -544,6 +544,113 @@ class Lehrveranstaltung_model extends DB_Model
return $this->execQuery($qry, $params);
}
/**
* Gets Lehrveranstaltungen of a student with grades if available
*
* @param string $student_uid
* @param string $studiensemester_kurzbz
* @param string|null $sprache
* @param number|null $lvid - returns only information about that single lv if the parameter is set
*
* @return stdClass
*/
public function getLvsByStudentWithGrades($student_uid, $studiensemester_kurzbz, $sprache = null, $lvid=null)
{
if ($sprache) {
$sprache_qry = $this->db->compile_binds('SELECT index FROM public.tbl_sprache WHERE sprache = ?', [$sprache]);
$bezeichnung = 'bezeichnung_mehrsprachig[(' . $sprache_qry . ')]';
$sgbezeichnung = $sprache == 'English' ? 'COALESCE(sg.english, sg.bezeichnung)' : 'sg.bezeichnung';
$lvbezeichnung = $sprache == 'English' ? 'COALESCE(v.bezeichnung_english, v.bezeichnung)' : 'v.bezeichnung';
} else {
$bezeichnung = 'bezeichnung';
$sgbezeichnung = 'sg.bezeichnung';
$lvbezeichnung = 'v.bezeichnung';
}
$this->addDistinct();
// TODO(chris): selects
/*
semester (?)
module
bezeichnung
sg_bezeichnung
studiengang_kuerzel
lvnote
znote
studiengang_kz
lehrveranstaltung_id
benotung
lvinfo
farbe
sprache (?)
ects (?)
incoming (?)
orgform_kurzbz (?)
*/
// TODO(chris): module or kf
#$this->addSelect($this->dbTable . '.*');
#$this->addSelect('v.*');
$this->addSelect($this->dbTable . '.benotung');
$this->addSelect($this->dbTable . '.lvinfo');
$this->addSelect($this->dbTable . '.farbe');
$this->addSelect($this->dbTable . '.incoming');
$this->addSelect($this->dbTable . '.orgform_kurzbz');
$this->addSelect('v.studiengang_kz');
$this->addSelect('v.lehrveranstaltung_id');
$this->addSelect('v.semester');
$this->addSelect('v.sprache');
$this->addSelect('v.ects');
$this->addSelect('znn.positiv');
#$this->addSelect('splv.module');
$this->addSelect($lvbezeichnung . ' AS bezeichnung');
$this->addSelect($sgbezeichnung . ' AS sg_bezeichnung');
$this->addSelect('UPPER(sg.typ::VARCHAR(1) || sg.kurzbz) AS studiengang_kuerzel');
$this->addSelect('COALESCE(gnn.' . $bezeichnung . ', gnn.bezeichnung, gn.note::text) AS lvnote');
$this->addSelect('COALESCE(znn.' . $bezeichnung . ', znn.bezeichnung, zn.note::text) AS znote');
// TODO(chris): Potentielle Anpassung "Eine UID"
$this->addJoin('campus.vw_student_lehrveranstaltung v', 'lehrveranstaltung_id');
$this->addJoin('public.tbl_studiengang sg', $this->dbTable . '.studiengang_kz = sg.studiengang_kz');
$this->db->where("v.lehreverzeichnis<>''");
if(isset($lvid))
{
$this->db->where("v.lehrveranstaltung_id", $lvid);
}
$this->addJoin('campus.tbl_lvgesamtnote gn', 'gn.lehrveranstaltung_id=v.lehrveranstaltung_id AND gn.student_uid=v.uid AND gn.studiensemester_kurzbz=v.studiensemester_kurzbz', 'LEFT');
$this->addJoin('lehre.tbl_note gnn', 'gn.note=gnn.note', 'LEFT');
$this->addJoin('lehre.tbl_zeugnisnote zn', 'zn.lehrveranstaltung_id=v.lehrveranstaltung_id AND zn.student_uid=v.uid AND zn.studiensemester_kurzbz=v.studiensemester_kurzbz', 'LEFT');
$this->addJoin('lehre.tbl_note znn', 'zn.note=znn.note', 'LEFT');
$this->addOrder('bezeichnung');
/*if (!defined("CIS_PROFIL_STUDIENPLAN_MODULE_AUSBLENDEN") || !CIS_PROFIL_STUDIENPLAN_MODULE_AUSBLENDEN) {
$modulebezeichnung = str_replace('v.', 'm.', $lvbezeichnung);
$modulesql = '
LEFT JOIN lehre.tbl_studienplan_lehrveranstaltung p ON(lv.studienplan_lehrveranstaltung_id_parent=p.studienplan_lehrveranstaltung_id)
LEFT JOIN lehre.tbl_lehrveranstaltung m ON(m.lehrveranstaltung_id = p.lehrveranstaltung_id)';
} else {
$modulebezeichnung = 'NULL';
$modulesql = '';
}
$this->addJoin('(
SELECT lv.lehrveranstaltung_id, sps.studiensemester_kurzbz, so.studiengang_kz, lv.semester, ' . $modulebezeichnung . ' AS module
FROM lehre.tbl_studienplan_lehrveranstaltung lv
LEFT JOIN lehre.tbl_studienplan sp ON(sp.studienplan_id=lv.studienplan_id)
JOIN lehre.tbl_studienplan_semester sps ON(sp.studienplan_id=sps.studienplan_id AND sps.semester=lv.semester)
JOIN lehre.tbl_studienordnung so ON(so.studienordnung_id=sp.studienordnung_id)
' . $modulesql . '
) splv', 'splv.lehrveranstaltung_id=v.lehrveranstaltung_id AND splv.studiensemester_kurzbz=v.studiensemester_kurzbz AND splv.studiengang_kz=v.studiengang_kz', 'LEFT');*/
return $this->loadWhere(['v.uid' => $student_uid, 'v.lehre' => true, 'v.studiensemester_kurzbz' => $studiensemester_kurzbz]);
}
/**
* Gets valid Lehrveranstaltungen with incoming places for a Studiensemester.
* Only
@@ -785,10 +892,124 @@ class Lehrveranstaltung_model extends DB_Model
return $this->execQuery($qry, array($student_uid));
}
/**
* @param integer $lehrveranstaltung_id
* @param string $studiensemester_kurzbz
*
* @return stdClass
*/
public function getKoordinator($lehrveranstaltung_id, $studiensemester_kurzbz = null)
{
$binds = [
$lehrveranstaltung_id,
$lehrveranstaltung_id,
$lehrveranstaltung_id,
$lehrveranstaltung_id
];
$qry = "
SELECT
a.uid, vorname, nachname, titelpre, titelpost
FROM (
SELECT
koordinator as uid
FROM
lehre.tbl_lehrveranstaltung
WHERE
lehrveranstaltung_id = ?
UNION
SELECT
uid
FROM
lehre.tbl_lehreinheit
JOIN lehre.tbl_lehrveranstaltung AS lehrfach ON(tbl_lehreinheit.lehrfach_id = lehrfach.lehrveranstaltung_id)
JOIN public.tbl_fachbereich ON(lehrfach.oe_kurzbz=tbl_fachbereich.oe_kurzbz)
JOIN public.tbl_benutzerfunktion ON(tbl_fachbereich.fachbereich_kurzbz=tbl_benutzerfunktion.fachbereich_kurzbz)
WHERE
tbl_benutzerfunktion.funktion_kurzbz='fbk'
AND (tbl_benutzerfunktion.datum_von IS null OR tbl_benutzerfunktion.datum_von <= now())
AND (tbl_benutzerfunktion.datum_bis IS null OR tbl_benutzerfunktion.datum_bis >= now())
AND tbl_lehreinheit.lehrveranstaltung_id = ?
AND tbl_benutzerfunktion.oe_kurzbz = (
SELECT
tbl_studiengang.oe_kurzbz
FROM
lehre.tbl_lehrveranstaltung
JOIN public.tbl_studiengang USING(studiengang_kz)
WHERE lehrveranstaltung_id = ?
)
AND EXISTS (
SELECT
lehrveranstaltung_id
FROM
lehre.tbl_lehrveranstaltung
WHERE
lehrveranstaltung_id = ?
AND koordinator IS null
)
";
if ($studiensemester_kurzbz !== null)
{
$qry .= " AND tbl_lehreinheit.studiensemester_kurzbz = ?";
$binds[] = $studiensemester_kurzbz;
}
$qry .= "
) AS a
JOIN campus.vw_mitarbeiter ON(a.uid=vw_mitarbeiter.uid)
WHERE vw_mitarbeiter.aktiv
";
return $this->execQuery($qry, $binds);
}
public function getStg($lehrveranstaltung_id)
{
$this->addSelect('stg.*');
$this->addJoin('public.tbl_studiengang stg', 'studiengang_kz');
return $this->load($lehrveranstaltung_id);
}
//Berechtigungen auf Fachbereichsebene
public function getBerechtigungenAufFachberechsebene($lvid, $angezeigtes_stsem)
{
$query = "
SELECT
DISTINCT lehrfach.oe_kurzbz
FROM
lehre.tbl_lehrveranstaltung
JOIN
lehre.tbl_lehreinheit USING(lehrveranstaltung_id)
JOIN
lehre.tbl_lehrveranstaltung as lehrfach ON(tbl_lehreinheit.lehrfach_id=lehrfach.lehrveranstaltung_id)
WHERE
tbl_lehrveranstaltung.lehrveranstaltung_id = " . $this->escape(intval($lvid));
if(isset($angezeigtes_stsem) && $angezeigtes_stsem != ''){
$query .= " AND studiensemester_kurzbz = " . $this->escape($angezeigtes_stsem);
}
$res = $this->execReadOnlyQuery($query);
return $res;
}
public function getStudentEMail($lvid, $angezeigtes_stsem)
{
$query = "
SELECT
DISTINCT vw_lehreinheit.stg_kurzbz, vw_lehreinheit.stg_typ,
vw_lehreinheit.semester, COALESCE(vw_lehreinheit.verband,'') as verband,
COALESCE(vw_lehreinheit.gruppe,'') as gruppe,
vw_lehreinheit.gruppe_kurzbz, tbl_gruppe.mailgrp
FROM
campus.vw_lehreinheit
LEFT JOIN
public.tbl_gruppe USING(gruppe_kurzbz)
WHERE
lehrveranstaltung_id = " . $this->escape(intval($lvid)) . "
AND studiensemester_kurzbz = " . $this->escape($angezeigtes_stsem);
$res = $this->execReadOnlyQuery($query);
return $res;
}
}
@@ -11,4 +11,39 @@ class Lvangebot_model extends DB_Model
$this->dbTable = 'lehre.tbl_lvangebot';
$this->pk = 'lvangebot_id';
}
/**
* Prueft ob eine Abmeldung von einer Lehrveranstaltung moeglich ist
* und liefert die Gruppen von denen sich abgemeldet werden kann
* @param $lehrveranstaltung_id
* @param $studiensemester_kurzbz
* @param $uid
* @return $gruppen Array mit den Gruppen
*/
public function AbmeldungMoeglich($lehrveranstaltung_id, $studiensemester_kurzbz, $uid)
{
$query = "SELECT
gruppe_kurzbz
FROM
lehre.tbl_lvangebot
JOIN public.tbl_benutzergruppe USING(studiensemester_kurzbz, gruppe_kurzbz)
WHERE
tbl_lvangebot.studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz)."
AND tbl_benutzergruppe.uid = " . $this->escape($uid)."
AND (tbl_lvangebot.lehrveranstaltung_id = " . $this->escape(intval($lehrveranstaltung_id))."
OR tbl_lvangebot.lehrveranstaltung_id IN(SELECT lehrveranstaltung_id_kompatibel
FROM lehre.tbl_lehrveranstaltung_kompatibel
WHERE lehrveranstaltung_id = " . $this->escape(intval($lehrveranstaltung_id))."
)
)";
$res = $this->execReadOnlyQuery($query);
$rows = (hasData($res)) ? getData($res) : array();
$gruppen=array();
foreach($rows as $row)
{
$gruppen[] = $row->gruppe_kurzbz;
}
return $gruppen;
}
}
@@ -37,6 +37,35 @@ class Pruefung_model extends DB_Model
return $this->execQuery($qry, array($person_id, $studiensemester_kurzbz));
}
/**
* Gets Pruefungen of a student for a Lehrveranstaltung.
*
* @param string $uid
* @param string $lehrveranstaltung_id
* @param string|null $sprache
*
* @return object
*/
public function getByStudentAndLv($uid, $lehrveranstaltung_id, $sprache = null)
{
// TODO(chris): Potentielle Anpassung "Eine UID"
$this->dbTable = 'lehre.tbl_pruefung';
if ($sprache) {
$sprache_qry = $this->db->compile_binds('SELECT index FROM public.tbl_sprache WHERE sprache = ?', [$sprache]);
$bezeichnung = 'bezeichnung_mehrsprachig[(' . $sprache_qry . ')]';
} else {
$bezeichnung = 'bezeichnung';
}
$this->addSelect($this->dbTable . '.pruefung_id, ' . $this->dbTable . '.pruefungstyp_kurzbz, ' . $this->dbTable . '.datum, COALESCE(n.' . $bezeichnung . ', n.note::text) AS note');
$this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id');
$this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id');
$this->addJoin('lehre.tbl_note n', 'note');
return $this->loadWhere(['lehrveranstaltung_id' => $lehrveranstaltung_id, 'student_uid' => $uid]);
}
/**
* NOTE(chris): not used
@@ -151,6 +151,7 @@ class Studierendenantrag_model extends DB_Model
$this->addSelect('s.insertvon status_insertvon');
$this->addSelect('t.bezeichnung[(' . $lang . ')] statustyp');
$this->addSelect('p.unruly AS unruly');
$this->addSelect($this->dbTable . '.insertamum AS insertamum');
$this->addJoin(
'campus.tbl_studierendenantrag_status s',
@@ -489,4 +490,4 @@ class Studierendenantrag_model extends DB_Model
return hasData($this->load());
}
}
}
@@ -189,6 +189,19 @@ class Organisationseinheit_model extends DB_Model
return $this->loadWhere($condition);
}
/**
* @param string $oe_kurzbz
*
* @return stdClass
*/
public function getWithType($oe_kurzbz)
{
$this->addSelect($this->dbTable . '.*, t.bezeichnung AS organisationseinheittyp');
$this->addJoin('public.tbl_organisationseinheittyp t', 'organisationseinheittyp_kurzbz');
return $this->load($oe_kurzbz);
}
/**
* Get OEs by eventQuery string. Use with autocomplete event queries.
* @param $eventQuery String
@@ -457,7 +457,7 @@ class Studiengang_model extends DB_Model
*/
public function getLeitung($studiengang_kz = null)
{
$this->addSelect('uid, studiengang_kz, oe_kurzbz, vorname, nachname, email');
$this->addSelect('uid, studiengang_kz, oe_kurzbz, vorname, nachname, email, titelpre, titelpost, alias');
$this->addJoin('public.tbl_benutzerfunktion', 'oe_kurzbz');
$this->addJoin('public.tbl_benutzer', 'uid');
$this->addJoin('public.tbl_person', 'person_id');
@@ -493,6 +493,53 @@ class Studiengang_model extends DB_Model
return $this->loadWhere($condition);
}
/**
* Get Studiengangsleitung/en of Studiengang/Studiengaenge. With Details
*
* @param null $studiengang_kz Numeric or Array
* @return array
*/
public function getLeitungDetailed($studiengang_kz = null)
{
$this->addSelect('studiengang_kz, email, f.oe_kurzbz, b.uid, b.alias, b.aktiv, p.vorname, p.nachname, p.titelpre, p.titelpost, m.telefonklappe, k.kontakt, o.planbezeichnung');
$this->addJoin('public.tbl_benutzerfunktion f', 'oe_kurzbz');
$this->addJoin('public.tbl_benutzer b', 'uid');
$this->addJoin('public.tbl_person p', 'person_id');
$this->addJoin('public.tbl_mitarbeiter m', 'mitarbeiter_uid=uid', 'LEFT');
$this->addJoin('public.tbl_kontakt k', 'k.standort_id=m.standort_id AND kontakttyp=\'telefon\'', 'LEFT');
$this->addJoin('public.tbl_ort o', 'ort_kurzbz', 'LEFT');
if (!is_numeric($studiengang_kz) && !is_array($studiengang_kz))
{
return error('Studiengangskennzahl ungültig');
}
if (is_null($studiengang_kz))
{
$condition = '
funktion_kurzbz = \'Leitung\'
AND ( datum_von <= NOW() OR datum_von IS NULL )
AND ( datum_bis >= NOW() OR datum_bis IS NULL )
';
}
elseif (is_numeric($studiengang_kz) || is_array($studiengang_kz))
{
if (is_array($studiengang_kz))
{
$studiengang_kz = array_map(array($this,'escape'), $studiengang_kz);
$studiengang_kz = implode(', ', $studiengang_kz);
}
$condition = '
funktion_kurzbz = \'Leitung\'
AND ( datum_von <= NOW() OR datum_von IS NULL )
AND ( datum_bis >= NOW() OR datum_bis IS NULL )
AND studiengang_kz IN (' . $studiengang_kz. ')';
;
}
return $this->loadWhere($condition);
}
public function getStudiengaengeWithOrgForm($typ, $semester)
{
$query = "SELECT DISTINCT (UPPER(so.studiengangkurzbzlang || ':' || sp.orgform_kurzbz)) AS Studiengang
@@ -205,6 +205,25 @@ class Studiensemester_model extends DB_Model
return $this->execQuery($query, array($studiensemester_kurzbz));
}
/**
* @param string $student_uid
*
* @return StdClass
*/
public function getWhereStudentHasLvs($student_uid)
{
$this->addDistinct();
$this->addSelect($this->dbTable . '.*');
// TODO(chris): Potentielle Anpassung "Eine UID"
$this->addJoin('campus.vw_student_lehrveranstaltung v', 'studiensemester_kurzbz');
$this->db->where("v.lehreverzeichnis<>''");
$this->addOrder($this->dbTable . '.start');
return $this->loadWhere(['uid' => $student_uid, 'v.lehre' => true]);
}
public function getAktAndFutureSemester()
{
$query = 'SELECT studiensemester_kurzbz
@@ -253,4 +272,19 @@ class Studiensemester_model extends DB_Model
if (is_numeric($studienjahrNumber) && mb_substr($studiensemester_kurzbz, 0, 2) == 'SS') (int)$studienjahrNumber -= 1;
return $studienjahrNumber;
}
/**
* Holt Start und Ende des Studiensemester_kurzbz
* @param studiensemester_kurzbz
* @return stdClass
*/
public function getStartEndeFromStudiensemester($studiensemester_kurzbz)
{
return $this->execReadOnlyQuery("
SELECT
start, ende
FROM public.tbl_studiensemester
WHERE studiensemester_kurzbz = ?",[$studiensemester_kurzbz]);
}
}
@@ -147,6 +147,38 @@ class Benutzerfunktion_model extends DB_Model
return $this->execQuery($query, $parametersArray);
}
/**
* Gets all Benutzer with details for a given Benutzerfunktion and optionally specified Oe and semester
*
* @param string $funktion_kurzbz
* @param string $oe_kurzbz
* @param integer | null $semester
* @return array|null
*/
public function getBenutzerFunktionenDetailed($funktion_kurzbz, $oe_kurzbz = null, $semester = null)
{
$this->addSelect($this->dbTable . '.funktion_kurzbz, ' . $this->dbTable . '.oe_kurzbz, ' . $this->dbTable . '.semester, ' . $this->dbTable . '.bezeichnung, f.beschreibung, b.uid, b.alias, b.aktiv, p.vorname, p.nachname, p.titelpre, p.titelpost, m.telefonklappe, k.kontakt, o.planbezeichnung');
$this->addJoin('public.tbl_funktion f', 'funktion_kurzbz');
$this->addJoin('public.tbl_benutzer b', 'uid');
$this->addJoin('public.tbl_person p', 'person_id');
$this->addJoin('public.tbl_mitarbeiter m', 'mitarbeiter_uid=uid', 'LEFT');
$this->addJoin('public.tbl_kontakt k', 'k.standort_id=m.standort_id AND kontakttyp=\'telefon\'', 'LEFT');
$this->addJoin('public.tbl_ort o', 'ort_kurzbz', 'LEFT');
$this->addOrder('LOWER(uid)');
$where = [$this->dbTable . '.funktion_kurzbz' => $funktion_kurzbz];
if ($oe_kurzbz !== null)
$where[$this->dbTable . '.oe_kurzbz'] = $oe_kurzbz;
if ($semester !== null)
$where[$this->dbTable . '.semester'] = $semester;
$this->db->where('(' . $this->dbTable . '.datum_bis >= NOW() OR ' . $this->dbTable . '.datum_bis IS NULL)', NULL, FALSE);
$this->db->where('(' . $this->dbTable . '.datum_von <= NOW() OR ' . $this->dbTable . '.datum_von IS NULL)', NULL, FALSE);
return $this->loadWhere($where);
}
/**
* Get active Studiengangsleitung(en) of the user by UID.
* @param $uid
@@ -12,4 +12,25 @@ class Benutzergruppe_model extends DB_Model
$this->pk = array('gruppe_kurzbz', 'uid');
$this->hasSequence = false;
}
/**
* Laedt die User in einer Benutzergruppe
* @param gruppe_kurzbz, stsem
* @return array
*/
public function getUids($gruppe_kurzbz, $stsem)
{
$query = "
SELECT
uid
FROM
public.tbl_benutzergruppe
WHERE
gruppe_kurzbz = " . $this->escape($gruppe_kurzbz) . "
AND studiensemester_kurzbz = " . $this->escape($stsem);
$res = $this->execReadOnlyQuery($query);
$uids = (hasData($res)) ? getData($res) : array();
return $uids;
}
}
@@ -0,0 +1,14 @@
<?php
class Gruppe_manager_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'public.tbl_gruppe_manager';
$this->pk = 'gruppe_manager_id';
}
}
+1 -1
View File
@@ -142,7 +142,7 @@ class Notiz_model extends DB_Model
$this->addSelect('public.tbl_notiz.*');
$this->addJoin('public.tbl_notizzuordnung', 'notiz_id');
return $this->loadWhere(array('person_id' => $person_id));
return $this->loadWhere(array('person_id' => $person_id, 'tbl_notiz.typ' => NULL));
}
/**
@@ -290,6 +290,21 @@ class Person_model extends DB_Model
return success($result->vorname. ' '. $result->nachname);
}
/**
* Get first name of given uid. (Vorname Nachname)
* @param $uid
* @return array
*/
public function getFirstName($uid)
{
$result = getData($this->getByUid($uid))[0];
if (!$result) {
show_error('Failed loading person');
}
return success($result->vorname);
}
public function checkDuplicate($person_id)
{
$qry = "SELECT person_id
@@ -0,0 +1,187 @@
<?php
class Profil_update_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'public.tbl_profil_update';
$this->pk = ['profil_update_id'];
$this->hasSequence = true;
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->load->library('PermissionLib');
}
/**
* getTimestamp
* returns insert or update timestamp of a certain profil update
*
* @param boolean $update: conditional whether to return insertamum or updateamum
*/
//TODO: function wird nicht verwendet
public function getTimestamp($id, $update = false)
{
$selectStatement = $update ? 'updateamum' : 'insertamum';
$this->addSelect([$selectStatement]);
$res = $this->load([$id]);
return hasData($res) ? getData($res)[0]->$selectStatement : null;
}
/**
* getFilesFromChangeRequest
*
* returns all files associated to a profil update request in the following format:
* {dms_id:123 , name:"test"}
*
* @param boolean $profil_update_id primary key of the profil update request
* @return array
*/
//TODO: function wird nicht verwendet
public function getFilesFromChangeRequest($profil_update_id)
{
$this->addSelect(["requested_change"]);
$res = $this->load([$profil_update_id]);
$res = hasData($res) ? getData($res)[0] : null;
return json_decode($res->requested_change)->files ?: [];
}
//? queries the tbl_profil_updates without permissions of the user
public function getProfilUpdatesWhere($whereClause)
{
if (array_key_exists("uid", $whereClause)) {
$whereClause["public.tbl_profil_update.uid"] = $whereClause["uid"];
unset($whereClause["uid"]);
}
$this->addSelect(["public.tbl_profil_update.*", "public.tbl_person.vorname"]);
$this->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_profil_update.uid");
$this->addJoin("public.tbl_person", "public.tbl_person.person_id = public.tbl_benutzer.person_id");
$res = $this->loadWhere($whereClause);
if (isError($res)) {
return $res;
}
if (hasData($res)) {
foreach (getData($res) as $request) {
$this->formatProfilRequest($request);
}
}
return $res;
}
//? remove File from the Profil Update
public function removeFileFromProfilUpdate($dms_id)
{
if(!is_int($dms_id) || $dms_id < 0){
return error("not valid dms_id");
}
return $this->execReadOnlyQuery("
UPDATE public.tbl_profil_update
SET attachment_id = NULL
WHERE attachment_id = ?", [$dms_id]);
}
/**
* getProfilUpdateWithPermission
*
* queries the profil updates and checks if the user trying to query the data has permissions to get the profil updates
*
* @param string $whereClause additional where clause that will be appended to the db query
* @return array array with all the profil updates that the user is eligible to see
*/
public function getProfilUpdateWithPermission($whereClause = null)
{
$studentBerechtigung = $this->permissionlib->isBerechtigt('student/stammdaten', 's');
$mitarbeiterBerechtigung = $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', 's');
$oe_berechtigung = $this->permissionlib->getOE_isEntitledFor('student/stammdaten');
$lang = "select index from public.tbl_sprache where sprache =" . $this->escape(getUserLanguage());
$res = [];
if ($studentBerechtigung) {
//? Nur wenn der/die AssistentIn auch die Berechtigung in der gleichen Organisationseinheit des Studenten hat
$parameters = [];
$query = "
SELECT
profil_update_id, tbl_profil_update.uid, (tbl_person.vorname || ' ' || tbl_person.nachname) AS name , topic, requested_change, tbl_profil_update.updateamum, tbl_profil_update.updatevon, tbl_profil_update.insertamum, tbl_profil_update.insertvon, status, public.tbl_profil_update_status.bezeichnung_mehrsprachig[(" . $lang . ")] as status_translated, status_timestamp, status_message, attachment_id
FROM public.tbl_profil_update
JOIN public.tbl_profil_update_status ON public.tbl_profil_update_status.status_kurzbz = public.tbl_profil_update.status
JOIN public.tbl_student ON public.tbl_student.student_uid=public.tbl_profil_update.uid
JOIN public.tbl_benutzer ON public.tbl_benutzer.uid = public.tbl_student.student_uid
JOIN public.tbl_person ON public.tbl_benutzer.person_id=public.tbl_person.person_id
JOIN public.tbl_studiengang ON public.tbl_studiengang.studiengang_kz=public.tbl_student.studiengang_kz
Where public.tbl_studiengang.oe_kurzbz IN ? ";
$parameters[] = $oe_berechtigung;
if ($whereClause) {
foreach ($whereClause as $key => $value) {
$parameters[] = $value;
$query .= " AND " . $key . " = ?";
}
}
$studentRequests = $this->execReadOnlyQuery($query, $parameters);
if (isError($studentRequests))
return error("db error: " . getData($studentRequests));
$studentRequests = getData($studentRequests) ?: [];
foreach ($studentRequests as $request) {
array_push($res, $request);
}
}
if ($mitarbeiterBerechtigung) {
$this->addSelect(["profil_update_id", "tbl_profil_update.uid", "(tbl_person.vorname || ' ' || tbl_person.nachname) AS name", "topic", "requested_change", "tbl_profil_update.updateamum", "tbl_profil_update.updatevon", "tbl_profil_update.insertamum", "tbl_profil_update.insertvon", "status", "public.tbl_profil_update_status.bezeichnung_mehrsprachig[(" . $lang . ")] AS status_translated", "status_timestamp", "status_message", "attachment_id"]);
$this->addJoin('tbl_profil_update_status', 'tbl_profil_update_status.status_kurzbz=tbl_profil_update.status');
$this->addJoin('tbl_mitarbeiter', 'tbl_mitarbeiter.mitarbeiter_uid=tbl_profil_update.uid');
$this->addJoin('tbl_benutzer', 'tbl_benutzer.uid=tbl_profil_update.uid');
$this->addJoin('tbl_person', 'tbl_benutzer.person_id=tbl_person.person_id');
$mitarbeiterRequests = $this->loadWhere($whereClause);
if (isError($mitarbeiterRequests))
return error("db error: " . getData($mitarbeiterRequests));
$mitarbeiterRequests = getData($mitarbeiterRequests) ?: [];
foreach ($mitarbeiterRequests as $request) {
array_push($res, $request);
}
}
if ($res) {
foreach ($res as $request) {
$this->formatProfilRequest($request);
}
}
return $res;
}
/**
* formatProfilRequest
*
* formats the the properties of a profilUpdate request row result
*
* @param stdClass $request unflitered profilUpdate row result from the database
* @return void
*/
private function formatProfilRequest($request)
{
$request->requested_change = json_decode($request->requested_change);
$request->insertamum = !is_null($request->insertamum) ? date_create($request->insertamum)->format('d.m.Y') : null;
$request->updateamum = !is_null($request->updateamum) ? date_create($request->updateamum)->format('d.m.Y') : null;
$request->status_timestamp = !is_null($request->status_timestamp) ? date_create($request->status_timestamp)->format('d.m.Y') : null;
}
}
@@ -0,0 +1,18 @@
<?php
class Profil_update_status_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'public.tbl_profil_update_status';
$this->pk = ['status_kurzbz'];
$this->hasSequence = false;
}
}
@@ -0,0 +1,16 @@
<?php
class Profil_update_topic_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'public.tbl_profil_update_topic';
$this->pk = ['topic_kurzbz'];
$this->hasSequence = false;
}
}
@@ -0,0 +1,22 @@
<?php
class Projects_Employees_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'sync.tbl_projects_employees';
$this->pk = 'projects_employees_id';
}
public function deleteByProjectTaskId($ids)
{
$qry = "DELETE FROM " . $this->dbTable . "
WHERE project_task_id IN ?";
return $this->execQuery($qry, array($ids));
}
}
@@ -0,0 +1,62 @@
<?php
class Lehretools_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'campus.tbl_lehre_tools';
$this->pk = 'lehre_tools_id';
}
/**
*
* Laedt die Tools zu einer Lehrveranstaltung
* @param $lehrveranstaltung_id
* @param $studiensemester_kurzbz
*/
public function getTools($lehrveranstaltung_id, $studiensemester_kurzbz, $sprache)
{
$query = "SELECT
lehre_tools_id,
bezeichnung[(SELECT index FROM public.tbl_sprache WHERE sprache = " . $this->escape($sprache) . ")] AS bezeichnung,
kurzbz,
basis_url,
logo_dms_id
FROM
campus.tbl_lehre_tools
JOIN campus.tbl_lehre_tools_organisationseinheit USING(lehre_tools_id)
WHERE
campus.tbl_lehre_tools_organisationseinheit.aktiv AND
(
oe_kurzbz IN(
SELECT
tbl_studiengang.oe_kurzbz
FROM
lehre.tbl_lehrveranstaltung
JOIN public.tbl_studiengang USING(studiengang_kz)
WHERE
tbl_lehrveranstaltung.lehrveranstaltung_id = " . $this->escape(intval($lehrveranstaltung_id)) . "
)
OR
oe_kurzbz IN(
SELECT
lehrfach.oe_kurzbz
FROM
lehre.tbl_lehreinheit
JOIN lehre.tbl_lehrveranstaltung as lehrfach ON(lehrfach_id=lehrfach.lehrveranstaltung_id)
WHERE
tbl_lehreinheit.studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . "
AND tbl_lehreinheit.lehrveranstaltung_id = " . $this->escape(intval($lehrveranstaltung_id)) . "
)
)
ORDER BY lehre_tools_id";
$toolsres = $this->execReadOnlyQuery($query);
$tools = (hasData($toolsres)) ? getData($toolsres) : array();
return $tools;
}
}
@@ -20,4 +20,16 @@ class Ort_model extends DB_Model
return $this->OrtModel->loadWhere(array("raumtyp_kurzbz" => $raumtyp_kurzbz));
}
public function getContentID($ort_kurzbz)
{
return $this->execReadOnlyQuery("
SELECT content_id
FROM public.tbl_ort
WHERE ort_kurzbz = ?;
",[$ort_kurzbz]);
}
}
@@ -11,4 +11,84 @@ class Reservierung_model extends DB_Model
$this->dbTable = 'campus.tbl_reservierung';
$this->pk = 'reservierung_id';
}
/**
* @param $uid
*
* @return stdClass
*/
public function getReservierungen($start_date, $end_date, $ort_kurzbz = null)
{
$stundenplan_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),'/'))
END as gruppen_kuerzel
FROM campus.vw_reservierung r
JOIN public.tbl_studiengang studg ON studg.studiengang_kz=r.studiengang_kz
JOIN lehre.tbl_stunde stund ON stund.stunde = r.stunde
LEFT JOIN public.tbl_benutzergruppe bg ON r.gruppe_kurzbz=bg.gruppe_kurzbz AND bg.uid=?
LEFT JOIN public.tbl_studiensemester ss1 ON bg.studiensemester_kurzbz=ss1.studiensemester_kurzbz AND ss1.start <= r.datum AND ss1.ende >= r.datum
LEFT JOIN public.tbl_studentlehrverband slv ON r.studiengang_kz=slv.studiengang_kz AND slv.student_uid=? AND (slv.semester=r.semester OR r.semester IS NULL) AND (slv.verband=r.verband OR r.verband IS NULL OR r.verband='' OR r.verband='0') AND (slv.gruppe=r.gruppe OR r.gruppe IS NULL OR r.gruppe ='' OR r.gruppe ='0') AND r.gruppe_kurzbz IS NULL
LEFT JOIN public.tbl_studiensemester ss2 ON slv.studiensemester_kurzbz = ss2.studiensemester_kurzbz AND ss2.start <=r.datum AND ss2.ende >= r.datum
WHERE datum >= ? AND datum <= ? AND (ss1.studiensemester_kurzbz IS NOT NULL
OR ss2.studiensemester_kurzbz IS NOT NULL)";
$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),'/'))
END as gruppen_kuerzel
FROM campus.vw_reservierung res
JOIN public.tbl_studiengang studg ON studg.studiengang_kz=res.studiengang_kz
JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = res.stunde
WHERE res.ort_kurzbz = ? AND datum >= ? AND datum <= ?";
$subquery = is_null($ort_kurzbz)? $stundenplan_reservierungen_query:$raum_reservierungen_query;
$query_result= $this->execReadOnlyQuery("
SELECT
'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,
ort_kurzbz, 'FFFFFF' as farbe
FROM
(
". $subquery ."
) AS subquery
GROUP BY datum, beginn, ende, ort_kurzbz, titel, beschreibung
ORDER BY datum, beginn
", is_null($ort_kurzbz) ?[getAuthUID(), getAuthUID(),$start_date,$end_date]: [$ort_kurzbz, $start_date, $end_date]);
return $query_result;
}
/**
* @param $uid
*
* @return stdClass
*/
public function loadForUid($uid)
{
$this->addSelect('r.*');
$this->db->join('public.tbl_benutzergruppe bg', 'r.gruppe_kurzbz=bg.gruppe_kurzbz AND bg.uid=?', 'LEFT', false);
$this->addJoin('public.tbl_studiensemester ss1', 'bg.studiensemester_kurzbz=ss1.studiensemester_kurzbz AND ss1.start<=r.datum AND ss1.ende>=r.datum', 'LEFT');
$this->db->join('public.tbl_studentlehrverband slv', "r.studiengang_kz=slv.studiengang_kz AND slv.student_uid=? AND (slv.semester=r.semester OR r.semester IS NULL) AND (slv.verband=r.verband OR r.verband IS NULL OR r.verband='' OR r.verband='0') AND (slv.gruppe=r.gruppe OR r.gruppe IS NULL OR r.gruppe='' OR r.gruppe='0') AND r.gruppe_kurzbz IS NULL", 'LEFT', false);
$this->addJoin('public.tbl_studiensemester ss2', 'slv.studiensemester_kurzbz=ss2.studiensemester_kurzbz AND ss2.start<=r.datum AND ss2.ende>=r.datum', 'LEFT');
$this->db->or_where('ss1.studiensemester_kurzbz IS NOT NULL', null, false);
$this->db->or_where('ss2.studiensemester_kurzbz IS NOT NULL', null, false);
$query = $this->db->get_compiled_select('campus.vw_reservierung r');
return $this->execQuery($query, [$uid, $uid]);
}
}
@@ -11,4 +11,318 @@ class Stundenplan_model extends DB_Model
$this->dbTable = 'lehre.tbl_stundenplan';
$this->pk = 'stundenplan_id';
}
/**
* @param string $ort_kurzbz
* @param string $date
*
* @return stdClass
*/
public function getRoomDataOnInterval($ort_kurzbz,$start_date,$end_date){
/*$raum_stundenplan= $this->execReadOnlyQuery("
-- merging all reservierungs information with the stundenplan information but with different types
SELECT 'stundenplan_eintrag' as eintrags_type, CONCAT(UPPER(sp.stg_typ),UPPER(sp.stg_kurzbz),'-',COALESCE(CAST(sp.semester AS varchar),'/'),COALESCE(CAST(sp.verband AS varchar),'/')) AS stg, CONCAT(lehrfach,'-',lehrform) AS lv_info, ort_kurzbz, studiengang_kz, uid, stunde, datum, titel, semester, verband, gruppe, gruppe_kurzbz, stg_kurzbz, * FROM lehre.vw_stundenplan sp
WHERE ort_kurzbz = ? AND datum >= ? AND datum <= ?
UNION ALL
SELECT 'reservierungs_eintrag' as eintrags_type, NULL, NULL, ort_kurzbz, studiengang_kz, uid, stunde, datum, titel, semester, verband, gruppe, gruppe_kurzbz, stg_kurzbz, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL FROM lehre.vw_reservierung res
WHERE ort_kurzbz = ? AND datum >= ? AND datum <= ?
", [$ort_kurzbz, $start_date, $end_date,$ort_kurzbz, $start_date, $end_date]);
*/
$raum_stundenplan= $this->execReadOnlyQuery("
SELECT CONCAT(UPPER(sp.stg_typ),UPPER(sp.stg_kurzbz),'-',COALESCE(CAST(sp.semester AS varchar),'/'),COALESCE(CAST(sp.verband AS varchar),'/')) AS stg, CONCAT(lehrfach,'-',lehrform) AS lv_info, * FROM lehre.vw_stundenplan sp
WHERE ort_kurzbz = ? AND datum >= ? AND datum <= ?
", [$ort_kurzbz, $start_date, $end_date]);
return $raum_stundenplan;
}
/**
* @param string $ort_kurzbz The room to query the planning for
* @param string $start_date The start date of the query interval
* @param string $end_date The end date of the query interval
*
* @return stdClass
*/
public function groupedCalendarEvents($ort_kurzbz,$start_date,$end_date){
$gruppierteEvents= $this->execReadOnlyQuery("
SELECT
'reservierung' as type,
NULL as unr,datum, stunde,
titel AS topic,
beschreibung as beschreibung,
string_agg(DISTINCT gruppe, '/') as gruppe,
string_agg(DISTINCT lektor, '/') as lektor,
res.ort_kurzbz,res.studiengang_kz, res.titel, res.beschreibung,NULL as lehreinheit_id,NULL as lehrfach_id,NULL as anmerkung, NULL as fix,NULL as lehrveranstaltung_id,NULL as stg_kurzbzlang,NULL as stg_bezeichnung,NULL as stg_typ, NULL as fachbereich_kurzbz,NULL as lehrfach,NULL as lehrfach_bez,NULL as farbe,NULL as lehrform, NULL as anmerkung_lehreinheit
FROM
(
SELECT
NULL as unr,datum, stunde,
CASE
WHEN gruppe_kurzbz IS NOT NULL THEN gruppe_kurzbz
ELSE CONCAT(UPPER(studg.typ),UPPER(res.stg_kurzbz),'-',COALESCE(CAST(res.semester AS varchar),'/'),COALESCE(CAST(res.verband AS varchar),'/'))
END as gruppe,
CASE
WHEN mit.kurzbz IS NOT NULL THEN mit.kurzbz
ELSE uid
END as lektor,
res.ort_kurzbz,res.studiengang_kz, res.titel, res.beschreibung,NULL as lehreinheit_id,NULL as lehrfach_id,NULL as anmerkung, NULL as fix,NULL as lehrveranstaltung_id,NULL as stg_kurzbzlang,NULL as stg_bezeichnung,NULL as stg_typ, NULL as fachbereich_kurzbz,NULL as lehrfach,NULL as lehrfach_bez,NULL as farbe,NULL as lehrform, NULL as anmerkung_lehreinheit
FROM lehre.vw_reservierung res
LEFT JOIN public.tbl_mitarbeiter mit ON mit.mitarbeiter_uid=uid
JOIN public.tbl_studiengang studg ON studg.studiengang_kz=res.studiengang_kz
WHERE
res.ort_kurzbz = ?
AND res.datum >= ?
AND res.datum <= ?
) as res
GROUP BY res.ort_kurzbz,res.studiengang_kz, res.datum, res.stunde, res.titel, res.beschreibung
UNION ALL
SELECT
'stundenplan' as type,
unr,datum, stunde,
CONCAT(lehrfach,'-',lehrform) as topic,
'' as beschreibung,
string_agg(DISTINCT gruppe, '/') as gruppe,
string_agg(DISTINCT lektor, '/') as lektor,
ort_kurzbz, studiengang_kz, titel,'' as beschreibung,lehreinheit_id,lehrfach_id,anmerkung,fix,lehrveranstaltung_id,stg_kurzbzlang,stg_bezeichnung,stg_typ,fachbereich_kurzbz,lehrfach,lehrfach_bez,farbe,lehrform,anmerkung_lehreinheit
FROM
(
SELECT
unr,datum, stunde,
CASE
WHEN gruppe_kurzbz IS NOT NULL THEN gruppe_kurzbz
ELSE CONCAT(UPPER(sp.stg_typ),UPPER(sp.stg_kurzbz),'-',COALESCE(CAST(sp.semester AS varchar),'/'),COALESCE(CAST(sp.verband AS varchar),'/'))
END as gruppe,
CASE
WHEN sp.mitarbeiter_kurzbz IS NOT NULL THEN sp.mitarbeiter_kurzbz
ELSE lektor
END as lektor,
ort_kurzbz, studiengang_kz, titel,'' as beschreibung,lehreinheit_id,lehrfach_id,anmerkung,fix,lehrveranstaltung_id,stg_kurzbzlang,stg_bezeichnung,stg_typ,fachbereich_kurzbz,lehrfach,lehrfach_bez,farbe,lehrform,anmerkung_lehreinheit
FROM lehre.vw_stundenplan sp
WHERE ort_kurzbz = ?
AND datum >= ?
AND datum <= ?
) as sp
GROUP BY
ort_kurzbz,unr, datum, stunde, lehreinheit_id, lehrfach_id,studiengang_kz,titel,anmerkung,fix,lehrveranstaltung_id,stg_kurzbzlang,stg_bezeichnung,stg_typ,fachbereich_kurzbz,lehrfach,lehrfach_bez,farbe,lehrform,anmerkung_lehreinheit
ORDER BY datum, stunde
", [$ort_kurzbz, $start_date, $end_date, $ort_kurzbz, $start_date, $end_date]);
return $gruppierteEvents;
}
/**
* groups rows of a subquery that fetches data from the lehre.vw_stundenplan table
* @param string $stundenplanViewQuery the subquery used to group the result
*
* @return stdClass
*/
public function stundenplanGruppierung($stundenplanViewQuery)
{
$query_result = $this->execReadOnlyQuery("
SELECT
'lehreinheit' as type, beginn, ende, datum,
CONCAT(lehrfach,'-',lehrform) as topic,
array_agg(DISTINCT lektor) as lektor,
array_agg(DISTINCT (gruppe,verband,semester,studiengang_kz,gruppen_kuerzel)) as gruppe,
string_agg(DISTINCT ort_kurzbz, '/') as ort_kurzbz,
array_agg(DISTINCT lehreinheit_id) as lehreinheit_id,
titel, lehrfach, lehrform, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id
FROM
(
SELECT unr,datum,beginn, ende,
CASE
WHEN sp.mitarbeiter_kurzbz IS NOT NULL THEN sp.mitarbeiter_kurzbz
ELSE lektor
END as lektor,
CASE
WHEN gruppe_kurzbz IS NOT NULL THEN gruppe_kurzbz
ELSE CONCAT(UPPER(sp.stg_typ),UPPER(sp.stg_kurzbz),'-',COALESCE(CAST(sp.semester AS varchar),'/'),COALESCE(CAST(sp.verband AS varchar),'/'))
END as gruppen_kuerzel,
(SELECT bezeichnung
FROM public.tbl_organisationseinheit
WHERE oe_kurzbz IN(
SELECT oe_kurzbz
FROM lehre.tbl_lehrveranstaltung
WHERE lehrveranstaltung_id = sp.lehrveranstaltung_id
)) as organisationseinheit,
ort_kurzbz, studiengang_kz, titel,lehreinheit_id,lehrfach_id,anmerkung,fix,lehrveranstaltung_id,stg_kurzbzlang,stg_bezeichnung,stg_typ,fachbereich_kurzbz,lehrfach,lehrfach_bez,farbe,lehrform,anmerkung_lehreinheit,gruppe, verband, semester,stg_kurzbz
FROM (".$stundenplanViewQuery.") sp
JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = sp.stunde
) as subquery
GROUP BY unr, datum, beginn, ende, ort_kurzbz, titel, lehrform, lehrfach, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id
ORDER BY datum, beginn
");
return $query_result;
}
/**
* NO STANDALONE FUNCTION - Generates a SQL query string to fetch 'stundenplan' events for a specific student within the current semester.
* @param string $uid the user id that is used to fetch the stundenplan rows from the lehre.vw_stundenplan table
*
* @return mixed
*/
public function getStundenplanQuery($start_date, $end_date,$semester,$gruppen,$studentlehrverbaende){
// helper function to check if either $gruppen or $studentlehrverbaende are empty for each semester
$emptyCheck = function($toBeCheckedArray) use ($semester){
$result = true;
$sem = array_keys($semester);
foreach($sem as $s){
if(count($toBeCheckedArray[$s]) > 0){
$result = false;
break;
}
}
return $result;
};
// if both the gruppen and the studentlehrverbaende are empty we early return
if($emptyCheck($gruppen) && $emptyCheck($studentlehrverbaende))
{
return false;
}
$query =
"select sp.*
from lehre.vw_stundenplan sp
WHERE
sp.datum >= ".$this->escape($start_date)."
AND sp.datum <= ".$this->escape($end_date);
// adds the AND sql chain only if both $gruppen and $studentlehrverbaende are not empty
if(!$emptyCheck($gruppen) || !$emptyCheck($studentlehrverbaende))
{
$query .= " AND ( ";
}
foreach($semester as $sem => $semester_date_range)
{
foreach($semester_date_range as $sem_date => $sem_date_range)
{
// if there are not groups for the semester skip the iteration step
if(!array_key_exists($sem_date,$gruppen) || count($gruppen[$sem_date]) == 0)
{
continue;
}
// converts the array of gruppen strings into a sql IN (_,_,_) chain
$query .="(sp.gruppe_kurzbz IN (" .implode(',',$gruppen[$sem_date]).") AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende)." )";
$query .="OR";
}
}
// if there are no studentlehrverbaende and the gruppen are not empty, we can remove the last OR added after the groups
if($emptyCheck($studentlehrverbaende) && !$emptyCheck($gruppen))
{
$query = substr($query, 0, -2);
}
foreach($semester as $sem=>$semester_date_range)
{
foreach($semester_date_range as $sem_date => $sem_date_range)
{
if(!array_key_exists($sem_date,$studentlehrverbaende) || count($studentlehrverbaende[$sem_date]) == 0)
{
continue;
}
foreach($studentlehrverbaende[$sem_date] as $key=>$lehrverband)
{
$query .= "((sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND sp.gruppe = ".$this->escape($lehrverband->gruppe)." AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).")";
// Eintraege fuer den ganzen Verband
$query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND (sp.gruppe is null OR sp.gruppe='') AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).")";
// Eintraege fuer das ganze Semester
$query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND (sp.verband is null OR sp.verband='') AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).") AND gruppe_kurzbz is null)";
$query .="OR";
}
}
}
// if the studentlehrverbaende is not empty we can remove the last OR that was added to the query
if(!$emptyCheck($studentlehrverbaende))
{
$query = substr($query, 0, -2);
}
// closes the AND sql chain only if it was opened previously
if(!$emptyCheck($gruppen) || !$emptyCheck($studentlehrverbaende))
{
$query .= ")";
}
return $query;
}
/**
* NO STANDALONE FUNCTION - Generates a SQL query string to fetch 'stundenplan' events for a specific room within a date range.
* @param string $ort_kurzbz the ort from which we want to query the stundenplan events
* @param string $start_date (inclusive) the minimum date that an event should have to be fetched
* @param string $end_date (inclusive) the maximum date that an event should not extend to be fetched
*
* @return string
*/
public function getRoomQuery($ort_kurzbz, $start_date, $end_date)
{
return
"select sp.*
FROM lehre.vw_stundenplan sp
WHERE ort_kurzbz = ".$this->escape($ort_kurzbz)."
AND datum >= ".$this->escape($start_date)."
AND datum <= ".$this->escape($end_date);
}
/**
* @param string $uid
*
* @return stdClass
*/
public function loadForUid($uid)
{
$this->addSelect(['sp.*','le.studiensemester_kurzbz']);
$this->db->join('public.tbl_benutzergruppe bg', 'sp.gruppe_kurzbz=bg.gruppe_kurzbz AND bg.uid=?', 'LEFT', false);
$this->addJoin('public.tbl_studiensemester ss1', 'bg.studiensemester_kurzbz=ss1.studiensemester_kurzbz AND ss1.start<=sp.datum AND ss1.ende>=sp.datum', 'LEFT');
$this->db->join('public.tbl_studentlehrverband slv', "sp.studiengang_kz=slv.studiengang_kz AND slv.student_uid=? AND (slv.semester=sp.semester OR sp.semester IS NULL) AND (slv.verband=sp.verband OR sp.verband IS NULL OR sp.verband='' OR sp.verband='0') AND (slv.gruppe=sp.gruppe OR sp.gruppe IS NULL OR sp.gruppe='' OR sp.gruppe='0') AND sp.gruppe_kurzbz IS NULL", 'LEFT', false);
$this->addJoin('public.tbl_studiensemester ss2', 'slv.studiensemester_kurzbz=ss2.studiensemester_kurzbz AND ss2.start<=sp.datum AND ss2.ende>=sp.datum', 'LEFT');
$this->db->join('lehre.tbl_lehreinheit le', 'le.lehreinheit_id=sp.lehreinheit_id', 'LEFT');
$this->db->or_where('ss1.studiensemester_kurzbz IS NOT NULL', null, false);
$this->db->or_where('ss2.studiensemester_kurzbz IS NOT NULL', null, false);
$query = $this->db->get_compiled_select('lehre.vw_stundenplan sp');
return $this->execQuery($query, [$uid, $uid]);
}
}
@@ -12,6 +12,8 @@ class Stundenplandev_model extends DB_Model
$this->pk = 'stundenplandev_id';
}
public function getMissingDirectGroups($studiensemester_kurzbz = null)
{
$qry = "
@@ -13,5 +13,33 @@ class Stundensatz_model extends DB_Model
$this->pk = 'stundensatz_id';
$this->hasSequence = true;
}
public function getStundensatzByDatum($uid, $beginn, $ende = null, $typ = null)
{
$qry = "SELECT
*
FROM
hr.tbl_stundensatz
WHERE
uid = ?
AND (gueltig_bis >= ? OR gueltig_bis is null)";
$params = array($uid, $beginn);
if (!is_null($ende))
{
$qry .= " AND (gueltig_von <= ?)";
$params[] = $ende;
}
if (!is_null($typ))
{
$qry .= " AND stundensatztyp = ?";
$params[] = $typ;
}
$qry .= " ORDER BY gueltig_bis DESC NULLS FIRST, gueltig_von DESC NULLS LAST LIMIT 1;";
return $this->execQuery($qry, $params);
}
}
@@ -0,0 +1,14 @@
<?php
class Notiztyp_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'public.tbl_notiz_typ';
$this->pk = 'typ_kurzbz';
}
}
@@ -11,4 +11,19 @@ class Sprache_model extends DB_Model
$this->dbTable = 'public.tbl_sprache';
$this->pk = 'sprache';
}
/**
* @param array $sprachen
*
* @return stdClass
*/
public function loadMultiple($sprachen)
{
$this->db->where_in('sprache', $sprachen);
$this->addOrder('index');
return $this->load();
}
}
@@ -66,6 +66,15 @@ class Variable_model extends DB_Model
}
}
}
if (!isset($vardata['emailadressentrennzeichen']))
{
$vardata['emailadressentrennzeichen'] =
(defined('DEFAULT_EMAILADRESSENTRENNZEICHEN'))
? DEFAULT_EMAILADRESSENTRENNZEICHEN
: ',';
}
$result = success($vardata);
}
@@ -0,0 +1,11 @@
<?php if ($obj->aktiv) { ?>
<uid><![CDATA[ <?= $obj->uid; ?>]]></uid>
<name><![CDATA[ <?= $obj->titelpre . ' ' . $obj->vorname . ' ' . $obj->nachname . ' ' . $obj->titelpost; ?>]]></name>
<email><![CDATA[<?= $obj->alias ?: $obj->uid; ?>@<?= DOMAIN; ?>]]></email>
<?php if ($obj->telefonklappe !== null) { ?>
<telefon><![CDATA[<?= $obj->kontakt ?: ''; ?> - <?= $obj->telefonklappe; ?>]]></telefon>
<?php } ?>
<?php if ($obj->planbezeichnung) { ?>
<ort><![CDATA[<?= $obj->planbezeichnung; ?>]]></ort>
<?php } ?>
<?php } ?>
@@ -0,0 +1,6 @@
<?php if ($obj->aktiv) { ?>
<uid><![CDATA[ <?= $obj->uid; ?>]]></uid>
<email><![CDATA[<?= $obj->uid; ?>@<?= DOMAIN; ?>]]></email>
<name><![CDATA[ <?= $obj->titelpre . ' ' . $obj->vorname . ' ' . $obj->nachname . ' ' . $obj->titelpost; ?><?php if ($obj->bezeichnung != '' && $obj->bezeichnung != $obj->beschreibung) echo ' (' . $obj->bezeichnung . ')'; ?>]]></name>
<?php } ?>
@@ -0,0 +1,46 @@
<stg_extras>
<stg_kz><?= $studiengang->studiengang_kz; ?></stg_kz>
<stg_ltg_name><![CDATA[<?= $this->p->t('global', 'studiengangsleitung'); ?>]]></stg_ltg_name>';
<?php foreach ($stg_ltg as $item) { ?>
<stg_ltg> <?php $this->view('Cis/Cms/News/Xml/Address/Detailed', ['obj' => $item]); ?></stg_ltg>
<?php } ?>
<gf_ltg_name><![CDATA[<?= $this->p->t('global', 'geschaeftsfuehrendeltg'); ?>]]></gf_ltg_name>';
<?php foreach ($gf_ltg as $item) { ?>
<gf_ltg> <?php $this->view('Cis/Cms/News/Xml/Address/Detailed', ['obj' => $item]); ?></gf_ltg>
<?php } ?>
<stv_ltg_name><![CDATA[<?= $this->p->t('global', 'stellvertreter'); ?>]]></stv_ltg_name>';
<?php foreach ($stv_ltg as $item) { ?>
<stv_ltg> <?php $this->view('Cis/Cms/News/Xml/Address/Detailed', ['obj' => $item]); ?></stv_ltg>
<?php } ?>
<ass_name><![CDATA[<?= $this->p->t('global', 'sekretariat'); ?>]]></ass_name>';
<?php foreach ($ass as $item) { ?>
<ass> <?php $this->view('Cis/Cms/News/Xml/Address/Detailed', ['obj' => $item]); ?></ass>
<?php } ?>
<zusatzinfo><![CDATA[<?= $studiengang->zusatzinfo_html; ?>]]></zusatzinfo>
<hochschulvertr_name><![CDATA[<?= $this->p->t('global', 'hochschulvertretung'); ?>]]></hochschulvertr_name>';
<?php foreach ($hochschulvertr as $item) { ?>
<hochschulvertr> <?php $this->view('Cis/Cms/News/Xml/Address/Short', ['obj' => $item]); ?></hochschulvertr>
<?php } ?>
<stdv_name><![CDATA[<?= $this->p->t('global', 'studentenvertreter'); ?> <?= strtoupper($studiengang->oe_kurzbz); ?>]]></stdv_name>';
<?php foreach ($stdv as $item) { ?>
<stdv> <?php $this->view('Cis/Cms/News/Xml/Address/Short', ['obj' => $item]); ?></stdv>
<?php } ?>
<jahrgangsvertr_name><![CDATA[<?= $this->p->t('global', 'jahrgangsvertretung'); ?><?= $semester; ?> <?= $this->p->t('global', 'semester'); ?>]]></jahrgangsvertr_name>';
<?php foreach ($jahrgangsvertr as $item) { ?>
<jahrgangsvertr> <?php $this->view('Cis/Cms/News/Xml/Address/Short', ['obj' => $item]); ?></jahrgangsvertr>
<?php } ?>
<?php if (defined("CIS_EXT_MENU") && CIS_EXT_MENU) { ?>
<cis_ext_menu>
<download_name><![CDATA[<?= $this->p->t('global', 'allgemeinerdownload'); ?>]]></download_name>
<kurzbz><![CDATA[<?= strtolower($studiengang->typ . $studiengang->kurzbz); ?>]]></kurzbz>
<kurzbzlang><![CDATA[<?= strtolower($studiengang->kurzbzlang); ?>]]></kurzbzlang>
<stg_kz><![CDATA[<?= $studiengang->studiengang_kz; ?>]]></stg_kz>
</cis_ext_menu>';
<?php } ?>
</stg_extras>
+212
View File
@@ -0,0 +1,212 @@
<?php
$includesArray = array(
'title' => 'Documents',
'tabulator5' => true,
'customJSModules' => ['public/js/apps/Cis/Documents.js']
);
$this->load->view('templates/CISVUE-Header', $includesArray);
?>
<div id="content">
<div class="fhc-header">
<h1><?= $this->p->t('tools', 'dokumente'); ?><small><?= $this->p->t('tools', 'bestaetigungenZeugnisse'); ?></small></h1>
</div>
<div class="row">
<div class="order-2 col-lg-8">
<div class="fhc-table mb-3">
<div class="fhc-table-header d-flex align-items-center mb-2 gap-2">
<h3 class="h5 col m-0"><?= $this->p->t('tools', 'inskriptionsbestaetigung'); ?><?= $studienbuchblatt ? ' & ' . $this->p->t('tools', 'studienbuchblatt') : ''; ?></h3>
<?php if (count($stgs) != 1) { ?>
<div class="col-auto">
<select class="form-select" @input="changeFilter('inscriptiontable', 'Stg', $event)">
<option value="">Alle</option>
<?php foreach ($stgs as $stg) { ?>
<option value="<?= $stg->bezeichnung; ?>">
<?= $stg->bezeichnung; ?>
</option>
<?php } ?>
</select>
</div>
<?php } ?>
<div class="col-auto">
<select class="form-select" @input="changeFilter('inscriptiontable', 'Stsem', $event)">
<option value="">Alle</option>
<?php foreach ($stsemArray as $sem) { ?>
<option value="<?= $sem; ?>">
<?= $sem; ?>
</option>
<?php } ?>
</select>
</div>
</div>
<table ref="inscriptiontable">
<thead>
<tr>
<th tabulator-formatter="html">Dokument</th>
<?php if (count($stgs) != 1) { ?>
<th tabulator-field="Stg">Studiengang</th>
<?php } ?>
<th tabulator-field="Stsem">Studiensemester</th>
</tr>
</thead>
<tbody>
<?php foreach ($stgs as $stg) { ?>
<?php foreach ($stg->studiensemester as $stsem => $sem) { ?>
<?php if (true && $sem->inskriptionsbestaetigung) { ?>
<tr>
<td>
<a class="text-decoration-none" target="_blank" href="<?= base_url('cis/private/pdfExport.php?xsl=Inskription&xml=student.rdf.php&ss=' . $stsem . '&uid=' . $uid . '&xsl_stg_kz=' . $stg->studiengang_kz); ?>">
<img class="align-baseline" src="<?= base_url('skin/images/pdfpic.gif'); ?>" alt="PDF"> <?= $this->p->t('tools', 'inskriptionsbestaetigung'); ?>
</a>
</td>
<?php if (count($stgs) != 1) { ?>
<td><?= $stg->bezeichnung; ?></td>
<?php } ?>
<td><?= $stsem; ?></td>
</tr>
<?php if ($studienbuchblatt) { ?>
<tr>
<td>
<a class="text-decoration-none" target="_blank" href="<?= base_url('cis/private/pdfExport.php?xsl=Studienblatt&xml=studienblatt.xml.php&ss=' . $stsem . '&uid=' . $uid); ?>">
<img class="align-baseline" src="<?= base_url('skin/images/pdfpic.gif'); ?>" alt="PDF"> <?= $this->p->t('tools', 'studienbuchblatt'); ?>
</a>
</td>
<?php if (count($stgs) != 1) { ?>
<td><?= $stg->bezeichnung; ?></td>
<?php } ?>
<td><?= $stsem; ?></td>
</tr>
<?php } ?>
<?php } ?>
<?php } ?>
<?php } ?>
</tbody>
</table>
</div>
<?php if ($studienerfolgsbestaetigung) { ?>
<div class="fhc-table mb-3">
<div class="fhc-table-header d-flex align-items-center mb-2 gap-2">
<h3 class="h5 col m-0"><?= $this->p->t('tools', 'studienerfolgsbestaetigung'); ?></h3>
<?php if (count($stgs) != 1) { ?>
<div class="col-auto">
<select class="form-select" @input="changeFilter('studienerfolgsbestaetigungtable', 'Stg', $event)">
<option value="">Alle</option>
<?php foreach ($stgs as $stg) { ?>
<option value="<?= $stg->bezeichnung; ?>">
<?= $stg->bezeichnung; ?>
</option>
<?php } ?>
</select>
</div>
<?php } ?>
<div class="col-auto">
<select class="form-select" @input="changeFilter('studienerfolgsbestaetigungtable', 'Stsem', $event)">
<option value="<?= $this->p->t('tools', 'alleStudiensemester'); ?>"><?= $this->p->t('tools', 'alleStudiensemester'); ?></option>
<?php foreach ($stsemArray as $sem) { ?>
<option value="<?= $sem; ?>">
<?= $sem; ?>
</option>
<?php } ?>
</select>
</div>
<div class="col-auto">
<select class="form-select" @input="changeFilter('studienerfolgsbestaetigungtable', 'Lang', $event)">
<option value="">Alle</option>
<option value="<?= $this->p->t('global', 'deutsch'); ?>"><?= $this->p->t('global', 'deutsch'); ?></option>
<option value="<?= $this->p->t('global', 'englisch'); ?>"><?= $this->p->t('global', 'englisch'); ?></option>
</select>
</div>
</div>
<table ref="studienerfolgsbestaetigungtable">
<thead>
<tr>
<th tabulator-formatter="html">Dokument</th>
<?php if (count($stgs) != 1) { ?>
<th tabulator-field="Stg">Studiengang</th>
<?php } ?>
<th tabulator-field="Stsem">Studiensemester</th>
<th tabulator-field="Lang">Sprache</th>
<th tabulator-field="Finance" tabulator-formatter="tickCross"><?= $this->p->t('tools', 'vorlageWohnsitzfinanzamt'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach (['Studienerfolg' => $this->p->t('global', 'deutsch'), 'StudienerfolgEng' => $this->p->t('global', 'englisch')] as $lang_xsl => $lang) { ?>
<?php foreach ([true, false] as $finance) { ?>
<?php foreach ($stgs as $stg) { ?>
<tr>
<td>
<a class="text-decoration-none" target="_blank" href="<?= base_url('cis/private/pdfExport.php?xsl=' . $lang_xsl . '&xml=studienerfolg.rdf.php&ss=alle&all=1&uid=' . $uid . ($finance ? '&typ=finanzamt' : '')); ?>">
<img class="align-baseline" src="<?= base_url('skin/images/pdfpic.gif'); ?>" alt="PDF"> <?= $this->p->t('tools', 'studienerfolgsbestaetigung'); ?>
</a>
</td>
<?php if (count($stgs) != 1) { ?>
<td><?= $stg->bezeichnung; ?></td>
<?php } ?>
<td><?= $this->p->t('tools', 'alleStudiensemester'); ?></td>
<td><?= $lang; ?></td>
<td><?= $finance; ?></td>
</tr>
<?php foreach ($stg->studiensemester as $stsem => $sem) { ?>
<tr>
<td>
<a class="text-decoration-none" target="_blank" href="<?= base_url('cis/private/pdfExport.php?xsl=' . $lang_xsl . '&xml=studienerfolg.rdf.php&ss=' . $stsem . '&uid=' . $uid . ($finance ? '&typ=finanzamt' : '')); ?>">
<img class="align-baseline" src="<?= base_url('skin/images/pdfpic.gif'); ?>" alt="PDF"> <?= $this->p->t('tools', 'studienerfolgsbestaetigung'); ?>
</a>
</td>
<?php if (count($stgs) != 1) { ?>
<td><?= $stg->bezeichnung; ?></td>
<?php } ?>
<td><?= $stsem; ?></td>
<td><?= $lang; ?></td>
<td><?= $finance; ?></td>
</tr>
<?php } ?>
<?php } ?>
<?php } ?>
<?php } ?>
</tbody>
</table>
</div>
<?php } ?>
<?php if ($selfservice !== null) { ?>
<div class="fhc-table mb-3">
<div class="fhc-table-header d-flex align-items-center mb-2 gap-2">
<h3 class="h5 col m-0"><?= $this->p->t('tools', 'abschlussdokumente'); ?></h3>
</div>
<table ref="abschlussdokumentetable">
<thead>
<tr>
<th tabulator-formatter="html">Dokument</th>
<th tabulator-field="Date">Datum</th>
</tr>
</thead>
<tbody>
<?php foreach ($selfservice as $row) { ?>
<tr>
<td>
<a class="text-decoration-none" target="_blank" href="<?= site_url('Cis/Documents/download/' . $row->akte_id . ($row->person_id != getAuthPersonId() ? '/' . $uid : '')); ?>">
<img class="align-baseline" src="<?= base_url('skin/images/pdfpic.gif'); ?>" alt="PDF"> <?= $row->bezeichnung; ?>
</a>
<td><?= (new DateTime($row->erstelltam))->format('d.m.Y'); ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<?php } ?>
</div>
<?php if ($selfservice) { ?>
<div class="order-1 order-lg-3 col-lg-4">
<div class="alert alert-warning" role="alert">
<?= $this->p->t('tools', 'warnungDruckDigitaleSignatur'); ?>
</div>
</div>
<?php } ?>
</div>
</div>
<?php $this->load->view('templates/CISVUE-Footer', $includesArray); ?>

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