mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-25 16:44:28 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
290d617e0f | ||
|
|
01ea24f5bd | ||
|
|
16b649c951 | ||
|
|
8a567416db | ||
|
|
a3dffd1fc2 | ||
|
|
2460253c19 | ||
|
|
62ad0dcd47 | ||
|
|
9355ee740d | ||
|
|
2484bf1217 |
@@ -1,11 +1,27 @@
|
||||
<?php
|
||||
// Header menu
|
||||
/**
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if(defined('CIS4') && CIS4) {
|
||||
$root = APP_ROOT;
|
||||
} else {
|
||||
$root = CIS_ROOT;
|
||||
}
|
||||
$root = CIS_ROOT;
|
||||
|
||||
if (defined('CIS4') && CIS4) $root = APP_ROOT;
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// Head menu
|
||||
|
||||
$config['navigation_header'] = array(
|
||||
'*' => array(
|
||||
@@ -202,13 +218,20 @@ $config['navigation_header'] = array(
|
||||
'sort' => 20,
|
||||
'requiredPermissions' => 'system/developer:r'
|
||||
),
|
||||
'anrechnungen' => array(
|
||||
'link' => site_url('lehre/anrechnung/AdminAnrechnung'),
|
||||
'description' => 'Anrechnungen',
|
||||
'expand' => true,
|
||||
'sort' => 30,
|
||||
'requiredPermissions' => 'lehre/anrechnungszeitfenster:rw'
|
||||
),
|
||||
'anrechnungen' => array(
|
||||
'link' => site_url('lehre/anrechnung/AdminAnrechnung'),
|
||||
'description' => 'Anrechnungen',
|
||||
'expand' => true,
|
||||
'sort' => 30,
|
||||
'requiredPermissions' => 'lehre/anrechnungszeitfenster:rw'
|
||||
),
|
||||
'loginas' => array(
|
||||
'link' => site_url('system/Login/loginAs'),
|
||||
'description' => 'Login as',
|
||||
'expand' => true,
|
||||
'sort' => 40,
|
||||
'requiredPermissions' => 'admin:rw'
|
||||
),
|
||||
'dashboardadmin' => array(
|
||||
'link' => site_url('dashboard/Admin'),
|
||||
'description' => 'Dashboard Admin',
|
||||
@@ -236,12 +259,12 @@ $config['navigation_menu']['Vilesci/index'] = array(
|
||||
);
|
||||
|
||||
$config['navigation_menu']['Vilesci/index'] = array(
|
||||
'dashboard' => array(
|
||||
'link' => '#',
|
||||
'description' => 'Dashboard',
|
||||
'icon' => 'dashboard',
|
||||
'sort' => 1
|
||||
)
|
||||
'dashboard' => array(
|
||||
'link' => '#',
|
||||
'description' => 'Dashboard',
|
||||
'icon' => 'dashboard',
|
||||
'sort' => 1
|
||||
)
|
||||
);
|
||||
|
||||
$config['navigation_menu']['organisation/Reihungstest/index'] = array(
|
||||
@@ -383,3 +406,4 @@ $config['navigation_menu']['apps'] = [
|
||||
'requiredPermissions' => array('lehre/lehrauftrag_bestellen:r', 'lehre/lehrauftrag_erteilen:r')
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Login extends FHCAPI_Controller
|
||||
{
|
||||
/**
|
||||
* Object initialization
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(array(
|
||||
'loginLDAP' => self::PERM_ANONYMOUS,
|
||||
'loginASByUid' => 'admin:rw',
|
||||
'loginASByPersonId' => 'admin:rw',
|
||||
'whoAmI' => self::PERM_ANONYMOUS,
|
||||
'searchUser' => 'admin:rw'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called with HTTP POST via ajax to login using the LDAP authentication
|
||||
*/
|
||||
public function loginLDAP()
|
||||
{
|
||||
$username = $this->input->post('username');
|
||||
$password = $this->input->post('password');
|
||||
|
||||
$this->load->library('AuthLib', array(false)); // without authentication otherwise loooooop!
|
||||
|
||||
$login = $this->authlib->loginLDAP($username, $password);
|
||||
|
||||
// If login is success then retrieves the desired page
|
||||
if (isSuccess($login)) $this->terminateWithSuccess($this->authlib->getLandingPage());
|
||||
|
||||
$this->terminateWithError(getError($login)); // returns the error code
|
||||
}
|
||||
|
||||
/**
|
||||
* Called with HTTP POST via ajax to login as another user specified by uid
|
||||
*/
|
||||
public function loginASByUid()
|
||||
{
|
||||
$uid = $this->input->post('uid');
|
||||
|
||||
// With authentication -> you must be already logged to gain another identity
|
||||
$this->load->library('AuthLib');
|
||||
|
||||
$loginAS = $this->authlib->loginASByUID($uid);
|
||||
|
||||
// Got it!
|
||||
if (isSuccess($loginAS)) $this->terminateWithSuccess(true);
|
||||
|
||||
// Returns the error code
|
||||
$this->terminateWithError(getError($loginAS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called with HTTP POST via ajax to login as another user specified by person id
|
||||
*/
|
||||
public function loginASByPersonId()
|
||||
{
|
||||
$person_id = $this->input->post('person_id');
|
||||
|
||||
// With authentication -> you must be already logged to gain another identity
|
||||
$this->load->library('AuthLib');
|
||||
|
||||
$loginAS = $this->authlib->loginASByPersonId($person_id);
|
||||
|
||||
// Got it!
|
||||
if (isSuccess($loginAS)) $this->terminateWithSuccess(true);
|
||||
|
||||
// Returns the error code
|
||||
$this->terminateWithError(getError($loginAS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called with HTTP GET via ajax to show which login cretentials are in use
|
||||
*/
|
||||
public function whoAmI()
|
||||
{
|
||||
// With authentication -> you must be already logged to gain another identity
|
||||
$this->load->library('AuthLib');
|
||||
|
||||
$this->terminateWithSuccess($this->authlib->getAuthObj());
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a user in database checking the name, surname or uid
|
||||
*/
|
||||
public function searchUser()
|
||||
{
|
||||
$query = strtolower('%'.$this->input->get('query').'%');
|
||||
|
||||
$this->load->model('person/Benutzer_model', 'BenutzerModel');
|
||||
|
||||
$dataset = $this->BenutzerModel->execReadOnlyQuery('
|
||||
SELECT p.person_id,
|
||||
b.uid,
|
||||
p.nachname,
|
||||
p.vorname,
|
||||
b.uid,
|
||||
p.person_id || \' - \' || b.uid || \' - \' || p.nachname || \' \' || p.vorname AS label
|
||||
FROM public.tbl_person p
|
||||
LEFT JOIN public.tbl_benutzer b ON(b.person_id = p.person_id)
|
||||
WHERE b.aktiv = TRUE
|
||||
AND (p.nachname ILIKE ? OR p.vorname ILIKE ? OR b.uid ILIKE ? OR p.person_id::text LIKE ?)
|
||||
ORDER BY p.nachname, p.vorname
|
||||
',
|
||||
array($query, $query, $query, $query)
|
||||
);
|
||||
|
||||
if (isError($dataset)) $this->terminateWithError(getError($dataset));
|
||||
|
||||
$this->terminateWithSuccess($dataset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
<?php
|
||||
/* Copyright (C) 2024 fhcomplete.net
|
||||
*
|
||||
* 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined("BASEPATH")) exit("No direct script access allowed");
|
||||
|
||||
class Modulgrafik extends JOB_Controller
|
||||
{
|
||||
const DEFAULT_XOFFSET = 40;
|
||||
const DEFAULT_YOFFSET = 30;
|
||||
const DEFAULT_WIDTH = 160;
|
||||
const DEFAULT_SEMESTER_LABEL_WIDTH = 80;
|
||||
const DEFAULT_ECTS_WIDTH = 40;
|
||||
const DEFAULT_HEIGHT = 50;
|
||||
const DEFAULT_SPACING = 40;
|
||||
const DEFAULT_FONTSIZE = 8;
|
||||
|
||||
protected $curx;
|
||||
protected $cury;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
|
||||
|
||||
$this->load->model('CL/Drawio_model', 'DrawioModel');
|
||||
|
||||
$this->load->library('DocsboxLib', null, 'DocsboxLib');
|
||||
}
|
||||
|
||||
public function drawModulGrafik($studienplan_id)
|
||||
{
|
||||
$sql = <<<EOSQL
|
||||
SELECT
|
||||
sl.studienplan_lehrveranstaltung_id,
|
||||
sl.lehrveranstaltung_id,
|
||||
sl.studienplan_lehrveranstaltung_id_parent,
|
||||
COALESCE(sl.studienplan_lehrveranstaltung_id_parent, sl.studienplan_lehrveranstaltung_id) AS lvgrp,
|
||||
sl.semester,
|
||||
lv.bezeichnung,
|
||||
lv.ects,
|
||||
lv.lehrtyp_kurzbz
|
||||
FROM
|
||||
lehre.tbl_studienplan_lehrveranstaltung sl
|
||||
JOIN
|
||||
lehre.tbl_lehrveranstaltung lv USING(lehrveranstaltung_id)
|
||||
WHERE
|
||||
sl.studienplan_id = {$studienplan_id}
|
||||
AND
|
||||
ects > '0.00'
|
||||
ORDER BY
|
||||
sl.semester ASC,
|
||||
lvgrp ASC,
|
||||
lv.lehrtyp_kurzbz DESC
|
||||
EOSQL;
|
||||
|
||||
$result = $this->StudienplanModel->execReadOnlyQuery($sql);
|
||||
$lvs = getData($result);
|
||||
|
||||
$errors = array();
|
||||
$assoclvs = array();
|
||||
$semester = array();
|
||||
if($lvs)
|
||||
{
|
||||
ob_start();
|
||||
|
||||
foreach($lvs as &$lv)
|
||||
{
|
||||
if( !isset($semester[$lv->semester]) ) {
|
||||
$semester[$lv->semester] = array();
|
||||
}
|
||||
$lv->parent = null;
|
||||
$lv->childs = array();
|
||||
$assoclvs[$lv->studienplan_lehrveranstaltung_id] = $lv;
|
||||
}
|
||||
|
||||
foreach($assoclvs as &$assoclv)
|
||||
{
|
||||
if( $assoclv->studienplan_lehrveranstaltung_id_parent === NULL )
|
||||
{
|
||||
$semester[$assoclv->semester][] = $assoclv;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( isset($assoclvs[$assoclv->studienplan_lehrveranstaltung_id_parent]) )
|
||||
{
|
||||
$assoclv->parent = $assoclvs[$assoclv->studienplan_lehrveranstaltung_id_parent];
|
||||
$assoclvs[$assoclv->studienplan_lehrveranstaltung_id_parent]->childs[] = $assoclv;
|
||||
}
|
||||
else
|
||||
{
|
||||
$errors[] = "ERROR: Missing parent lv " . $assoclv->studienplan_lehrveranstaltung_id_parent . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function printchilds($childs, $level) {
|
||||
if( count($childs) < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($childs as $child)
|
||||
{
|
||||
echo $level . $child->bezeichnung . " (" . $child->ects . ") " . $child->lehrtyp_kurzbz . "\n";
|
||||
printchilds($child->childs, $level . "\t");
|
||||
}
|
||||
}
|
||||
|
||||
echo "<!--\n\n";
|
||||
|
||||
foreach($semester as $sem => $mods)
|
||||
{
|
||||
echo $sem . ". Semester: \n";
|
||||
foreach($mods as $mod)
|
||||
{
|
||||
$level = "\t";
|
||||
echo $level . $mod->bezeichnung . " (" . $mod->ects . ") " . $mod->lehrtyp_kurzbz . "\n";
|
||||
printchilds($mod->childs, $level . "\t");
|
||||
}
|
||||
}
|
||||
echo "-->\n\n";
|
||||
|
||||
if (count($errors) === 0)
|
||||
{
|
||||
$this->DrawioModel->renderFileStart();
|
||||
$this->maxxoffset = self::DEFAULT_XOFFSET;
|
||||
$this->DrawioModel->renderDiagramStart($studienplan_id, 'Modulgrafik');
|
||||
$this->renderSemester($semester);
|
||||
$this->DrawioModel->renderDiagramEnd();
|
||||
$this->DrawioModel->renderFileEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($errors as $error)
|
||||
{
|
||||
echo $error;
|
||||
}
|
||||
}
|
||||
|
||||
$output = ob_get_clean();
|
||||
file_put_contents(sys_get_temp_dir().'/Modulgrafik.xml', $output);
|
||||
|
||||
$ret = DocsboxLib::convert(sys_get_temp_dir().'/Modulgrafik.xml', sys_get_temp_dir().'/Modulgrafik.png', 'png');
|
||||
|
||||
echo 'File: '.sys_get_temp_dir().'/Modulgrafik.png'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "Keine LVs gefunden.\n";
|
||||
}
|
||||
}
|
||||
|
||||
protected function renderSemester($semester)
|
||||
{
|
||||
$cury = self::DEFAULT_YOFFSET;
|
||||
|
||||
foreach($semester as $sem => $mods)
|
||||
{
|
||||
$curx = self::DEFAULT_XOFFSET;
|
||||
$id = uniqid();
|
||||
$ects = 30; //TODO calc
|
||||
$this->DrawioModel->renderSemesterLabel($id, $sem, $ects, self::DEFAULT_XOFFSET, $cury, self::DEFAULT_SEMESTER_LABEL_WIDTH, self::DEFAULT_HEIGHT);
|
||||
$curx += self::DEFAULT_SEMESTER_LABEL_WIDTH + self::DEFAULT_SPACING;
|
||||
$maxmodulheight = 0;
|
||||
foreach($mods as $mod)
|
||||
{
|
||||
$modid = uniqid();
|
||||
$size = $this->DrawioModel->renderModulList($modid, $mod, $curx, $cury, self::DEFAULT_ECTS_WIDTH, self::DEFAULT_HEIGHT);
|
||||
$curx += $size->width + self::DEFAULT_SPACING;
|
||||
if( $size->height > $maxmodulheight)
|
||||
{
|
||||
$maxmodulheight = $size->height;
|
||||
}
|
||||
}
|
||||
$cury += $maxmodulheight + self::DEFAULT_SPACING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,339 +0,0 @@
|
||||
<?php
|
||||
/* Copyright (C) 2024 fhcomplete.net
|
||||
*
|
||||
* 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined("BASEPATH")) exit("No direct script access allowed");
|
||||
|
||||
class Organigramm extends JOB_Controller
|
||||
{
|
||||
const DEFAULT_XOFFSET = 40;
|
||||
const DEFAULT_YOFFSET = 30;
|
||||
const DEFAULT_WIDTH = 160;
|
||||
const DEFAULT_HEIGHT = 50;
|
||||
const DEFAULT_SPACING = 40;
|
||||
const DEFAULT_FONTSIZE = 8;
|
||||
const RENDER_CHILDS_HORIZONTAL = 1;
|
||||
const RENDER_CHILDS_VERTICAL = 2;
|
||||
|
||||
protected $maxxoffset;
|
||||
protected $donotrenderchildsoftype;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
|
||||
|
||||
$this->load->model('CL/Drawio_model', 'DrawioModel');
|
||||
|
||||
$this->load->library('DocsboxLib', null, 'DocsboxLib');
|
||||
|
||||
$this->maxxoffset = self::DEFAULT_XOFFSET;
|
||||
$this->donotrenderchildsoftype = array();
|
||||
}
|
||||
|
||||
public function getAllActiveOes()
|
||||
{
|
||||
$sql = <<<EOSQL
|
||||
SELECT
|
||||
oe.oe_kurzbz,
|
||||
CASE
|
||||
WHEN oe.oe_parent_kurzbz = 'atw' THEN 'gst'
|
||||
WHEN oe.oe_parent_kurzbz = 'etw' THEN 'gst'
|
||||
ELSE oe.oe_parent_kurzbz
|
||||
END AS oe_parent_kurzbz,
|
||||
oe.bezeichnung,
|
||||
oe.organisationseinheittyp_kurzbz,
|
||||
STRING_AGG(
|
||||
DISTINCT p.vorname || ' ' || p.nachname,
|
||||
', '
|
||||
) AS leitung_uid
|
||||
FROM
|
||||
"public"."tbl_organisationseinheit" oe
|
||||
LEFT JOIN public.tbl_benutzerfunktion bf ON bf.oe_kurzbz = oe.oe_kurzbz
|
||||
AND (
|
||||
bf.datum_bis IS NULL
|
||||
OR bf.datum_bis > NOW() :: date
|
||||
)
|
||||
AND (
|
||||
bf.funktion_kurzbz IS NULL
|
||||
OR bf.funktion_kurzbz = 'Leitung'
|
||||
)
|
||||
LEFT JOIN public.tbl_benutzer b USING(uid)
|
||||
LEFT JOIN public.tbl_person p USING(person_id)
|
||||
WHERE
|
||||
oe.aktiv = true
|
||||
AND oe.oe_kurzbz NOT IN ('betriebsrat', 'oeh', 'FUEWahl', 'atw', 'etw', 'gf20')
|
||||
GROUP BY
|
||||
oe.oe_kurzbz,
|
||||
oe.oe_parent_kurzbz,
|
||||
oe.bezeichnung,
|
||||
oe.organisationseinheittyp_kurzbz
|
||||
ORDER BY
|
||||
oe.oe_parent_kurzbz ASC NULLS FIRST,
|
||||
oe.oe_kurzbz ASC;
|
||||
EOSQL;
|
||||
|
||||
$result = $this->OrganisationseinheitModel->execReadOnlyQuery($sql);
|
||||
$oes = getData($result);
|
||||
|
||||
$errors = array();
|
||||
$assocoes = array();
|
||||
$roots = array();
|
||||
if($oes)
|
||||
{
|
||||
ob_start();
|
||||
|
||||
foreach($oes as &$oe)
|
||||
{
|
||||
$oe->parent = NULL;
|
||||
$oe->childs = array();
|
||||
$oe->renderchilds = self::RENDER_CHILDS_HORIZONTAL;
|
||||
$oe->childstorender = array();
|
||||
$oe->donotrenderchildsoftype = array();
|
||||
$assocoes[$oe->oe_kurzbz] = $oe;
|
||||
}
|
||||
|
||||
foreach($assocoes as &$assocoe)
|
||||
{
|
||||
if( $assocoe->oe_parent_kurzbz === NULL )
|
||||
{
|
||||
$roots[$assocoe->oe_kurzbz] = $assocoe;
|
||||
$assocoe->donotrenderchildsoftype = array(
|
||||
'Team',
|
||||
'Lehrgang',
|
||||
'Studiengang',
|
||||
'Kompetenzfeld',
|
||||
'Forschungsfeld',
|
||||
'Container'
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( isset($assocoes[$assocoe->oe_parent_kurzbz]) )
|
||||
{
|
||||
$assocoe->parent = $assocoes[$assocoe->oe_parent_kurzbz];
|
||||
$assocoes[$assocoe->oe_parent_kurzbz]->childs[] = $assocoe;
|
||||
|
||||
if( $assocoe->organisationseinheittyp_kurzbz === 'Fakultaet' )
|
||||
{
|
||||
$roots[$assocoe->oe_kurzbz] = $assocoe;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$errors[] = "ERROR: Missing parent oe " . $assocoe->oe_parent_kurzbz . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count($errors) === 0)
|
||||
{
|
||||
$pages = count($roots);
|
||||
$this->DrawioModel->renderFileStart($pages);
|
||||
|
||||
foreach($roots AS &$root)
|
||||
{
|
||||
$this->maxxoffset = self::DEFAULT_XOFFSET;
|
||||
$this->donotrenderchildsoftype = $root->donotrenderchildsoftype;
|
||||
$this->prepareChildsToRender($root);
|
||||
$this->DrawioModel->renderDiagramStart($root->oe_kurzbz, $root->bezeichnung);
|
||||
$this->renderOE($root, 0, 0);
|
||||
$this->DrawioModel->renderDiagramEnd();
|
||||
}
|
||||
$this->DrawioModel->renderFileEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($errors as $error)
|
||||
{
|
||||
echo $error;
|
||||
}
|
||||
}
|
||||
|
||||
$output = ob_get_clean();
|
||||
file_put_contents(sys_get_temp_dir().'/Organigramm.xml', $output);
|
||||
|
||||
$ret = DocsboxLib::convert(sys_get_temp_dir().'/Organigramm.xml', sys_get_temp_dir().'/Organigramm.png', 'png');
|
||||
|
||||
echo 'File: '.sys_get_temp_dir().'//Organigramm.png'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "Keine Oes gefunden.\n";
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareChildsToRender(&$oe)
|
||||
{
|
||||
$oe->childstorender = array();
|
||||
$oe->renderchilds = self::RENDER_CHILDS_HORIZONTAL;
|
||||
if( isset($oe->childsxoffset) )
|
||||
{
|
||||
unset($oe->childsxoffset);
|
||||
}
|
||||
|
||||
foreach($oe->childs AS &$oechild )
|
||||
{
|
||||
$this->prepareChildsToRender($oechild);
|
||||
if( !in_array($oechild->organisationseinheittyp_kurzbz, $this->donotrenderchildsoftype) )
|
||||
{
|
||||
$oe->childstorender[] = $oechild;
|
||||
}
|
||||
}
|
||||
|
||||
$nurLehrgaengeOderStudiengaengeOhneKinder = true;
|
||||
foreach($oe->childstorender AS &$oechildtorender )
|
||||
{
|
||||
if( !(count($oechildtorender->childstorender) === 0) )
|
||||
{
|
||||
$nurLehrgaengeOderStudiengaengeOhneKinder = false;
|
||||
}
|
||||
}
|
||||
|
||||
if( $nurLehrgaengeOderStudiengaengeOhneKinder && $oe->parent !== NULL )
|
||||
{
|
||||
$oe->renderchilds = self::RENDER_CHILDS_VERTICAL;
|
||||
}
|
||||
}
|
||||
|
||||
protected function renderOE($oe, $level, $parentrenderedchildcount)
|
||||
{
|
||||
$width = self::DEFAULT_WIDTH;
|
||||
$height = self::DEFAULT_HEIGHT;
|
||||
$spacing = self::DEFAULT_SPACING;
|
||||
$fontsize = self::DEFAULT_FONTSIZE;
|
||||
$nextlevel = $level + 1;
|
||||
$renderedchildcount = 0;
|
||||
|
||||
$curxoffset = $this->maxxoffset;
|
||||
|
||||
if( count($oe->childstorender) > 0 )
|
||||
{
|
||||
if( !isset($oe->childsxoffset) )
|
||||
{
|
||||
$oe->childsxoffset = (object) array(
|
||||
'min' => $curxoffset,
|
||||
'max' => $curxoffset
|
||||
);
|
||||
}
|
||||
|
||||
foreach($oe->childstorender AS $child)
|
||||
{
|
||||
$ret = $this->renderOE($child, $nextlevel, $renderedchildcount);
|
||||
$renderedchildcount++;
|
||||
if( $renderedchildcount === 1 )
|
||||
{
|
||||
$oe->childsxoffset->min = $ret->minx;
|
||||
}
|
||||
$oe->childsxoffset->max = $ret->maxx;
|
||||
}
|
||||
|
||||
if( count($oe->childstorender) === $renderedchildcount )
|
||||
{
|
||||
$curxoffset = $oe->childsxoffset->min +
|
||||
floor((($oe->childsxoffset->max - $oe->childsxoffset->min) / 2)) -
|
||||
floor((($width + $spacing) / 2));
|
||||
}
|
||||
}
|
||||
|
||||
if( $oe->parent !== null && $oe->parent->renderchilds === self::RENDER_CHILDS_VERTICAL )
|
||||
{
|
||||
$x = $curxoffset;
|
||||
$y = self::DEFAULT_YOFFSET
|
||||
+ (($level - 1) * ($height + $spacing))
|
||||
+ (($parentrenderedchildcount + 1) * ($height + floor($spacing / 2)));
|
||||
}
|
||||
else
|
||||
{
|
||||
$x = $curxoffset;
|
||||
$y = self::DEFAULT_YOFFSET + ($level * ($height + $spacing));
|
||||
}
|
||||
$bezeichnung = htmlspecialchars($oe->bezeichnung);
|
||||
$leitung = ($oe->leitung_uid !== null) ? htmlspecialchars($oe->leitung_uid) : 'N.N.';
|
||||
$fillcolors = array(
|
||||
'Team' => '#ffe6cc',
|
||||
'Abteilung' => '#e6ffcc',
|
||||
'Studiengang' => '#cce6ff',
|
||||
'Lehrgang' => '#e6ccff',
|
||||
'Fakultaet' => '#f8cecc',
|
||||
'Department' => '#fff2cc',
|
||||
'Forschungsfeld' => '#e1d5e7',
|
||||
'Kompetenzfeld' => '#f5f5f5'
|
||||
);
|
||||
$fillcolor = (isset($fillcolors[$oe->organisationseinheittyp_kurzbz])) ? $fillcolors[$oe->organisationseinheittyp_kurzbz] : '#ffffff';
|
||||
$value = <<<EOVAL
|
||||
<font style="font-size: {$fontsize}px;"><div style="">[{$oe->organisationseinheittyp_kurzbz}]</div><b style="">{$bezeichnung}</b><div>({$leitung})</div></font>" style="whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;newEdgeStyle={"edgeStyle":"elbowEdgeStyle","startArrow":"none","endArrow":"none"};fillColor={$fillcolor};
|
||||
EOVAL;
|
||||
|
||||
$this->DrawioModel->renderCell($oe->oe_kurzbz, $value, $x, $y, $width, $height);
|
||||
|
||||
if( $oe->oe_parent_kurzbz !== NULL )
|
||||
{
|
||||
$exitX = '0.5';
|
||||
$exitY = '1';
|
||||
$entryX = '0.5';
|
||||
$entryY = '0';
|
||||
$points = array();
|
||||
if( $oe->parent !== null && $oe->parent->renderchilds === self::RENDER_CHILDS_VERTICAL)
|
||||
{
|
||||
$exitX = '0';
|
||||
$exitY = '0.5';
|
||||
$entryX = '0';
|
||||
$entryY = '0.5';
|
||||
$points = array(
|
||||
(object) array(
|
||||
'x' => ($x - floor($spacing / 2)),
|
||||
'y' => ($y + floor($height / 2))
|
||||
)
|
||||
);
|
||||
}
|
||||
$this->DrawioModel->renderEdge($oe->oe_parent_kurzbz, $oe->oe_kurzbz, $exitX, $exitY, $entryX, $entryY, $points);
|
||||
}
|
||||
|
||||
if( $oe->parent !== null && $oe->parent->renderchilds === self::RENDER_CHILDS_VERTICAL )
|
||||
{
|
||||
if( count($oe->parent->childstorender) === ($parentrenderedchildcount + 1) )
|
||||
{
|
||||
if( $this->maxxoffset < ($x + $width + $spacing) )
|
||||
{
|
||||
$this->maxxoffset = ($x + $width + $spacing);
|
||||
}
|
||||
return (object) array(
|
||||
'minx' => $curxoffset,
|
||||
'maxx' => ($x + $width + $spacing)
|
||||
);
|
||||
}
|
||||
return (object) array(
|
||||
'minx' => $curxoffset,
|
||||
'maxx' => $x
|
||||
);
|
||||
}
|
||||
|
||||
if( $this->maxxoffset < ($x + $width + $spacing) )
|
||||
{
|
||||
$this->maxxoffset = ($x + $width + $spacing);
|
||||
}
|
||||
|
||||
return (object) array(
|
||||
'minx' => $curxoffset,
|
||||
'maxx' => ($x + $width + $spacing)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
@@ -8,12 +24,14 @@ if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
class Login extends FHC_Controller
|
||||
{
|
||||
/**
|
||||
*
|
||||
* Object initialization
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
{
|
||||
parent::__construct(array(
|
||||
'loginAs' => 'admin:rw'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a login page with username and password
|
||||
@@ -24,72 +42,11 @@ class Login extends FHC_Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Called with HTTP POST via ajax to login using the LDAP authentication
|
||||
* Displays a login page with username and password
|
||||
*/
|
||||
public function loginLDAP()
|
||||
{
|
||||
$username = $this->input->post('username');
|
||||
$password = $this->input->post('password');
|
||||
|
||||
$this->load->library('AuthLib', array(false)); // without authentication otherwise loooooop!
|
||||
|
||||
$login = $this->authlib->loginLDAP($username, $password);
|
||||
if (isSuccess($login))
|
||||
{
|
||||
$this->outputJsonSuccess($this->authlib->getLandingPage()); // if login is success then retrieves the desired page
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->outputJsonError(getCode($login)); // returns the error code
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called with HTTP POST via ajax to login as another user specified by uid
|
||||
*/
|
||||
public function loginASByUid()
|
||||
{
|
||||
$uid = $this->input->get('uid');
|
||||
|
||||
// With authentication -> you must be already logged to gain another identity
|
||||
$this->load->library('AuthLib');
|
||||
|
||||
$loginAS = $this->authlib->loginASByUID($uid);
|
||||
$this->outputJson($loginAS); // returns the error code
|
||||
}
|
||||
|
||||
/**
|
||||
* Called with HTTP POST via ajax to login as another user specified by person id
|
||||
*/
|
||||
public function loginASByPersonId()
|
||||
{
|
||||
$person_id = $this->input->get('person_id');
|
||||
|
||||
// With authentication -> you must be already logged to gain another identity
|
||||
$this->load->library('AuthLib');
|
||||
|
||||
$loginAS = $this->authlib->loginASByPersonId($person_id);
|
||||
if (isSuccess($loginAS))
|
||||
{
|
||||
$this->outputJsonSuccess(true); // obtained!
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->outputJsonSuccess(getCode($loginAS)); // returns the error code
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* To login into the system with email and code as credentials
|
||||
*/
|
||||
public function emailCode()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* To login into the system using SSO
|
||||
*/
|
||||
public function sso()
|
||||
public function loginAs()
|
||||
{
|
||||
$this->load->view('system/login/loginAs');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
/* Copyright (C) 2024 fhcomplete.net
|
||||
/* Copyright (C) 2022 fhcomplete.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as
|
||||
@@ -32,7 +32,7 @@ class DocsboxLib
|
||||
const STATUS_QUEUED = 'queued'; // Docsbox status when a file has been queued for the conversion
|
||||
const STATUS_STARTED = 'started'; // Docsbox status when a file has started being worked
|
||||
const STATUS_WORKING = 'working'; // Docsbox status when a file is being converted
|
||||
const JSON_FORMATS = '{"formats": ["%s"]}'; // JSON object to be sent to docsbox to specify the file format
|
||||
const OUTPUT_FILENAME = 'out.zip.pdf'; // File name used by docsbox to save a converted document
|
||||
|
||||
const DEFAULT_FORMAT = 'pdf'; // Default supported format
|
||||
|
||||
@@ -50,7 +50,7 @@ class DocsboxLib
|
||||
if (($format == null) || ($format != null && ctype_space($format) === true)) $format = self::DEFAULT_FORMAT;
|
||||
|
||||
// Posts the file to docsbox
|
||||
$queueId = self::_postFile($inputFileName, $format);
|
||||
$queueId = self::_postFile($inputFileName);
|
||||
// If an error occurred
|
||||
if ($queueId == null) return self::ERROR;
|
||||
|
||||
@@ -60,7 +60,7 @@ class DocsboxLib
|
||||
if ($resultUrl == null) return self::ERROR;
|
||||
|
||||
// Download and rename the converted file
|
||||
$downloaded = self::_downloadFile($inputFileName, $resultUrl, $outputFileName, $format);
|
||||
$downloaded = self::_downloadFile($resultUrl, $outputFileName);
|
||||
// If an error occurred
|
||||
if (!$downloaded) return self::ERROR;
|
||||
|
||||
@@ -74,7 +74,7 @@ class DocsboxLib
|
||||
* Posts the given file to a Docsboxserver and checks the response to return a valid queue id
|
||||
* On failure it returns a null value
|
||||
*/
|
||||
private static function _postFile($inputFileName, $format)
|
||||
private static function _postFile($inputFileName)
|
||||
{
|
||||
$queueId = null;
|
||||
|
||||
@@ -82,14 +82,8 @@ class DocsboxLib
|
||||
{
|
||||
// Posts the given file and expects a response in JSON format
|
||||
$postFileResponse = \Httpful\Request::post(DOCSBOX_SERVER.DOCSBOX_PATH_API)
|
||||
->sendsType(\Httpful\Mime::FORM)
|
||||
->expectsJson()
|
||||
->body(
|
||||
array(
|
||||
'options' => sprintf(self::JSON_FORMATS, $format)
|
||||
)
|
||||
)
|
||||
->attach(array('file' => $inputFileName))
|
||||
->expectsJson()
|
||||
->send();
|
||||
|
||||
// Checks that:
|
||||
@@ -227,7 +221,7 @@ class DocsboxLib
|
||||
/**
|
||||
* Download the converted file using the provided URL, unzip it, and renames it into the provided file name
|
||||
*/
|
||||
private static function _downloadFile($inputFileName, $resultUrl, $outputFileName, $format)
|
||||
private static function _downloadFile($resultUrl, $outputFileName)
|
||||
{
|
||||
$downloaded = false; // pessimistic assumption
|
||||
|
||||
@@ -259,7 +253,7 @@ class DocsboxLib
|
||||
// Opened, extracted and closed!
|
||||
|
||||
// Rename the extracted file to the given output file name
|
||||
if (@rename($inputFileName.'.'.$format, $outputFileName))
|
||||
if (rename($outputDirectory.'/'.self::OUTPUT_FILENAME, $outputFileName))
|
||||
{
|
||||
$downloaded = true;
|
||||
}
|
||||
@@ -267,7 +261,7 @@ class DocsboxLib
|
||||
{
|
||||
error_log(
|
||||
'An error occurred while renaming the extracted file: '.
|
||||
$inputFileName.'.'.$format.' into: '.
|
||||
$outputDirectory.'/'.self::OUTPUT_FILENAME.' into: '.
|
||||
$outputFileName
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
<?php
|
||||
/* Copyright (C) 2024 fhcomplete.net
|
||||
*
|
||||
* 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
class Drawio_model extends CI_Model
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderFileStart($pages=1, $agent='FH-Complete', $timemodified='now')
|
||||
{
|
||||
$modified = (new DateTime($timemodified, new DateTimeZone('UTC')))->format(DateTime::ATOM);
|
||||
|
||||
echo <<<HEADER
|
||||
<mxfile modified="{$modified}" host="Electron" agent="{$agent}" type="device" pages="{$pages}">
|
||||
HEADER;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderFileEnd()
|
||||
{
|
||||
echo <<<FOOTER
|
||||
</mxfile>
|
||||
FOOTER;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderDiagramStart($diagram_id, $diagram_bezeichnung)
|
||||
{
|
||||
$bezeichnung = htmlspecialchars($diagram_bezeichnung);
|
||||
|
||||
echo <<<STARTDIAGRAMM
|
||||
<diagram id="diagram_{$diagram_id}" name="{$bezeichnung}">
|
||||
<mxGraphModel dx="1177" dy="687" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
STARTDIAGRAMM;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderDiagramEnd()
|
||||
{
|
||||
echo <<<ENDDIAGRAMM
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
ENDDIAGRAMM;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderCell($id, $value, $x, $y, $width, $height)
|
||||
{
|
||||
echo <<<OE
|
||||
<mxCell id="{$id}" value="{$value}" parent="1" vertex="1">
|
||||
<mxGeometry x="{$x}" y="{$y}" width="{$width}" height="{$height}" as="geometry" />
|
||||
</mxCell>
|
||||
OE;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderEdge($source, $target, $exitX, $exitY, $entryX, $entryY, $points=array())
|
||||
{
|
||||
if( count($points) > 0 )
|
||||
{
|
||||
$pointsxml = '';
|
||||
foreach($points as $point)
|
||||
{
|
||||
$pointsxml .= <<<EOPOINT
|
||||
<mxPoint x="{$point->x}" y="{$point->y}" />
|
||||
EOPOINT;
|
||||
}
|
||||
|
||||
$edgegeom = <<<EDGEPOINTS
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
{$pointsxml}
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
EDGEPOINTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
$edgegeom = ' <mxGeometry relative="1" as="geometry" />';
|
||||
}
|
||||
|
||||
echo <<<EDGE
|
||||
<mxCell id="edge_{$source}_{$target}" value="" style="edgeStyle=elbowEdgeStyle;elbow=vertical;sourcePerimeterSpacing=0;targetPerimeterSpacing=0;startArrow=none;endArrow=none;rounded=0;curved=0;exitX={$exitX};exitY={$exitY};exitDx=0;exitDy=0;entryX={$entryX};entryY={$entryY};entryDx=0;entryDy=0;" parent="1" source="{$source}" target="{$target}" edge="1">
|
||||
{$edgegeom}
|
||||
</mxCell>
|
||||
EDGE;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderSemesterLabel($id, $sem, $ects, $x, $y, $width, $height)
|
||||
{
|
||||
echo <<<RENDERSEM
|
||||
<mxCell id="{$id}" value="<b>{$sem}. Semester<br></b><div style="text-align: left;"><span style="background-color: initial;">{$ects} ECTS</span></div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="{$x}" y="{$y}" width="{$width}" height="{$height}" as="geometry" />
|
||||
</mxCell>
|
||||
RENDERSEM;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderModulList($listid, $mod, $x, $y, $ects_width, $lv_height)
|
||||
{
|
||||
$width = ceil($mod->ects * $ects_width);
|
||||
$height = (count($mod->childs) + 1) * $lv_height;
|
||||
$modul_ects = (int) $mod->ects;
|
||||
|
||||
echo <<<RENDERMOD
|
||||
<mxCell id="{$listid}" value="{$mod->bezeichnung} ({$modul_ects})" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize={$lv_height};horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=0;marginBottom=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="{$x}" y="{$y}" width="{$width}" height="{$height}" as="geometry">
|
||||
<mxRectangle x="{$x}" y="{$y}" width="{$width}" height="{$height}" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
RENDERMOD;
|
||||
|
||||
$childnumber = 0;
|
||||
|
||||
foreach ($mod->childs as $child)
|
||||
{
|
||||
$childnumber++;
|
||||
$childid = uniqid();
|
||||
$childheight = $childnumber * $lv_height;
|
||||
$child_ects = (int) $child->ects;
|
||||
|
||||
echo <<<RENDERMODFOR
|
||||
<mxCell id="{$childid}" value="{$child->bezeichnung} ({$child_ects})" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="{$listid}">
|
||||
<mxGeometry y="{$childheight}" width="{$width}" height="{$lv_height}" as="geometry" />
|
||||
</mxCell>
|
||||
RENDERMODFOR;
|
||||
}
|
||||
|
||||
return (object) array(
|
||||
'width' => $width,
|
||||
'height' => $height
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
$includesArray = array(
|
||||
'title' => 'Login',
|
||||
'axios027' => true,
|
||||
'bootstrap5' => true,
|
||||
'fontawesome6' => true,
|
||||
'vue3' => true,
|
||||
'primevue3' => true,
|
||||
'phrases' => array('uid', 'global'),
|
||||
'navigationcomponent' => true,
|
||||
'customJSModules' => array('public/js/LoginAs.js'),
|
||||
);
|
||||
|
||||
$this->load->view('templates/FHC-Header', $includesArray);
|
||||
?>
|
||||
|
||||
<div id="main"></div>
|
||||
|
||||
<?php $this->load->view('templates/FHC-Footer', $includesArray); ?>
|
||||
|
||||
@@ -1,44 +1,39 @@
|
||||
<?php
|
||||
$this->load->view(
|
||||
'templates/FHC-Header',
|
||||
array(
|
||||
'title' => 'Login',
|
||||
'jquery3' => true,
|
||||
'jqueryui1' => true,
|
||||
'bootstrap3' => true,
|
||||
'fontawesome4' => true,
|
||||
'sbadmintemplate3' => true,
|
||||
'ajaxlib' => true,
|
||||
'dialoglib' => true,
|
||||
'customCSSs' => 'public/css/Login.css',
|
||||
'customJSs' => 'public/js/Login.js'
|
||||
)
|
||||
);
|
||||
/**
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
$includesArray = array(
|
||||
'title' => 'Login',
|
||||
'axios027' => true,
|
||||
'bootstrap5' => true,
|
||||
'fontawesome6' => true,
|
||||
'vue3' => true,
|
||||
'filtercomponent' => true,
|
||||
'navigationcomponent' => true,
|
||||
'tabulator5' => true,
|
||||
'primevue3' => true,
|
||||
'phrases' => array('uid', 'global'),
|
||||
'customJSModules' => array('public/js/Login.js'),
|
||||
);
|
||||
|
||||
$this->load->view('templates/FHC-Header', $includesArray);
|
||||
?>
|
||||
|
||||
<div id="main"></div>
|
||||
|
||||
<div class="login-form">
|
||||
<?php $this->load->view('templates/FHC-Footer', $includesArray); ?>
|
||||
|
||||
<p class="text-center">
|
||||
<img src="<?php echo base_url('public/images/logo-300x160.png'); ?>" >
|
||||
</p>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="form-group">
|
||||
<input id="username" type="text" class="form-control" placeholder="Username" required="required">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input id="password" type="password" class="form-control" placeholder="Password" required="required">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button id="btnLogin" ype="submit" class="btn btn-primary btn-block">Log in</button>
|
||||
</div>
|
||||
|
||||
<p class="text-center"><a href="#">Forgot Password?</a></p>
|
||||
|
||||
</div>
|
||||
|
||||
<?php $this->load->view('templates/FHC-Footer'); ?>
|
||||
|
||||
@@ -287,7 +287,6 @@ class dokument_export
|
||||
{
|
||||
case 'pdf':
|
||||
case 'doc':
|
||||
case 'docx':
|
||||
$ret = 0;
|
||||
$this->temp_filename = $this->temp_folder . '/out.' . $this->outputformat;
|
||||
|
||||
@@ -370,11 +369,6 @@ class dokument_export
|
||||
header('Content-Disposition: attachment; filename="'.$this->filename.'.doc"');
|
||||
header('Content-Length: '.$fsize);
|
||||
break;
|
||||
case 'docx':
|
||||
header('Content-type: application/vnd.ms-word');
|
||||
header('Content-Disposition: attachment; filename="'.$this->filename.'.docx"');
|
||||
header('Content-Length: '.$fsize);
|
||||
break;
|
||||
|
||||
case 'odt':
|
||||
header('Content-type: application/vnd.oasis.opendocument.text');
|
||||
|
||||
+73
-49
@@ -1,55 +1,79 @@
|
||||
|
||||
/**
|
||||
* To login via LDAP
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
function loginLDAP()
|
||||
{
|
||||
// Ajax call to login with LDAP
|
||||
FHC_AjaxClient.ajaxCallPost(
|
||||
"system/Login/loginLDAP",
|
||||
{
|
||||
username: $("#username").val(),
|
||||
password: $("#password").val()
|
||||
},
|
||||
{
|
||||
successCallback: function(data, textStatus, jqXHR) {
|
||||
|
||||
if (FHC_AjaxClient.isError(data))
|
||||
{
|
||||
if (FHC_AjaxClient.getError(data) == 10)
|
||||
import PluginsPhrasen from '../js/plugins/Phrasen.js';
|
||||
import ApiLogin from '../js/api/factory/login.js';
|
||||
|
||||
const loginApp = Vue.createApp({
|
||||
data: function() {
|
||||
return {
|
||||
username: '',
|
||||
password: ''
|
||||
};
|
||||
},
|
||||
components: {
|
||||
},
|
||||
methods: {
|
||||
loginLDAP: function() {
|
||||
this.$api
|
||||
.call(ApiLogin.loginLDAP({
|
||||
username: this.username,
|
||||
password: this.password
|
||||
}))
|
||||
.then((response) => {
|
||||
// If property data exists
|
||||
if (Object.hasOwn(response, 'data'))
|
||||
{
|
||||
FHC_DialogLib.alertError("Username not foud");
|
||||
// If property data is a string
|
||||
if (typeof response.data === 'string' || response.data instanceof String)
|
||||
{
|
||||
// If property data is a valid URL
|
||||
try {
|
||||
let url = new URL(response.data);
|
||||
// If here the URL contained in response.data is fine
|
||||
// and can be used to switch to the landing page
|
||||
document.location.href = response.data;
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
if (FHC_AjaxClient.getError(data) == 2)
|
||||
{
|
||||
FHC_DialogLib.alertError("Wrong password");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$(location).attr("href", FHC_AjaxClient.getData(data));
|
||||
}
|
||||
},
|
||||
errorCallback: function(jqXHR, textStatus, errorThrown) {
|
||||
FHC_DialogLib.alertError(textStatus);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* When JQuery is up
|
||||
*/
|
||||
$(document).ready(function() {
|
||||
|
||||
$("#btnLogin").click(loginLDAP);
|
||||
|
||||
$("#username").keydown(function(e) {
|
||||
if (e.keyCode == 13) loginLDAP();
|
||||
})
|
||||
|
||||
$("#password").keydown(function(e) {
|
||||
if (e.keyCode == 13) loginLDAP();
|
||||
})
|
||||
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="d-flex align-items-center justify-content-center">
|
||||
<div>
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Username</label>
|
||||
<input type="text" class="form-control" name="username" id="username" v-model="username">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Password</label>
|
||||
<input type="password" class="form-control" name="password" id="password" v-model="password">
|
||||
</div>
|
||||
<div class="d-flex align-items-center justify-content-center">
|
||||
<button type="button" class="btn btn-primary" @click="loginLDAP">Login</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
});
|
||||
|
||||
loginApp.use(PluginsPhrasen).mount('#main');
|
||||
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import PluginsPhrasen from '../js/plugins/Phrasen.js';
|
||||
import ApiLogin from '../js/api/factory/login.js';
|
||||
|
||||
import {CoreNavigationCmpt} from '../js/components/navigation/Navigation.js';
|
||||
import PvAutoComplete from "../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js";
|
||||
|
||||
const loginAsApp = Vue.createApp({
|
||||
data: function() {
|
||||
return {
|
||||
person_id: '',
|
||||
username: '',
|
||||
surname: '',
|
||||
name: '',
|
||||
selectedUser: null,
|
||||
filteredUsers: [],
|
||||
appSideMenuEntries: {}
|
||||
};
|
||||
},
|
||||
components: {
|
||||
CoreNavigationCmpt,
|
||||
PvAutoComplete
|
||||
},
|
||||
methods: {
|
||||
loginAs: function() {
|
||||
if (this.selectedUser != null)
|
||||
{
|
||||
this.$api
|
||||
.call(ApiLogin.loginASByUid({
|
||||
uid: this.selectedUser.uid
|
||||
}))
|
||||
.then((response) => {
|
||||
location.reload();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
},
|
||||
logout: function() {
|
||||
this.$api
|
||||
.call(ApiLogin.logout())
|
||||
.then((response) => {
|
||||
location.reload();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
},
|
||||
searchUser: function(event) {
|
||||
if (event.query.length >= 3)
|
||||
{
|
||||
this.$api
|
||||
.call(ApiLogin.searchUser(event.query))
|
||||
.then(result => {
|
||||
this.filteredUsers = result.data.retval;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted: function() {
|
||||
this.$api
|
||||
.call(ApiLogin.whoAmI())
|
||||
.then((response) => {
|
||||
// If property data exists
|
||||
if (Object.hasOwn(response, 'data'))
|
||||
{
|
||||
if (response.data != null && Object.hasOwn(response.data, 'person_id'))
|
||||
{
|
||||
this.person_id = response.data.person_id;
|
||||
this.username = response.data.username;
|
||||
this.surname = response.data.surname;
|
||||
this.name = response.data.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.person_id = 'Not logged';
|
||||
this.username = 'Not logged';
|
||||
this.surname = 'Not logged';
|
||||
this.name = 'Not logged';
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
},
|
||||
template: `
|
||||
<!-- Navigation component -->
|
||||
<core-navigation-cmpt v-bind:add-side-menu-entries="appSideMenuEntries"></core-navigation-cmpt>
|
||||
<div style="width: 700px !important">
|
||||
<div class="card" style="padding: 20px;">
|
||||
<div class="mb-3">
|
||||
Who am I?
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="d-inline-flex align-items-center">
|
||||
<label for="person_id" class="form-label" style="width: 150px !important">Person ID</label>
|
||||
<input type="text" style="width: 400px !important" disabled="disabled" class="form-control" id="person_id" v-model="person_id">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="d-inline-flex align-items-center">
|
||||
<label for="username" class="form-label" style="width: 150px !important">UID</label>
|
||||
<input type="text" style="width: 400px !important" disabled="disabled" class="form-control" id="username" v-model="username">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="d-inline-flex align-items-center">
|
||||
<label for="surname" class="form-label" style="width: 150px !important">Surname</label>
|
||||
<input type="text" style="width: 400px !important" disabled="disabled" class="form-control" id="surname" v-model="surname">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="d-inline-flex align-items-center">
|
||||
<label for="name" class="form-label" style="width: 150px !important">Name</label>
|
||||
<input type="text" style="width: 400px !important" disabled="disabled" class="form-control" id="name" v-model="name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center justify-content-center">
|
||||
<button type="button" class="btn btn-primary" @click="logout">Logout</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" style="padding: 20px;">
|
||||
<div class="mb-3">
|
||||
Who I want to be?
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="d-inline-flex align-items-center">
|
||||
<PvAutoComplete inputStyle="width: 600px;" v-model="selectedUser" optionLabel="label" :suggestions="filteredUsers" @complete="searchUser" placeholder="Search user..." />
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center justify-content-center">
|
||||
<button type="button" class="btn btn-primary" @click="loginAs">Login as</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
});
|
||||
|
||||
loginAsApp.
|
||||
use(PluginsPhrasen).
|
||||
use(primevue.config.default, {
|
||||
zIndex: {
|
||||
overlay: 1100
|
||||
}
|
||||
}).
|
||||
mount('#main');
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export default {
|
||||
loginLDAP(params) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/Login/loginLDAP',
|
||||
params
|
||||
};
|
||||
},
|
||||
loginASByUid(params) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/Login/loginASByUid',
|
||||
params
|
||||
};
|
||||
},
|
||||
loginASByPersonId(params) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/Login/loginASByPersonId',
|
||||
params
|
||||
};
|
||||
},
|
||||
whoAmI() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/Login/whoAmI'
|
||||
};
|
||||
},
|
||||
logout() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/system/Logout'
|
||||
};
|
||||
},
|
||||
searchUser(query) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/Login/searchUser?query=' + encodeURIComponent(query)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user