mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-01 20:29:29 +00:00
Added new Logging System for Persons
Added a Wrapper to call CI functions from outside Codeigniter
This commit is contained in:
@@ -209,6 +209,7 @@ $config['fhc_acl'] = array
|
||||
'system.tbl_webservicetyp' => 'basis/webservicetyp',
|
||||
'system.tbl_udf' => 'system/udf',
|
||||
'system.tbl_extensions' => 'system/extensions',
|
||||
'system.tbl_log' => 'basis/log',
|
||||
'testtool.tbl_ablauf' => 'basis/ablauf',
|
||||
'testtool.tbl_antwort' => 'basis/antwort',
|
||||
'testtool.tbl_frage' => 'basis/frage',
|
||||
|
||||
@@ -14,16 +14,17 @@ class CallerLib
|
||||
const LIB_FILE_EXTENSION = '.php';
|
||||
const LIBS_PATH = 'libraries';
|
||||
const MODEL_PREFIX = '_model';
|
||||
|
||||
|
||||
// Black list of resources that are no allowed to be used
|
||||
private static $RESOURCES_BLACK_LIST = array(
|
||||
'CallerLib', // disabled self loading
|
||||
'LogLib', // hardly usefull and virtually dangerous
|
||||
'MigrationLib', // virtually dangerous, DB manipulation
|
||||
'FilesystemLib', // virtually dangerous, direct access to file system
|
||||
'PermissionLib' // usefull?
|
||||
'PermissionLib', // usefull?
|
||||
'PersonLogLib'
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Object initialization
|
||||
*/
|
||||
@@ -31,14 +32,14 @@ class CallerLib
|
||||
{
|
||||
// Gets CI instance
|
||||
$this->ci =& get_instance();
|
||||
|
||||
|
||||
// Loads helper message to manage returning messages
|
||||
$this->ci->load->helper('Message');
|
||||
|
||||
|
||||
// Loads permission library
|
||||
$this->ci->load->library('PermissionLib');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper method for _call
|
||||
*/
|
||||
@@ -46,7 +47,7 @@ class CallerLib
|
||||
{
|
||||
return $this->_call($callParameters, $permissionType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper method for _call
|
||||
*/
|
||||
@@ -54,7 +55,7 @@ class CallerLib
|
||||
{
|
||||
return $this->_call($callParameters, $permissionType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Everything starts here...
|
||||
*/
|
||||
@@ -63,7 +64,7 @@ class CallerLib
|
||||
$result = null;
|
||||
$parameters = $this->_getParameters($callParameters);
|
||||
$validation = $this->_validateCall($parameters);
|
||||
|
||||
|
||||
// If the validation was passed
|
||||
if (isSuccess($validation))
|
||||
{
|
||||
@@ -119,7 +120,7 @@ class CallerLib
|
||||
{
|
||||
$result = error('Neither a lib nor model: '.$parameters->resourcePath.$parameters->resourceName);
|
||||
}
|
||||
|
||||
|
||||
// If the resource was found and loaded
|
||||
if (!is_null($loaded))
|
||||
{
|
||||
@@ -134,10 +135,10 @@ class CallerLib
|
||||
{
|
||||
$result = $validation;
|
||||
}
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the parameters from the http call
|
||||
* Search for parameters <RESOURCE_PARAMETER> and <FUNCTION_PARAMETER>
|
||||
@@ -181,7 +182,7 @@ class CallerLib
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate the given parameters
|
||||
*/
|
||||
@@ -224,7 +225,7 @@ class CallerLib
|
||||
{
|
||||
$loaded = null;
|
||||
$result = null;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
$loaded = $this->ci->load->model($resourcePath.$resourceName);
|
||||
@@ -234,15 +235,15 @@ class CallerLib
|
||||
// Errors while loading the model
|
||||
$result = error('Errors while loading the model: '.$e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
if (!is_null($loaded))
|
||||
{
|
||||
$result = success($loaded);
|
||||
}
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search for a valid permission for this library that should be present with this format:
|
||||
* '<library path>.<library name>.<library method name>' => '<permission>'
|
||||
@@ -251,14 +252,14 @@ class CallerLib
|
||||
{
|
||||
$result = null;
|
||||
$permissionPath = '';
|
||||
|
||||
|
||||
if ($resourcePath != '')
|
||||
{
|
||||
$permissionPath = $resourcePath;
|
||||
}
|
||||
|
||||
|
||||
$permissionPath .= $resourceName.'.'.$function;
|
||||
|
||||
|
||||
if ($this->ci->permissionlib->isEntitled($permissionPath, $permissionType) === false)
|
||||
{
|
||||
$result = error(FHC_NORIGHT, FHC_NORIGHT);
|
||||
@@ -267,10 +268,10 @@ class CallerLib
|
||||
{
|
||||
$result = success('Has permission');
|
||||
}
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads a library using the given path and name
|
||||
*
|
||||
@@ -286,7 +287,7 @@ class CallerLib
|
||||
private function _loadLibrary($resourcePath, $resourceName)
|
||||
{
|
||||
$loaded = null;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// Gets all the configured resources paths
|
||||
@@ -328,15 +329,15 @@ class CallerLib
|
||||
// Errors while loading the library
|
||||
$result = error('Errors while loading the library: '.$e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
if (!is_null($loaded))
|
||||
{
|
||||
$result = success($loaded);
|
||||
}
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls a method of a class with the given parameters and returns its result
|
||||
*
|
||||
@@ -347,7 +348,7 @@ class CallerLib
|
||||
private function _callThis($resourceName, $function, $parameters)
|
||||
{
|
||||
$result = null;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// Get informations about the function
|
||||
@@ -402,7 +403,7 @@ class CallerLib
|
||||
{
|
||||
$result = error($e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Logging Actions of Persons
|
||||
*/
|
||||
class PersonLogLib
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->ci =& get_instance();
|
||||
$this->ci->load->model('system/PersonLog_model', 'PersonLogModel');
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a Log for a Person
|
||||
* @param int $person_id ID of the Person.
|
||||
* @param string $logtype_kurzbz Type of Log.
|
||||
* @param array $logdata Array of the JSON Data to save.
|
||||
* @param string $app Application that log belongs to.
|
||||
* @param string $oe_kurzbz Organisation Unit the Log belongs to.
|
||||
* @param string $user User who created the log.
|
||||
* @return boolean true if success
|
||||
*/
|
||||
public function log($person_id, $logtype_kurzbz, $logdata, $app = 'core', $oe_kurzbz = null, $user = null)
|
||||
{
|
||||
$data = array(
|
||||
'person_id' => $person_id,
|
||||
'zeitpunkt' => date('Y-m-d H:i:s'),
|
||||
'app' => $app,
|
||||
'oe_kurzbz' => $oe_kurzbz,
|
||||
'logtype_kurzbz' => $logtype_kurzbz,
|
||||
'logdata' => json_encode($logdata),
|
||||
'insertvon' => $user
|
||||
);
|
||||
|
||||
$result = $this->ci->PersonLogModel->insert($data);
|
||||
if (isSuccess($result))
|
||||
return true;
|
||||
else
|
||||
show_error($result->retval);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* PersonLog Extends from CI_Model instead of DB_Model
|
||||
* to be able to write Log without a loggedin User!
|
||||
*/
|
||||
class PersonLog_model extends CI_Model
|
||||
{
|
||||
private $dbTable;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->load->database();
|
||||
|
||||
$this->dbTable = 'system.tbl_log';
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a Log for a Person
|
||||
* @param array $data Data of Log Entry to save.
|
||||
* @return success object if true
|
||||
*/
|
||||
public function insert($data)
|
||||
{
|
||||
$result = $this->db->insert($this->dbTable, $data);
|
||||
if ($result)
|
||||
return success($this->db->insert_id());
|
||||
else
|
||||
return error();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the last Log Entry of a Person
|
||||
* @param int $person_id ID of the Person.
|
||||
* @param string $app Name of the App.
|
||||
* @param string $oe_kurzbz Organisations Unit.
|
||||
* @return object $result
|
||||
*/
|
||||
public function getLastLog($person_id, $app = null, $oe_kurzbz = null)
|
||||
{
|
||||
// Check Permissions
|
||||
$this->load->library('PermissionLib');
|
||||
if(!$this->permissionlib->isEntitled('system.tbl_log',PermissionLib::SELECT_RIGHT))
|
||||
show_error('Permission denied - You need Access to system.tbl_log');
|
||||
|
||||
$this->db->order_by('zeitpunkt', 'DESC');
|
||||
$this->db->order_by('log_id', 'DESC');
|
||||
$this->db->limit(1);
|
||||
if (!is_null($app))
|
||||
$this->db->where('app='.$this->db->escape($app));
|
||||
if (!is_null($oe_kurzbz))
|
||||
$this->db->where('oe_kurzbz='.$this->db->escape($oe_kurzbz));
|
||||
|
||||
$result = $this->db->get_where($this->dbTable, "person_id=".$this->db->escape($person_id));
|
||||
|
||||
return success($result->result());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* This Script is for Loading the Codeigniter Context in Non-Codeigniter Scripts
|
||||
* Usage:
|
||||
* $ci = require_once(ci_loader.php');
|
||||
* $ci->load->library('xxx');
|
||||
*/
|
||||
ob_start();
|
||||
require_once('index.ci.php');
|
||||
ob_get_clean();
|
||||
return $CI;
|
||||
@@ -1079,4 +1079,10 @@ function cutString($string, $limit, $placeholderSign = '', $keepFilextension = f
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
function PersonLog($ci, $person_id, $logtype_kurzbz, $logdata, $app, $oe_kurzbz = null, $user=null)
|
||||
{
|
||||
$ci->load->library('PersonLogLib');
|
||||
$ci->personloglib->log($person_id, $logtype_kurzbz, $logdata, $app, $oe_kurzbz, $user);
|
||||
}
|
||||
?>
|
||||
|
||||
+3
-4
@@ -54,7 +54,7 @@
|
||||
* NOTE: If you change these, also change the error_reporting() code below
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');
|
||||
|
||||
/*
|
||||
@@ -102,7 +102,7 @@ switch (ENVIRONMENT)
|
||||
* as this file.
|
||||
*
|
||||
*/
|
||||
$system_path = 'vendor/codeigniter/framework/system';
|
||||
$system_path = dirname(__FILE__).'/vendor/codeigniter/framework/system';
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------
|
||||
@@ -118,7 +118,7 @@ switch (ENVIRONMENT)
|
||||
* NO TRAILING SLASH!
|
||||
*
|
||||
*/
|
||||
$application_folder = 'application';
|
||||
$application_folder = dirname(__FILE__).'/application';
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------
|
||||
@@ -308,4 +308,3 @@ include_once 'vendor/autoload.php';
|
||||
|
||||
// Now the bootstrap file
|
||||
require_once BASEPATH.'core/CodeIgniter.php';
|
||||
|
||||
|
||||
+55
-4
@@ -578,7 +578,7 @@ if(!@$db->db_query("SELECT campus.get_highest_content_version(0)"))
|
||||
RETURN rec.version;
|
||||
END;
|
||||
$_$;
|
||||
|
||||
|
||||
ALTER FUNCTION campus.get_highest_content_version(bigint) OWNER TO fhcomplete;';
|
||||
|
||||
if(!$db->db_query($qry))
|
||||
@@ -753,6 +753,55 @@ if ($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berech
|
||||
// End extensions
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
if (!$result = @$db->db_query("SELECT 1 FROM system.tbl_log LIMIT 1"))
|
||||
{
|
||||
$qry = "CREATE TABLE system.tbl_log
|
||||
(
|
||||
log_id bigint NOT NULL,
|
||||
person_id integer,
|
||||
zeitpunkt timestamp NOT NULL DEFAULT now(),
|
||||
app varchar(32) NOT NULL,
|
||||
oe_kurzbz varchar(32),
|
||||
logtype_kurzbz varchar(32) NOT NULL,
|
||||
logdata jsonb NOT NULL,
|
||||
insertvon varchar(32)
|
||||
);
|
||||
ALTER TABLE system.tbl_log ADD CONSTRAINT pk_log PRIMARY KEY (log_id);
|
||||
|
||||
CREATE SEQUENCE system.tbl_log_log_id_seq
|
||||
INCREMENT BY 1
|
||||
NO MAXVALUE
|
||||
NO MINVALUE
|
||||
CACHE 1;
|
||||
ALTER TABLE system.tbl_log ALTER COLUMN log_id SET DEFAULT nextval('system.tbl_log_log_id_seq');
|
||||
|
||||
GRANT SELECT, INSERT ON system.tbl_log TO vilesci;
|
||||
GRANT SELECT, INSERT ON system.tbl_log TO web;
|
||||
GRANT SELECT, UPDATE ON system.tbl_log_log_id_seq TO vilesci;
|
||||
GRANT SELECT, UPDATE ON system.tbl_log_log_id_seq TO web;
|
||||
|
||||
CREATE TABLE system.tbl_logtype
|
||||
(
|
||||
logtype_kurzbz varchar(32),
|
||||
data_schema jsonb NOT NULL
|
||||
);
|
||||
ALTER TABLE system.tbl_logtype ADD CONSTRAINT pk_logtype PRIMARY KEY (logtype_kurzbz);
|
||||
GRANT SELECT ON system.tbl_logtype TO vilesci;
|
||||
GRANT SELECT ON system.tbl_logtype TO web;
|
||||
|
||||
ALTER TABLE system.tbl_log ADD CONSTRAINT fk_log_person_id FOREIGN KEY (person_id) REFERENCES public.tbl_person(person_id) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||
ALTER TABLE system.tbl_log ADD CONSTRAINT fk_log_app FOREIGN KEY (app) REFERENCES system.tbl_app(app) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||
ALTER TABLE system.tbl_log ADD CONSTRAINT fk_log_oe_kurzbz FOREIGN KEY (oe_kurzbz) REFERENCES public.tbl_organisationseinheit(oe_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||
ALTER TABLE system.tbl_log ADD CONSTRAINT fk_log_logtype_kurzbz FOREIGN KEY (logtype_kurzbz) REFERENCES system.tbl_logtype(logtype_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||
|
||||
INSERT INTO system.tbl_logtype VALUES ('Action', '{\"type\": \"object\", \"title\": \"Action\", \"required\": [\"name\", \"success\", \"message\"], \"properties\": {\"name\": {\"type\": \"string\"}, \"message\": {\"type\": \"string\"}, \"success\": {\"type\": \"string\"}}}');
|
||||
INSERT INTO system.tbl_logtype VALUES ('Processstate', '{\"type\": \"object\", \"title\": \"Processstate\", \"required\": [\"name\"], \"properties\": {\"name\": {\"type\": \"string\"}}}');
|
||||
";
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>system.tbl_log '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo ' system.tbl_log hinzugefügt<br>';
|
||||
}
|
||||
|
||||
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
|
||||
echo '<H2>Pruefe Tabellen und Attribute!</H2>';
|
||||
@@ -881,7 +930,7 @@ $tabellen=array(
|
||||
"lehre.tbl_projektbetreuer" => array("person_id","projektarbeit_id","betreuerart_kurzbz","note","faktor","name","punkte","stunden","stundensatz","updateamum","updatevon","insertamum","insertvon","ext_id","vertrag_id"),
|
||||
"lehre.tbl_projekttyp" => array("projekttyp_kurzbz","bezeichnung"),
|
||||
"lehre.tbl_pruefung" => array("pruefung_id","lehreinheit_id","student_uid","mitarbeiter_uid","note","pruefungstyp_kurzbz","datum","anmerkung","insertamum","insertvon","updateamum","updatevon","ext_id","pruefungsanmeldung_id","vertrag_id", "punkte"),
|
||||
"lehre.tbl_pruefungstyp" => array("pruefungstyp_kurzbz","beschreibung","abschluss"),
|
||||
"lehre.tbl_pruefungstyp" => array("pruefungstyp_kurzbz","beschreibung","abschluss","sort"),
|
||||
"lehre.tbl_studienordnung" => array("studienordnung_id","studiengang_kz","version","gueltigvon","gueltigbis","bezeichnung","ects","studiengangbezeichnung","studiengangbezeichnung_englisch","studiengangkurzbzlang","akadgrad_id","insertamum","insertvon","updateamum","updatevon","ext_id", "status_kurzbz", "standort_id"),
|
||||
"lehre.tbl_studienordnungstatus" => array("status_kurzbz","bezeichnung","reihenfolge"),
|
||||
"lehre.tbl_studienordnung_semester" => array("studienordnung_semester_id","studienordnung_id","studiensemester_kurzbz","semester"),
|
||||
@@ -902,7 +951,7 @@ $tabellen=array(
|
||||
"lehre.tbl_zeugnisnote" => array("lehrveranstaltung_id","student_uid","studiensemester_kurzbz","note","uebernahmedatum","benotungsdatum","bemerkung","updateamum","updatevon","insertamum","insertvon","ext_id","punkte"),
|
||||
"public.ci_apikey" => array("apikey_id","key","level","ignore_limits","date_created"),
|
||||
"public.tbl_adresse" => array("adresse_id","person_id","name","strasse","plz","ort","gemeinde","nation","typ","heimatadresse","zustelladresse","firma_id","updateamum","updatevon","insertamum","insertvon","ext_id","rechnungsadresse","anmerkung"),
|
||||
"public.tbl_akte" => array("akte_id","person_id","dokument_kurzbz","uid","inhalt","mimetype","erstelltam","gedruckt","titel","bezeichnung","updateamum","updatevon","insertamum","insertvon","ext_id","dms_id","nachgereicht","anmerkung","titel_intern","anmerkung_intern","nachgereicht_am"),
|
||||
"public.tbl_akte" => array("akte_id","person_id","dokument_kurzbz","uid","inhalt","mimetype","erstelltam","gedruckt","titel","bezeichnung","updateamum","updatevon","insertamum","insertvon","ext_id","dms_id","nachgereicht","anmerkung","titel_intern","anmerkung_intern","nachgereicht_am","ausstellungsnation","formal_geprueft_amum"),
|
||||
"public.tbl_ampel" => array("ampel_id","kurzbz","beschreibung","benutzer_select","deadline","vorlaufzeit","verfallszeit","insertamum","insertvon","updateamum","updatevon","email","verpflichtend","buttontext"),
|
||||
"public.tbl_ampel_benutzer_bestaetigt" => array("ampel_benutzer_bestaetigt_id","ampel_id","uid","insertamum","insertvon"),
|
||||
"public.tbl_aufmerksamdurch" => array("aufmerksamdurch_kurzbz","beschreibung","ext_id","bezeichnung", "aktiv"),
|
||||
@@ -915,7 +964,7 @@ $tabellen=array(
|
||||
"public.tbl_benutzergruppe" => array("uid","gruppe_kurzbz","studiensemester_kurzbz","updateamum","updatevon","insertamum","insertvon","ext_id"),
|
||||
"public.tbl_bewerbungstermine" => array("bewerbungstermin_id","studiengang_kz","studiensemester_kurzbz","beginn","ende","nachfrist","nachfrist_ende","anmerkung", "insertamum", "insertvon", "updateamum", "updatevon","studienplan_id"),
|
||||
"public.tbl_buchungstyp" => array("buchungstyp_kurzbz","beschreibung","standardbetrag","standardtext","aktiv","credit_points"),
|
||||
"public.tbl_dokument" => array("dokument_kurzbz","bezeichnung","ext_id","bezeichnung_mehrsprachig","dokumentbeschreibung_mehrsprachig"),
|
||||
"public.tbl_dokument" => array("dokument_kurzbz","bezeichnung","ext_id","bezeichnung_mehrsprachig","dokumentbeschreibung_mehrsprachig","ausstellungsdetails"),
|
||||
"public.tbl_dokumentprestudent" => array("dokument_kurzbz","prestudent_id","mitarbeiter_uid","datum","updateamum","updatevon","insertamum","insertvon","ext_id"),
|
||||
"public.tbl_dokumentstudiengang" => array("dokument_kurzbz","studiengang_kz","ext_id", "onlinebewerbung", "pflicht","beschreibung_mehrsprachig","nachreichbar"),
|
||||
"public.tbl_erhalter" => array("erhalter_kz","kurzbz","bezeichnung","dvr","logo","zvr"),
|
||||
@@ -1003,6 +1052,8 @@ $tabellen=array(
|
||||
"system.tbl_benutzerrolle" => array("benutzerberechtigung_id","rolle_kurzbz","berechtigung_kurzbz","uid","funktion_kurzbz","oe_kurzbz","art","studiensemester_kurzbz","start","ende","negativ","updateamum", "updatevon","insertamum","insertvon","kostenstelle_id","anmerkung"),
|
||||
"system.tbl_berechtigung" => array("berechtigung_kurzbz","beschreibung"),
|
||||
"system.tbl_extensions" => array("extension_id","name","version","description","license","url","core_version","dependencies","enabled"),
|
||||
"system.tbl_log" => array("log_id","person_id","zeitpunkt","app","oe_kurzbz","logtype_kurzbz","logdata","insertvon"),
|
||||
"system.tbl_logtype" => array("logtype_kurzbz", "data_schema"),
|
||||
"system.tbl_phrase" => array("phrase_id","app","phrase","insertamum","insertvon"),
|
||||
"system.tbl_phrasentext" => array("phrasentext_id","phrase_id","sprache","orgeinheit_kurzbz","orgform_kurzbz","text","description","insertamum","insertvon"),
|
||||
"system.tbl_rolle" => array("rolle_kurzbz","beschreibung"),
|
||||
|
||||
Reference in New Issue
Block a user