diff --git a/application/controllers/Cis/MyLv.php b/application/controllers/Cis/MyLv.php index 49a938553..819d56b05 100644 --- a/application/controllers/Cis/MyLv.php +++ b/application/controllers/Cis/MyLv.php @@ -33,9 +33,4 @@ class MyLv extends Auth_Controller $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'MyLv']); } - - public function Info($studien_semester,$lvid) - { - $this->load->view('Cis/LvInfo',['lvid'=> $lvid, 'studien_semester' => $studien_semester]); - } } diff --git a/application/helpers/hlp_header_helper.php b/application/helpers/hlp_header_helper.php index 41d40ca0d..27dfba5a1 100644 --- a/application/helpers/hlp_header_helper.php +++ b/application/helpers/hlp_header_helper.php @@ -269,3 +269,199 @@ function absoluteJsImportUrl($relurl) } return $url; } + +/* + * Manipulate CI views includes Array to load + * - public/js/FhcApps.js via customJSs and + * - app customisation js and/or css from extensions via customJSModules + * if customJSModules contains at least one vuejs app and customisation files + * exist in extensions + */ +class ExtendableAppsHelper +{ + private static $instance = null; + + protected $extensions; + + protected $customCSSs; + protected $customJSs; + protected $customJSModules; + + protected $initialised; + protected $appscount; + + protected $extCustomCSSs; + protected $extCustomJSs; + protected $extCustomJSModules; + + private function __construct() + { + $this->extensions = array(); + $this->customCSSs = null; + $this->customJSs = null; + $this->customJSModules = null; + + $this->initialised = false; + $this->appscount = 0; + + $this->extCustomCSSs = null; + $this->extCustomJSs = null; + $this->extCustomJSModules = null; + } + + public static function getInstance() + { + if(self::$instance === null) + { + self::$instance = new ExtendableAppsHelper(); + } + return self::$instance; + } + + public function init($customCSSs, $customJSs, $customJSModules) + { + if($this->initialised) + { + return; + } + + $this->customCSSs = $customCSSs; + $this->customJSs = $customJSs; + $this->customJSModules = $customJSModules; + $this->initialised = true; + + if(!isset($this->customJSModules)) + { + return; + } + + if(!is_array($this->customJSModules)) + { + $this->customJSModules = array($this->customJSModules); + } + + if(count($this->customJSModules) < 1) + { + return; + } + + $this->buildExtensionsList(); + $this->prepareExtendedArrays(); + } + + public function getCustomCSSs() + { + if(is_null($this->extCustomCSSs)) + { + return $this->customCSSs; + } + return $this->extCustomCSSs; + } + + public function getCustomJSs() + { + if(is_null($this->extCustomJSs)) + { + return $this->customJSs; + } + return $this->extCustomJSs; + } + + public function getCustomJSModules() + { + if(is_null($this->extCustomJSModules)) + { + return $this->customJSModules; + } + return $this->extCustomJSModules; + } + + protected function buildExtensionsList() + { + $this->extensions = array(); + $fsiterator = new FilesystemIterator(FHCPATH . 'application/extensions'); + foreach ($fsiterator as $fsitem) + { + if(preg_match('/^FHC-Core-/', $fsitem->getBasename())) + { + $this->extensions[] = $fsitem->getBasename(); + } + } + } + + protected function prepareExtendedArrays() + { + $this->appscount = 0; + $this->initExtCustomCSSs(); + $this->extCustomJSModules = array(); + foreach($this->customJSModules as $item) + { + $matches = array(); + if(preg_match('#^public/(extensions/FHC-Core-.+)?js/apps/(.*)\.js$#', $item, $matches)) + { + $this->appscount++; + + $fhcextension = $matches[1]; + $app = $matches[2]; + + $extend_js_suffix = 'js/extend_app/' . $fhcextension . $app . '.js'; + $extend_css_suffix = 'css/extend_app/' . $fhcextension . $app . '.css'; + + foreach($this->extensions as $extension) + { + $extend_js = 'public/extensions/' . $extension . '/' . $extend_js_suffix; + $extend_css = 'public/extensions/' . $extension . '/' . $extend_css_suffix; + + if(is_readable(FHCPATH . $extend_js)) + { + array_push($this->extCustomJSModules, $extend_js); + } + + if(is_readable(FHCPATH . $extend_css)) + { + array_push($this->extCustomCSSs, $extend_css); + } + } + } + array_push($this->extCustomJSModules, $item); + } + + if($this->appscount > 0) + { + $this->addFhcAppsJs(); + } + } + + protected function initExtCustomCSSs() + { + if(!isset($this->customCSSs)) + { + $this->extCustomCSSs = array(); + } + elseif(!is_array($this->customCSSs)) + { + $this->extCustomCSSs = array($this->customCSSs); + } + else + { + $this->extCustomCSSs = $this->customCSSs; + } + } + + protected function addFhcAppsJs() + { + if(!isset($this->customJSs)) + { + $this->extCustomJSs = array(); + } + elseif(!is_array($this->customJSs)) + { + $this->extCustomJSs = array($this->customJSs); + } + else + { + $this->extCustomJSs = $this->customJSs; + } + array_push($this->extCustomJSs, 'public/js/FhcApps.js'); + } +} diff --git a/application/views/Cis/LvInfo.php b/application/views/Cis/LvInfo.php deleted file mode 100644 index 49a7b7a85..000000000 --- a/application/views/Cis/LvInfo.php +++ /dev/null @@ -1,15 +0,0 @@ - 'LvInfo', - 'customJSModules' => ['public/js/apps/Cis/LvInfo.js'] -); - -$this->load->view('templates/CISVUE-Header', $includesArray); -?> - -
- - -
- -load->view('templates/CISVUE-Footer', $includesArray); ?> diff --git a/application/views/Cis/Profil.php b/application/views/Cis/Profil.php deleted file mode 100644 index f66ebf8a9..000000000 --- a/application/views/Cis/Profil.php +++ /dev/null @@ -1,18 +0,0 @@ - 'Profil', - 'customJSModules' => ['public/js/apps/Cis/Profil.js'], - 'tabulator5' => true, - 'primevue3' => true, - 'customCSSs' => ['public/css/components/calendar.css', 'public/css/components/FilterComponent.css','public/css/components/Profil.css','public/css/components/FormUnderline.css'], - -); - -$this->load->view('templates/CISVUE-Header', $includesArray); -?> - -
- -
- -load->view('templates/CISVUE-Footer', $includesArray); ?> diff --git a/application/views/templates/FHC-Footer.php b/application/views/templates/FHC-Footer.php index c816ebf2e..d2eb229f1 100644 --- a/application/views/templates/FHC-Footer.php +++ b/application/views/templates/FHC-Footer.php @@ -17,6 +17,7 @@ $use_vuejs_dev_version = $this->config->item('use_vuejs_dev_version'); // By default set the parameters to null + $customCSSs = isset($customCSSs) ? $customCSSs : null; $customJSs = isset($customJSs) ? $customJSs : null; $customJSModules = isset($customJSModules) ? $customJSModules : null; @@ -191,12 +192,13 @@ // NOTE: keep it as the last but one if ($addons === true) generateAddonsJSsInclude($calledPath.'/'.$calledMethod); - - + $extapphelper = ExtendableAppsHelper::getInstance(); + $extapphelper->init($customCSSs, $customJSs, $customJSModules); + // Eventually required JS // NOTE: keep it as the latest - generateJSsInclude($customJSs); - generateJSModulesInclude($customJSModules); + generateJSsInclude($extapphelper->getCustomJSs()); + generateJSModulesInclude($extapphelper->getCustomJSModules()); ?> diff --git a/application/views/templates/FHC-Header.php b/application/views/templates/FHC-Header.php index f7b5491a1..7b53cbf5d 100644 --- a/application/views/templates/FHC-Header.php +++ b/application/views/templates/FHC-Header.php @@ -9,6 +9,8 @@ $title = isset($title) ? $title : null; $refresh = isset($refresh) ? $refresh : null; $customCSSs = isset($customCSSs) ? $customCSSs : null; + $customJSs = isset($customJSs) ? $customJSs : null; + $customJSModules = isset($customJSModules) ? $customJSModules : null; $skipID = isset($skipID) ? $skipID : null; ?> @@ -132,8 +134,11 @@ //Tags if ($tags === true) generateCSSsInclude('public/css/tags.css'); + $extapphelper = ExtendableAppsHelper::getInstance(); + $extapphelper->init($customCSSs, $customJSs, $customJSModules); + // Eventually required CSS - generateCSSsInclude($customCSSs); // Eventually required CSS + generateCSSsInclude($extapphelper->getCustomCSSs()); // Eventually required CSS ?> diff --git a/public/js/FhcApps.js b/public/js/FhcApps.js new file mode 100644 index 000000000..f9ec61001 --- /dev/null +++ b/public/js/FhcApps.js @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2025 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 . + */ + + +const FhcApps = (function() { + // Logic to extend app here (like adding components, plugins, ...) + + function makeExtendable(app) { + // apply extensions here + return app; + } + + return { + makeExtendable + }; +})(); + +FhcApps.router = (() => { + const extraRoutes = []; + + function addRoute(...route) { + extraRoutes.push(route); + } + + function makeExtendable(router) { + while (extraRoutes.length) { + router.addRoute(...extraRoutes.shift()); + } + router.replace(router.currentRoute.value.fullPath); + } + + return { + addRoute, + makeExtendable + }; +})(); diff --git a/public/js/apps/Bismeldestichtag/Bismeldestichtag.js b/public/js/apps/Bismeldestichtag/Bismeldestichtag.js index d6e5a4a27..9a9766690 100644 --- a/public/js/apps/Bismeldestichtag/Bismeldestichtag.js +++ b/public/js/apps/Bismeldestichtag/Bismeldestichtag.js @@ -237,4 +237,6 @@ const bismeldestichtagApp = Vue.createApp({ } }); +FhcApps.makeExtendable(bismeldestichtagApp); + bismeldestichtagApp.use(PluginsPhrasen).mount('#main'); diff --git a/public/js/apps/Cis.js b/public/js/apps/Cis.js index 5b76c5721..c88a47a35 100644 --- a/public/js/apps/Cis.js +++ b/public/js/apps/Cis.js @@ -142,6 +142,9 @@ const app = Vue.createApp({ } } }); + +FhcApps.makeExtendable(app); + app.use(primevue.config.default, { zIndex: { overlay: 9000, diff --git a/public/js/apps/Cis/Documents.js b/public/js/apps/Cis/Documents.js index de03769b4..149a32446 100644 --- a/public/js/apps/Cis/Documents.js +++ b/public/js/apps/Cis/Documents.js @@ -87,6 +87,8 @@ const app = Vue.createApp({ } }); +FhcApps.makeExtendable(app); + setScrollbarWidth(); app.use(PluginsPhrasen); diff --git a/public/js/apps/Cis/ProfilUpdateRequests.js b/public/js/apps/Cis/ProfilUpdateRequests.js index 68465b202..974b2c362 100644 --- a/public/js/apps/Cis/ProfilUpdateRequests.js +++ b/public/js/apps/Cis/ProfilUpdateRequests.js @@ -34,4 +34,7 @@ const app = Vue.createApp({ }); }, }); + +FhcApps.makeExtendable(app); + app.use(PluginsPhrasen).mount("#content"); \ No newline at end of file diff --git a/public/js/apps/Dashboard/Fhc.js b/public/js/apps/Dashboard/Fhc.js index 540a74f06..140c76402 100644 --- a/public/js/apps/Dashboard/Fhc.js +++ b/public/js/apps/Dashboard/Fhc.js @@ -334,6 +334,10 @@ const app = Vue.createApp({ // kind of a bandaid for bad css on some pages to avoid horizontal scroll setScrollbarWidth(); app.config.globalProperties.$capitalize = capitalize; + +FhcApps.router.makeExtendable(router); +FhcApps.makeExtendable(app); + app.use(router); app.use(primevue.config.default, { zIndex: { diff --git a/public/js/apps/LVVerwaltung.js b/public/js/apps/LVVerwaltung.js index f365b74a8..18f8a072f 100644 --- a/public/js/apps/LVVerwaltung.js +++ b/public/js/apps/LVVerwaltung.js @@ -89,8 +89,12 @@ const router = VueRouter.createRouter({ ] }); +FhcApps.router.makeExtendable(router); + const app = Vue.createApp(); +FhcApps.makeExtendable(app); + app .use(router) .use(primevue.config.default, { diff --git a/public/js/apps/LogsViewer/LogsViewer.js b/public/js/apps/LogsViewer/LogsViewer.js index eeb4b38a7..ad377a369 100644 --- a/public/js/apps/LogsViewer/LogsViewer.js +++ b/public/js/apps/LogsViewer/LogsViewer.js @@ -42,5 +42,7 @@ const logsViewerApp = Vue.createApp({ } }); +FhcApps.makeExtendable(logsViewerApp); + logsViewerApp.use(PluginsPhrasen).mount('#main'); diff --git a/public/js/apps/Studentenverwaltung.js b/public/js/apps/Studentenverwaltung.js index e6f77d5f5..47490bfdd 100644 --- a/public/js/apps/Studentenverwaltung.js +++ b/public/js/apps/Studentenverwaltung.js @@ -206,10 +206,14 @@ router.afterEach((to, from, failure) => { document.title = title; }); +FhcApps.router.makeExtendable(router); + const app = Vue.createApp({ name: 'StudentenverwaltungApp' }); +FhcApps.makeExtendable(app); + app .use(router) .use(primevue.config.default, { diff --git a/public/js/apps/lehre/Antrag.js b/public/js/apps/lehre/Antrag.js index 97b4bda97..afdfe48ab 100644 --- a/public/js/apps/lehre/Antrag.js +++ b/public/js/apps/lehre/Antrag.js @@ -20,6 +20,9 @@ const app = Vue.createApp({ }; } }); + +FhcApps.makeExtendable(app); + app .use(PluginsPhrasen) .mount('#wrapper'); \ No newline at end of file diff --git a/public/js/apps/lehre/Antrag/Leitung.js b/public/js/apps/lehre/Antrag/Leitung.js index 8fd8b117e..c8169629a 100644 --- a/public/js/apps/lehre/Antrag/Leitung.js +++ b/public/js/apps/lehre/Antrag/Leitung.js @@ -7,6 +7,9 @@ const app = Vue.createApp({ StudierendenantragLeitung } }); + +FhcApps.makeExtendable(app); + app .use(PluginsPhrasen) .use(primevue.config.default,{zIndex: {overlay: 9999}}) diff --git a/public/js/apps/lehre/Antrag/Lvzuweisung.js b/public/js/apps/lehre/Antrag/Lvzuweisung.js index 7504e7dcf..f85a52f62 100644 --- a/public/js/apps/lehre/Antrag/Lvzuweisung.js +++ b/public/js/apps/lehre/Antrag/Lvzuweisung.js @@ -12,6 +12,9 @@ const app = Vue.createApp({ } } }); + +FhcApps.makeExtendable(app); + app .use(PluginsPhrasen) .mount('#wrapper'); \ No newline at end of file diff --git a/public/js/apps/lehre/Antrag/Student.js b/public/js/apps/lehre/Antrag/Student.js index 46150c541..7d40f4339 100644 --- a/public/js/apps/lehre/Antrag/Student.js +++ b/public/js/apps/lehre/Antrag/Student.js @@ -7,6 +7,9 @@ const app = Vue.createApp({ LvPopup } }); + +FhcApps.makeExtendable(app); + app .use(PluginsPhrasen) .mount('#wrapper'); \ No newline at end of file diff --git a/public/js/apps/lehre/lvplanung/LvTemplates.js b/public/js/apps/lehre/lvplanung/LvTemplates.js index 655d611ce..b19b1f730 100644 --- a/public/js/apps/lehre/lvplanung/LvTemplates.js +++ b/public/js/apps/lehre/lvplanung/LvTemplates.js @@ -28,6 +28,8 @@ const lvTemplatesApp = Vue.createApp({ } }); +FhcApps.makeExtendable(lvTemplatesApp); + lvTemplatesApp .use(primevue.config.default,{zIndex: {overlay: 9999}}) .use(PluginsPhrasen)