Initial xentral_oss_20.3.c9ffacf

This commit is contained in:
Alex
2021-05-21 08:49:41 +02:00
parent 5406e4a551
commit 34e5ac43d9
18884 changed files with 2109867 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+726
View File
@@ -0,0 +1,726 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
final class DatabaseUpgrade
{
/** @var Application $app */
private $app;
/** @var array $CheckColumnTableCache */
private $CheckColumnTableCache;
/** @var bool $check_column_missing_run */
private $check_column_missing_run=false;
/** @var array $check_column_missing */
private $check_column_missing=array();
/** @var array $check_index_missing */
private $check_index_missing=array();
/** @var array */
private $allTables = [];
/** @var array */
private $indexe = [];
/**
* @param Application $app
*/
public function __construct($app)
{
$this->app = $app;
}
public function emptyTableCache(){
$this->CheckColumnTableCache = [];
$this->allTables = [];
$this->indexe = [];
}
/**
* @var bool $force
*
* @return array
*/
public function getAllTables($force = false)
{
if($force || empty($this->allTables)) {
$this->allTables = $this->app->DB->SelectFirstCols('SHOW TABLES');
}
return $this->allTables;
}
/**
* @param string $table
* @param string $pk
*/
public function createTable($table, $pk = 'id')
{
$sql = "CREATE TABLE `$table` (`".$pk."` INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (`".$pk."`)) ENGINE = InnoDB DEFAULT CHARSET=utf8";
$this->app->DB->Query($sql);
$this->addPrimary($table, $pk);
}
/**
* @param string $table
* @param string $pk
*/
public function addPrimary($table, $pk = 'id')
{
$this->CheckAlterTable(
"ALTER TABLE `$table`
ADD PRIMARY KEY (`".$pk."`)",
true
);
$this->CheckAlterTable(
"ALTER TABLE `$table`
MODIFY `".$pk."` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1",
true
);
}
/**
* @param string $table
* @param bool $force
*
* @return array
*/
public function getIndexeCached($table, $force = false)
{
if($force || !isset($this->indexe[$table])){
$this->indexe[$table] = $this->app->DB->SelectArr(sprintf('SHOW INDEX FROM `%s`', $table));
if($this->indexe[$table] === null) {
$this->indexe[$table] = [];
}
}
return $this->indexe[$table];
}
/**
* @param string $table
*/
public function clearIndexCached($table)
{
if(!isset($this->indexe[$table])) {
return;
}
unset($this->indexe[$table]);
}
/**
* @param string $table
* @param string $pk
*/
public function hasPrimaryKey($table, $pk = 'id')
{
$indexe = $this->getIndexeCached($table);
if(empty($indexe)) {
return false;
}
foreach($indexe as $index) {
if($index['Column_name'] === $pk
&& $index['Key_name'] === 'PRIMARY'
&& (int)$index['Non_unique'] === 0
) {
return true;
}
}
return false;
}
/**
* @param string $table
* @param string $pk
*
* @return void
*/
function CheckTable($table, $pk = 'id')
{
if($pk === 'id') {
$tables = $this->getAllTables();
if(!empty($tables)){
if(!in_array($table, $tables)){
$this->createTable($table, $pk);
return;
}
if(!$this->hasPrimaryKey($table, $pk)) {
$this->addPrimary($table, $pk);
}
return;
}
}
$found = false;
$tables = $this->getAllTables(true);
if($tables) {
$found = in_array($table, $tables);
}
else{
$check = $this->app->DB->Select("SELECT $pk FROM `$table` LIMIT 1");
if($check) {
$found = true;
}
}
if($found==false)
{
$sql = "CREATE TABLE `$table` (`".$pk."` INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (`".$pk."`)) ENGINE = InnoDB DEFAULT CHARSET=utf8";
$this->app->DB->Update($sql);
$this->CheckAlterTable("ALTER TABLE `$table`
ADD PRIMARY KEY (`".$pk."`)");
$this->CheckAlterTable("ALTER TABLE `$table`
MODIFY `".$pk."` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1");
}
if($pk !== 'id') {
$this->CheckColumn('created_at','timestamp',$table,"DEFAULT CURRENT_TIMESTAMP NOT NULL");
}
}
/**
* @param string $column
* @param string $type
* @param string $table
* @param string $default
*
* @return void
*/
function UpdateColumn($column,$type,$table,$default="NOT NULL")
{
$fields = $this->app->DB->SelectArr("show columns from `".$table."`");
if($fields)
{
foreach($fields as $val)
{
$field_array[] = $val['Field'];
}
}
if (in_array($column, $field_array))
{
$this->app->DB->Query('ALTER TABLE `'.$table.'` CHANGE `'.$column.'` `'.$column.'` '.$type.' '.$default.';');
}
}
/**
* @param string $column
* @param string $table
*
* @return void
*/
public function DeleteColumn($column,$table)
{
$this->app->DB->Query('ALTER TABLE `'.$table.'` DROP `'.$column.'`;');
}
/**
* @param string $column
* @param string $type
* @param string $table
* @param string $default
*
* @return void
*/
public function CheckColumn($column,$type,$table,$default="")
{
if($table === 'firmendaten')
{
if($this->app->DB->Select("SELECT `id` FROM `firmendaten_werte` WHERE `name` = '$column' LIMIT 1"))return;
}
if(!isset($this->CheckColumnTableCache[$table]))
{
$tmp=$this->app->DB->SelectArr("show columns from `".$table."`");
if($tmp)
{
foreach($tmp as $val)
{
$this->CheckColumnTableCache[$table][] = $val['Field'];
//$types[$val['Field']] = strtolower($val['Type']);
}
}
}
if (isset($this->CheckColumnTableCache[$table]) && !in_array($column, $this->CheckColumnTableCache[$table]))
{
if($this->check_column_missing_run)
{
//$result = mysqli_query($this->app->DB->connection,'ALTER TABLE `'.$table.'` ADD `'.$column.'` '.$type.' '.$default.';');
$this->check_column_missing[$table][]=$column;
} else {
$result = $this->app->DB->Query('ALTER TABLE `'.$table.'` ADD `'.$column.'` '.$type.' '.$default.';');
if($table === 'firmendaten' && $this->app->DB->error())
{
if((method_exists($this->app->DB, 'errno2') && $this->app->DB->errno() == '1118')
|| strpos($this->app->DB->error(),'Row size too large') !== false
)
{
$this->ChangeFirmendatenToMyIsam();
$this->app->DB->Query('ALTER TABLE `'.$table.'` ADD `'.$column.'` '.$type.' '.$default.';');
}
}
}
}
}
/**
* @param array $indexe
*
* @return array
*/
protected function getGroupedIndexe($indexe)
{
if(empty($indexe)) {
return $indexe;
}
$return = [];
foreach($indexe as $index) {
$keyName = $index['Key_name'];
$isUnique = $index['Non_unique'] == '0';
$seq = $index['Seq_in_index'];
$columnName = $index['Column_name'];
$return[$isUnique?'unique':'index'][$keyName][(int)$seq - 1] = $columnName;
}
return $return;
}
/**
* @param array $indexe
*
* @return array
*/
protected function getDoubleIndexeFromGroupedIndexe($indexe)
{
if(empty($indexe)) {
return [];
}
$ret = [];
foreach($indexe as $type => $indexArrs) {
$columnStrings = [];
foreach($indexArrs as $indexKey => $columns) {
$columnString = implode('|', $columns);
if(in_array($columnString, $columnStrings)) {
$ret[$type][] = $indexKey;
continue;
}
$columnStrings[] = $columnString;
}
}
return $ret;
}
/**
* @param string $table
* @param array $indexe
* @param bool $noCache
*
* @return array|null
*/
public function CheckDoubleIndex($table, $indexe, $noCache = false)
{
$query = $noCache?null:$this->CheckAlterTable("SHOW INDEX FROM `$table`");
if(!$query) {
$indexeGrouped = $this->getGroupedIndexe($indexe);
$doubleIndexe = $this->getDoubleIndexeFromGroupedIndexe($indexeGrouped);
if(!empty($doubleIndexe)) {
$indexe = $this->getIndexeCached($table, true);
$indexeGrouped = $this->getGroupedIndexe($indexe);
$doubleIndexe = $this->getDoubleIndexeFromGroupedIndexe($indexeGrouped);
if(empty($doubleIndexe)) {
return $indexe;
}
foreach($doubleIndexe as $type => $doubleIndex) {
foreach($doubleIndex as $indexName) {
$this->app->DB->Query("ALTER TABLE `".$table."` DROP INDEX `".$indexName."`");
}
}
}
elseif($noCache) {
return $indexe;
}
$this->CheckAlterTable("SHOW INDEX FROM `$table`", true);
return $this->getIndexeCached($table, true);
}
if(empty($indexe) || count($indexe) == 1){
return $indexe;
}
$uniquearr = array();
$indexarr = array();
foreach($indexe as $index)
{
if($index['Key_name'] !== 'PRIMARY' && !empty($index['Column_name']))
{
if($index['Non_unique'])
{
$indexarr[$index['Key_name']][] = $index['Column_name'];
}else{
$uniquearr[$index['Key_name']][] = $index['Column_name'];
}
}
}
$cindex = count($indexarr);
$cuniqe = count($uniquearr);
$changed = false;
if($cindex > 1)
{
$check = array();
foreach($indexarr as $key => $value)
{
if(empty($value))
{
continue;
}
if(count($value) > 1){
sort($value);
}
$vstr = implode(',', $value);
if(in_array($vstr, $check))
{
$this->app->DB->Query("DROP INDEX `".$key."` ON `".$table."`");
$changed = true;
}else{
$check[] = $vstr;
}
}
}
if($cuniqe > 1)
{
$check = array();
foreach($uniquearr as $key => $value)
{
if(empty($value))
{
continue;
}
if(count($value) > 1){
sort($value);
}
$vstr = implode(',', $value);
if(in_array($vstr, $check))
{
$this->app->DB->Query("DROP UNIQUE `".$key."` ON `".$table."`");
$changed = true;
}else{
$check[] = $vstr;
}
}
}
if($changed) {
return $this->getIndexeCached($table, true);
}
return $indexe;
}
/**
* @param string $table
* @param string|array $column
*
* @return bool
*/
public function CheckFulltextIndex($table,$column)
{
if(empty($table) || empty($column))
{
return false;
}
if(!is_array($column))
{
$column = [$column];
}
$columnmasked = [];
foreach($column as $keyColumn => $valueColumn)
{
if(!empty($valueColumn))
{
$columnmasked[] = "`$valueColumn`";
}else{
unset($column[$keyColumn]);
}
}
if(empty($column))
{
return false;
}
$columnsFound = [];
$indexe = $this->getIndexeCached($table, true);
$indexeFound = [];
if(!empty($indexe))
{
foreach($indexe as $index)
{
if($index['Index_type'] === 'FULLTEXT')
{
$indexeFound[] = $index['Column_name'];
if(!in_array($index['Column_name'], $columnsFound))
{
$columnsFound[] = $index['Column_name'];
}
}
}
$cindexeFound = count($indexeFound);
$column = count($column);
if(($column === $cindexeFound) && (count($columnsFound) === $column))
{
return true;
}
if($cindexeFound > 0)
{
return false;
}
}
$this->app->DB->Query(
"ALTER TABLE `$table`
ADD FULLTEXT INDEX `FullText`
(".implode(',',$columnmasked).");"
);
$error = $this->app->DB->error();
return empty($error);
}
/**
* @param string $table
* @param string $column
* @param bool $unique
*
* @return void
*/
function CheckIndex($table, $column, $unique = false)
{
$indexex = null;
$indexexother = null;
$indexe = $this->getIndexeCached($table);
if($indexe)
{
$indexe = $this->CheckDoubleIndex($table, $indexe, true);
foreach($indexe as $index)
{
if(is_array($column) && $index['Key_name'] !== 'PRIMARY')
{
if($unique && !$index['Non_unique'])
{
if(in_array($index['Column_name'], $column))
{
$indexex[$index['Key_name']][$index['Column_name']] = true;
}else{
$indexexother[$index['Key_name']][$index['Column_name']] = true;
}
}
elseif(!$unique){
if(in_array($index['Column_name'], $column)) {
$indexex[$index['Key_name']][$index['Column_name']] = true;
}
}
}
elseif(!is_array($column)){
if($index['Column_name'] == $column)
{
return;
}
}
}
if($this->check_column_missing_run)
{
$this->check_index_missing[$table][] = $column;
}
if(!$unique)
{
if(is_array($column))
{
if($indexex)
{
foreach($indexex as $k => $v) {
if(count($v) === 1 && count($column) > 1) {
$this->app->DB->Query("DROP INDEX `".$k."` ON `".$table."`");
$this->clearIndexCached($table);
unset($indexex[$k]);
}
}
foreach($indexex as $k => $v)
{
if(count($v) == count($column)){
return;
}
}
foreach($indexex as $k => $v)
{
if(!isset($indexexother[$k]))
{
$this->app->DB->Query("DROP INDEX `".$k."` ON `".$table."`");
$cols = null;
foreach($column as $c) {
$cols[] = "`$c`";
}
$this->CheckAlterTable("ALTER TABLE `$table` ADD INDEX(".implode(', ',$cols)."); ",true);
$this->clearIndexCached($table);
return;
}
}
}
$cols = null;
foreach($column as $c) {
$cols[] = "`$c`";
}
$this->CheckAlterTable("ALTER TABLE `$table` ADD INDEX(".implode(', ',$cols)."); ", true);
$this->clearIndexCached($table);
}
else{
$this->CheckAlterTable("ALTER TABLE `$table` ADD INDEX(`$column`); ", true);
$this->clearIndexCached($table);
}
}
else{
if(is_array($column))
{
if($indexex)
{
foreach($indexex as $k => $v)
{
if(count($v) == count($column))
{
return;
}
}
foreach($indexex as $k => $v)
{
if(!isset($indexexother[$k]))
{
$this->app->DB->Query("DROP INDEX `".$k."` ON `".$table."`");
$cols = null;
foreach($column as $c) {
$cols[] = "`$c`";
}
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(".implode(', ',$cols)."); ", true);
$this->clearIndexCached($table);
return;
}
}
}
$cols = null;
foreach($column as $c) {
$cols[] = "`$c`";
}
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(".implode(', ',$cols)."); ", true);
$this->clearIndexCached($table);
}else{
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(`$column`); ", true);
$this->clearIndexCached($table);
}
}
}
elseif(!is_array($column))
{
if(!$unique)
{
$this->CheckAlterTable("ALTER TABLE `$table` ADD INDEX(`$column`); ");
}else{
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(`$column`); ");
}
$this->clearIndexCached($table);
}
elseif(is_array($column))
{
$cols = null;
foreach($column as $c) {
$cols[] = "`$c`";
}
$this->CheckAlterTable("ALTER TABLE `$table` ADD UNIQUE(".implode(', ',$cols)."); ");
$this->clearIndexCached($table);
}
}
/**
* @param string $sql
* @param bool $force
*
* @return mysqli_result|bool
*/
function CheckAlterTable($sql, $force = false)
{
$sqlmd5 = md5($sql);
$check = $this->app->DB->Select("SELECT id FROM checkaltertable WHERE checksum='$sqlmd5' LIMIT 1");
if($check > 0 && !$force) return;
$query = $this->app->DB->Query($sql);
if($query && empty($check) && !$this->app->DB->error()){
$this->app->DB->Insert("INSERT INTO checkaltertable (id,checksum) VALUES ('','$sqlmd5')");
}
return $query;
}
/**
* @return void
*/
public function ChangeFirmendatenToMyIsam()
{
$this->app->DB->Query("ALTER TABLE firmendaten ENGINE = MyISAM;");
}
/**
* @param string $table
*
* @return array
*/
public function getSortedIndexColumnsByIndexName($table): array
{
$indexesByName = [];
$indexes = $this->app->DB->SelectArr(sprintf('SHOW INDEX FROM `%s`', $table));
if(empty($indexes)) {
return $indexesByName;
}
foreach($indexes as $index) {
$indexesByName[$index['Key_name']][] = $index['Column_name'];
}
foreach($indexesByName as $indexName => $columns) {
$columns = array_unique($columns);
sort($columns);
$indexesByName[$indexName] = $columns;
}
return $indexesByName;
}
/**
* @deprecated will be removed in 21.4
*
* @param string $table
* @param array $columns
*/
public function dropIndex($table, $columns): void
{
if(empty($table) || empty($columns)) {
return;
}
$columns = array_unique($columns);
sort($columns);
$countColumns = count($columns);
$indexes = $this->getSortedIndexColumnsByIndexName($table);
if(empty($indexes)) {
return;
}
foreach($indexes as $indexName => $indexColumns) {
if(count($indexColumns) !== $countColumns) {
continue;
}
if(count(array_intersect($indexColumns, $columns)) === $countColumns) {
$this->app->DB->Query(sprintf('ALTER TABLE `%s` DROP INDEX `%s`', $table, $indexName));
}
}
}
}
File diff suppressed because it is too large Load Diff
+470
View File
@@ -0,0 +1,470 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
/**
* Class ModuleScriptCache
*
* Cache-Datei mit zufälligem Namen generieren
* @example IncludeJavascriptFiles('chat', $files) => cache/chat-1234abcd.js
*
* Cache-Datei mit festen Dateinamen generieren (erster Parameter muss mit .js oder .css enden)
* @example IncludeJavascriptFiles('chat.js', $files) => cache/chat.js?hash=1234abcd
*/
class ModuleScriptCache
{
/** @var string $baseDir Absoluter Pfad zur Xentral-Installation */
protected $baseDir;
/** @var string $absoluteCacheDir Absoluter Pfad zum Cache-Ordner (muss in www sein) */
protected $absoluteCacheDir;
/** @var string $relativeCacheDir Relativer Pfad zum Cache-Ordner (ausgehend von www) */
protected $relativeCacheDir;
/** @var array $javascriptFiles Absolute Pfade zu Javascript-Dateien die gecached werden sollen */
protected $javascriptFiles = [
'head' => [],
'body' => [],
];
/** @var array $stylesheetFiles Absolute Pfade zu Stylesheet-Dateien die gecached werden sollen */
protected $stylesheetFiles = [];
public function __construct()
{
$this->baseDir = dirname(dirname(__DIR__));
$this->absoluteCacheDir = $this->baseDir . '/www/cache';
$this->relativeCacheDir = './cache';
// Cache-Ordner anzulegen, falls nicht existent
if (!is_dir($this->absoluteCacheDir)) {
if(!mkdir($concurrentDirectory = $this->absoluteCacheDir, 0777) && !is_dir($concurrentDirectory)){
throw new \RuntimeException(sprintf('Directory "%s" was not created', $concurrentDirectory));
}
}
}
/**
* @param string $legacyModuleClassName Kompletter Klassenname das alten Moduls
*
* @return void
*/
public function IncludeModule($legacyModuleClassName)
{
$newModuleName = $this->DetermineNewModuleName($legacyModuleClassName);
// Neuer Modulname konnte nicht ermittelt werden; MODULE_NAME Konstante fehlt im alten Modul
if ($newModuleName === null) {
return;
}
// Javascript- und Stylesheet-Dateien sind als Eigenschaft im Modul definiert
$javascript = $this->GetClassProperty($legacyModuleClassName, 'javascript');
$stylesheet = $this->GetClassProperty($legacyModuleClassName, 'stylesheet');
// Falls nicht im Modul definiert > Defaults verwenden
if (empty($javascript)) {
$javascript = [$this->GetDefaultModuleJavascriptFile($newModuleName)];
}
if (empty($stylesheet)) {
$stylesheet = [$this->GetDefaultModuleStylesheetFile($newModuleName)];
}
$this->IncludeJavascriptFiles($newModuleName, $javascript);
$this->IncludeStylesheetFiles($newModuleName, $stylesheet);
}
/**
* @param string $widgetName
*
* @throws RuntimeException
*
* @return void
*/
public function IncludeWidgetNew($widgetName)
{
$widgetNameCleaned = preg_replace('/[^a-z]+/im', '', $widgetName);
if ($widgetName !== $widgetNameCleaned) {
throw new RuntimeException(sprintf(
'Widget name "%s" contains illegal characters. Valid characters: A-Z, a-z', $widgetName
));
}
if (empty($widgetName)){
throw new RuntimeException('Widget name can not be empty.');
}
$javascript = $stylesheet = [];
// Javascript- und CSS-Dateien aus Bootstrap holen
$widgetBootstrapClass = sprintf('Xentral\\Widgets\\%s\\Bootstrap', $widgetName);
if (class_exists($widgetBootstrapClass, true)) {
$javascript = (array)@forward_static_call([$widgetBootstrapClass, 'registerJavascript']);
foreach ($javascript as $cacheName => $jsFiles) {
$this->IncludeJavascriptFiles($cacheName, $jsFiles);
}
$stylesheets = (array)@forward_static_call([$widgetBootstrapClass, 'registerStylesheets']);
foreach ($stylesheets as $cacheName => $cssFiles) {
$this->IncludeStylesheetFiles($cacheName, $cssFiles);
}
}
// Falls nicht in Bootstrap definiert > Fallback auf Defaults
if (empty($javascript)) {
$javascript = [$this->GetDefaultWidgetJavascriptFile($widgetName)];
$this->IncludeJavascriptFiles($widgetName, $javascript);
}
if (empty($stylesheet)) {
$stylesheet = [$this->GetDefaultWidgetStylesheetFile($widgetName)];
$this->IncludeStylesheetFiles($widgetName, $stylesheet);
}
}
/**
* @param string $cacheName Name unter dem die Cache-Datei zusammengefasst werden
* @param array $files Array mit relativen Pfaden zur Xentral-Installation
*
* @return void
*/
public function IncludeJavascriptFiles($cacheName, array $files)
{
foreach ($files as $section => $file) {
// Neues Verhalten => Trennung nach Head und Body
if ($section === 'head' && is_array($file)) {
$this->IncludeJavascriptHeadFiles($cacheName, $file);
continue;
}
if ($section === 'body' && is_array($file)) {
$this->IncludeJavascriptBodyFiles($cacheName, $file);
continue;
}
// Altes Verhalten (vor Trennung in Head un Body) => Alles in Body
$realPath = realpath($this->baseDir . '/' . $file);
if(is_file($realPath)){
$this->javascriptFiles['body'][$cacheName][] = $realPath;
}
}
}
/**
* @param string $cacheName
* @param array $files
*
* @return void
*/
protected function IncludeJavascriptHeadFiles($cacheName, array $files)
{
// Prüfen ob Dateien existieren
foreach ($files as $file) {
$realPath = realpath($this->baseDir . '/' . $file);
if(is_file($realPath)){
$this->javascriptFiles['head'][$cacheName . '-head'][] = $realPath;
}
}
}
/**
* @param string $cacheName
* @param array $files
*
* @return void
*/
protected function IncludeJavascriptBodyFiles($cacheName, array $files)
{
// Prüfen ob Dateien existieren
foreach ($files as $file) {
$realPath = realpath($this->baseDir . '/' . $file);
if(is_file($realPath)){
$this->javascriptFiles['body'][$cacheName . '-body'][] = $realPath;
}
}
}
/**
* @param string $cacheName Name unter dem die Cache-Datei zusammengefasst werden
* @param array $files Array mit relativen Pfaden zur Xentral-Installation
*
* @return void
*/
public function IncludeStylesheetFiles($cacheName, array $files)
{
// Prüfen ob Dateien existieren
foreach ($files as $file) {
$realPath = realpath($this->baseDir . '/' . $file);
if(is_file($realPath)){
$this->stylesheetFiles[$cacheName][] = $realPath;
}
}
}
/**
* @return string
*/
public function GetStylesheetHtmlTags()
{
if (empty($this->stylesheetFiles)) {
return '';
}
$html = '';
foreach ($this->stylesheetFiles as $moduleName => $files) {
$cacheFilesUri = $this->GetCacheFileUri($moduleName, 'css', $files);
if (!empty($cacheFilesUri)){
$html .= sprintf('<link href="%s" rel="stylesheet" type="text/css" />', $cacheFilesUri);
$html .= "\r\n";
}
}
return $html;
}
/**
* @param string $section [head|body]
*
* @return string
*/
public function GetJavascriptHtmlTags($section = 'body')
{
if ($section !== 'body' && $section !== 'head') {
throw new RuntimeException(sprintf('Invalid section parameter "%s"', $section));
}
if (empty($this->javascriptFiles[$section])) {
return '';
}
$html = '';
foreach ($this->javascriptFiles[$section] as $moduleName => $files) {
$cacheFilesUri = $this->GetCacheFileUri($moduleName, 'js', $files);
if (!empty($cacheFilesUri)){
$html .= sprintf('<script type="text/javascript" src="%s" charset="UTF-8"></script>', $cacheFilesUri);
$html .= "\r\n";
}
}
return $html;
}
/**
* @return string
*/
public function GetAbsoluteCacheDir()
{
return $this->absoluteCacheDir;
}
/**
* @return string
*/
public function GetRelativeCacheDir()
{
return $this->relativeCacheDir;
}
/**
* @return bool
*/
public function IsCacheDirWritable()
{
$randomData = md5(microtime(true));
$tempFile = $this->absoluteCacheDir . '/' . $randomData . '.tmp';
if (!file_put_contents($tempFile, $randomData)) {
return false;
}
unlink($tempFile);
return true;
}
/**
* @param string $moduleName Neuer Modulename
* @param string $fileType [js|css]
* @param array $files Array mit absoluten Pfaden zu Resourcen
*
* @return string
*/
protected function GetCacheFileUri($moduleName, $fileType, array $files = [])
{
if(!in_array($fileType, ['css', 'js'])){
return '';
}
$files = array_unique($files);
// Hash über alle Dateien bilden
$hash = $this->CalculateFilesHash($files);
// Pfad zur Cache-Datei bestimmen
if(substr($moduleName, -3) === '.js' || substr($moduleName, -4) === '.css'){
$hashFilename = $moduleName;
$cacheFileUri = $this->relativeCacheDir . '/' . $hashFilename . '?hash=' . $hash;
}else{
$hashFilename = strtolower($moduleName) . '-' . $hash . '.' . $fileType;
$cacheFileUri = $this->relativeCacheDir . '/' . $hashFilename;
}
// Cache-Datei anlegen, falls nicht existent
$cacheFilePath = $this->absoluteCacheDir . '/' . $hashFilename;
if(!is_file($cacheFilePath)){
$this->CreateCacheFile($files, $cacheFilePath);
}
return $cacheFileUri;
}
/**
* Führt mehrere Dateieninhalte in eine Datei zusammen
*
* @param array $sourceFiles
* @param string $destFile
*/
protected function CreateCacheFile($sourceFiles, $destFile)
{
$destHandle = fopen($destFile, 'wb');
if ($destHandle === false) {
throw new RuntimeException(sprintf(
'Could not create cache file #1. Please make "%s" directory writable. Failed file: %s',
$this->GetRelativeCacheDir(),
$destFile
));
}
foreach ($sourceFiles as $sourceFile) {
$sourceContents = '/********* ' . basename($sourceFile) . ' *********/ ' . "\r\n";
$sourceContents .= file_get_contents($sourceFile);
$sourceContents .= "\r\n\r\n";
$writeResult = fwrite($destHandle, $sourceContents);
if ($writeResult === false) {
throw new RuntimeException(sprintf(
'Could not create cache file #2. Please make "%s" directory writable. Failed file: %s',
$this->GetRelativeCacheDir(),
$destFile
));
}
}
fclose($destHandle);
}
/**
* Berechnet einen Hash über mehrere Dateien
*
* Der Hash wird über das Änderungsdatum und die Dateigröße generiert.
*
* Die Hash-Berechnung über die Dateiinhalte (md5_file) wäre akkurater; ist aber mindestens 10 mal langsamer.
*
* @param array $files
*
* @return string
*/
protected function CalculateFilesHash($files)
{
$md5s = [];
foreach ($files as $file) {
$md5s[] = md5(filemtime($file) . filesize($file));
}
// Hash über alle Dateien ermitteln
return count($md5s) === 1 ? $md5s[0] : md5(implode('', $md5s), false);
}
/**
* @param string $moduleName
*
* @return string Relativer Pfad zur Javascript-Datei im neuen Modul-Verzeichnis
*/
protected function GetDefaultModuleJavascriptFile($moduleName)
{
return sprintf('./classes/Modules/%s/www/js/%s.js', $moduleName, strtolower($moduleName));
}
/**
* @param string $moduleName
*
* @return string Relativer Pfad zur Stylesheet-Datei im neuen Modul-Verzeichnis
*/
protected function GetDefaultModuleStylesheetFile($moduleName)
{
return sprintf('./classes/Modules/%s/www/css/%s.css', $moduleName, strtolower($moduleName));
}
/**
* @param string $widgetName
*
* @return string Relativer Pfad zur Javascript-Datei im neuen Widgets-Verzeichnis
*/
protected function GetDefaultWidgetJavascriptFile($widgetName)
{
return sprintf('./classes/Widgets/%s/www/js/%s.js', $widgetName, strtolower($widgetName));
}
/**
* @param string $widgetName
*
* @return string Relativer Pfad zur Stylesheet-Datei im neuen Widgets-Verzeichnis
*/
protected function GetDefaultWidgetStylesheetFile($widgetName)
{
return sprintf('./classes/Widgets/%s/www/css/%s.css', $widgetName, strtolower($widgetName));
}
/**
* @param string $legacyModuleClassName
* @param string $property
*
* @return array|null
*/
protected function GetClassProperty($legacyModuleClassName, $property)
{
if(!class_exists($legacyModuleClassName, true)){
include_once sprintf('%s/www/pages/%s.php', $this->baseDir, strtolower($legacyModuleClassName));
}
if (!class_exists($legacyModuleClassName, false)) {
return null;
}
if (!property_exists($legacyModuleClassName, $property)) {
return null;
}
$properties = get_class_vars($legacyModuleClassName);
return $properties[$property];
}
/**
* Ermittelt, anhand des alten Moduls, den Name des neuen Moduls
*
* Ist notwendig da die alten Module in Deutsch betitelt sind, und die neuen Module in Englisch.
*
* Beispiel @see Chat::MODULE_NAME
*
* @param string $legacyModuleClassName
*
* @return string|null
*/
protected function DetermineNewModuleName($legacyModuleClassName)
{
if(!class_exists($legacyModuleClassName, true)){
$legacyModuleClassFile = sprintf('%s/www/pages/%s.php', $this->baseDir, strtolower($legacyModuleClassName));
if (is_file($legacyModuleClassFile)) {
include_once $legacyModuleClassFile;
}
}
if(!defined($legacyModuleClassName . '::MODULE_NAME')){
return null;
}
return constant($legacyModuleClassName . '::MODULE_NAME');
}
}
File diff suppressed because it is too large Load Diff
+85
View File
@@ -0,0 +1,85 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
class ObjectAPI
{
private $app;
function __construct($app)
{
$this->app = &$app;
}
function Get($name)
{
if(file_exists("objectapi/mysql/object.$name.php")) {
include_once("objectapi/mysql/object.$name.php");
//echo "es gibt ein modifiziertes objecy";
$classname = "Obj".ucfirst($name);
return new $classname($this->app);
} else {
//echo "es gibt nur das generiewrte";
include_once("objectapi/mysql/_gen/object.gen.$name.php");
//echo "es gibt ein modifiziertes objecy";
$classname = "ObjGen".ucfirst($name);
return new $classname($this->app);
}
}
/*
function CreatePage($widgets,$tplfile)
{
if(count($widgets)>0){
foreach($widgets as $key=>$varname) {
// pruefen ob es ein widget sein soll
if(preg_match("/^[\[]WIDGET_/",$varname)) {
$classname = "";
$varname = str_replace('[','',$varname);
$varname = str_replace(']','',$varname);
list($type,$classname,$action)=split('_',$varname);
// pruefe ob es ein abgeleitetes gibt wenn nicht starte das generierte
if(file_exists("widgets/widget.".strtolower($classname).".php")) {
$filename = "widget.".strtolower($classname).".php";
$classname = "Widget".ucfirst(strtolower($classname));
$action = ucfirst(strtolower($action));
include_once("widgets/$filename");
} else {
$filename = "widget.gen.".strtolower($classname).".php";
$classname = "WidgetGen".ucfirst(strtolower($classname));
$action = ucfirst(strtolower($action));
include_once("widgets/_gen/$filename");
}
$mywidget = new $classname(&$this->app,$varname);
$mywidget->$action();
}
}
}
$this->app->Tpl->Parse(PAGE,$tplfile);
}
*/
}
?>
+301
View File
@@ -0,0 +1,301 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
/// central config board for the engine
class Page
{
var $engine;
/** @var Application $app */
/**
* Page constructor.
*
* @param Application $app
*/
function __construct($app)
{
$this->app = $app;
//$this->engine = &$engine;
}
/// load a themeset set
function LoadTheme($theme)
{
//$this->app->Tpl->ReadTemplatesFromPath("themes/$theme/templates/");
$this->app->Tpl->ReadTemplatesFromPath(__DIR__."/../../www/themes/$theme/templates/");
}
/// show complete page
function Show()
{
return $this->app->Tpl->FinalParse('page.tpl');
}
/**
* @param array $menu
*
* @return array
*/
public function removeDoubleMenuEntries($menu)
{
if(empty($menu)) {
return $menu;
}
foreach($menu as $key=>$value) {
if($value['first'][2] !== 'direktzugriff'){
if(!empty($value['sec']) && count($value['sec']) > 0){
$secKeys = [];
foreach ($value['sec'] as $key2 => $secnav) {
$secNavString = implode('|', $secnav);
if(in_array($secNavString, $secKeys)) {
unset($menu[$key]['sec'][$key2], $value['sec'][$key2]);
continue;
}
$secKeys[] = $secNavString;
}
}
}
}
return $menu;
}
/**
* @param array $menu
* @param string $module
* @param string $action
*
* @return array
*/
public function getSelectionKeysByModuleAction($menu, $module, $action)
{
$moduleKey = -1;
$actionKey = -1;
$moduleKey3 = -1;
$actionKey3 = -1;
foreach($menu as $key => $value){
if($value['first'][2]!=='direktzugriff') {
if(!empty($value['sec']) && count($value['sec'])>0){
foreach($value['sec'] as $key2 => $secnav){
$isModuleSecNav = $module == $secnav[1];
if($isModuleSecNav && $action == $secnav[2]) {
return [$key, $key2];
}
if($isModuleSecNav && $secnav[2] === 'list' && $moduleKey3 === -1) {
$actionKey3 = $key2;
$moduleKey3 = $key;
}
elseif($isModuleSecNav && $moduleKey === -1) {
$actionKey = $key2;
$moduleKey = $key;
}
}
}
}
}
if($moduleKey3 != -1) {
return [$moduleKey3, $actionKey3];
}
return [$moduleKey, $actionKey];
}
/**
* @param array $menu
* @param bool $returnJson
* @param null|string $aktmodule
* @param null|string $aktaction
*
* @return array|void
*/
public function CreateNavigation($menu, $returnJson = false, $aktmodule = null, $aktaction = null)
{
if(method_exists($this->app->erp, 'NavigationHooks')) {
$this->app->erp->NavigationHooks($menu);
}
$menu = $this->removeDoubleMenuEntries($menu);
if(isset($menu) && count($menu)>0){
if($aktmodule === null) {
$aktmodule = (string)$this->app->Secure->GetGET('module');
}
if($aktaction === null) {
$aktaction = (string)$this->app->Secure->GetGET('action');
}
$actKeys = $this->getSelectionKeysByModuleAction($menu, $aktmodule, $aktaction);
$aktmodulekey = $actKeys[0];
$aktactionkey = $actKeys[1];
$jsonMenu = [];
$breadCrumb= [];
foreach($menu as $key=>$value){
$main = [
'active' => false,
'sec' => [],
'link' => null,
];
if($value['first'][2]!=='direktzugriff') {
if($aktmodulekey == $key) {
$main['active'] = true;
}
if($value['first'][2]!='') {
$main['title'] = $this->app->Tpl->pruefeuebersetzung($value['first'][0],'menu');
$main['original_title'] = $value['first'][0];
}
else {
if($aktmodule == $value['first'][1]) {
$main['active'] = true;
}
$main['module'] = $value['first'][1];
$main['link'] = 'index.php?module='.$value['first'][1].'&top='.base64_encode($value['first'][0]);
$main['original_title'] = $value['first'][0];
$main['title'] = $this->app->Tpl->pruefeuebersetzung($value['first'][0],'menu');
}
}
else {
if($value['first'][2]!='') {
$main['original_title'] = $value['first'][0];
$main['title'] = $this->app->Tpl->pruefeuebersetzung($value['first'][0],'menu');
}
}
if(isset($value['sec']) && count($value['sec'])>0){
foreach($value['sec'] as $key2 => $secnav){
$sec = [
'active' => false,
];
if($secnav[2]!='') {
$sec['module'] = $secnav[1];
$sec['action'] = $secnav[2];
$sec['link'] = 'index.php?module='.$secnav[1].'&action='.$secnav[2].'&top='.base64_encode($value['first'][0]);
$sec['original_title'] = $secnav[0];
$sec['title'] = $this->app->Tpl->pruefeuebersetzung($secnav[0],'menu');
if($aktmodule == $secnav[1]) {
$breadCrumb[] = [
'link' => 'index.php?module='.$secnav[1].'&action='.$secnav[2].'&top='.base64_encode($value['first'][0]),
'title' => $this->app->Tpl->pruefeuebersetzung($secnav[0],'menu'),
];
}
}
else {
$sec['module'] = $secnav[1];
$sec['link'] = 'href="index.php?module='.$secnav[1].'&top='.base64_encode($value['first'][0]);
$sec['original_title'] = $secnav[0];
$sec['title'] = $this->app->Tpl->pruefeuebersetzung($secnav[0],'menu');
$breadCrumb[] = [
'link' => 'index.php?module='.$secnav[1].'&action='.$secnav[2].'&top='.base64_encode($value['first'][0]),
'title' => $this->app->Tpl->pruefeuebersetzung($secnav[0],'menu'),
];
}
if($aktmodulekey == $key && $aktactionkey == $key2)
{
$sec['active'] = true;
}
if(!empty($sec)) {
$main['sec'][] = $sec;
}
}
}
$jsonMenu[] = $main;
}
if($returnJson) {
return $jsonMenu;
}
$this->drawMenu($menu, $aktmodulekey, $aktmodule, $aktactionkey);
$this->app->Tpl->Add(
'BODYENDE',
'<script id="mainMenuJson" type="application/json">'.json_encode($jsonMenu).'</script>'
);
$this->app->Tpl->Add(
'BODYENDE',
'<script id="breadCrumbJson" type="application/json">'.json_encode($breadCrumb).'</script>'
);
}
}
/**
* @param array $menu
* @param string $aktmodulekey
* @param string $aktmodule
* @param int $aktactionkey
*/
public function drawMenu($menu, $aktmodulekey, $aktmodule, $aktactionkey) {
foreach($menu as $key=>$value){
$aktiv = 0;
if($value['first'][2]!=='direktzugriff') {
if($aktmodulekey == $key) {
$aktiv = 1;
}
if($value['first'][2]!='') {
$this->app->Tpl->Set('FIRSTNAV',' href="#">'.$this->app->Tpl->pruefeuebersetzung($value['first'][0],'menu').'</a>');
if($aktiv) {
$this->app->Tpl->Set('FIRSTNAVCLASS','active');
}
else{
$this->app->Tpl->Set('FIRSTNAVCLASS','');
}
}
else {
if($aktmodule == $value['first'][1]) {
$this->app->Tpl->Set('FIRSTNAVCLASS','active');
}
else {
$this->app->Tpl->Set('FIRSTNAVCLASS','');
}
$this->app->Tpl->Set('FIRSTNAV',' href="index.php?module='.$value['first'][1].'&top='.base64_encode($value['first'][0]).'" >'.$this->app->Tpl->pruefeuebersetzung($value['first'][0],'menu').'</a>');
}
}
else {
if($value['first'][2]!="") {
$this->app->Tpl->Set('FIRSTNAVCLASS','navnichtdirekt');
$this->app->Tpl->Set('FIRSTNAV',' href="#" >'.$this->app->Tpl->pruefeuebersetzung($value['first'][0],'menu').'</a>');
}
}
$this->app->Tpl->Parse('NAV','firstnav.tpl');
if(isset($value['sec']) && count($value['sec'])>0){
$this->app->Tpl->Add('NAV','<ul class="submenu">');
foreach($value['sec'] as $key2 => $secnav){
if($secnav[2]!='') {
$this->app->Tpl->Set('SECNAV',' href="index.php?module='.$secnav[1].'&action='.$secnav[2].'&top='.base64_encode($value['first'][0]).'">'.$this->app->Tpl->pruefeuebersetzung($secnav[0],'menu').'</a>');
if($aktmodule == $secnav[1]) {
$this->app->Tpl->Set('BREADCRUMB','<a href="index.php?module='.$secnav[1].'&action='.$secnav[2].'&top='.base64_encode($value['first'][0]).'">'.$this->app->Tpl->pruefeuebersetzung($secnav[0],'menu').'</a>&nbsp;&#9658;&nbsp;');
}
}
else {
$this->app->Tpl->Set('SECNAV',' href="index.php?module='.$secnav[1].'&top='.base64_encode($value['first'][0]).'">'.$this->app->Tpl->pruefeuebersetzung($secnav[0],'menu').'aa</a>');
$this->app->Tpl->Set('BREADCRUMB','<a href="index.php?module='.$secnav[1].'&top='.base64_encode($value['first'][0]).'">'.$secnav[0].'aa</a>&nbsp;&#9658;&nbsp;');
}
if($aktmodulekey == $key && $aktactionkey == $key2)
{
$this->app->Tpl->Set('SECNAVCLASS','active');
}
else {
$this->app->Tpl->Set('SECNAVCLASS','');
}
$this->app->Tpl->Parse('NAV','secnav.tpl');
}
$this->app->Tpl->Add('NAV','</ul></li>');
}
}
}
}
+87
View File
@@ -0,0 +1,87 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
class PageBuilder
{
private $app;
function __construct($app)
{
$this->app = &$app;
}
function CreateGen($tplfile)
{
$widgets = $this->app->Tpl->GetVars("pages/content/_gen/".$tplfile);
$this->CreatePage($widgets,$tplfile);
}
function Create($tplfile)
{
$widgets = $this->app->Tpl->GetVars("pages/content/".$tplfile);
$this->CreatePage($widgets,$tplfile);
}
function CreatePage($widgets,$tplfile)
{
if(count($widgets)>0){
foreach($widgets as $key=>$varname) {
// pruefen ob es ein widget sein soll
if(preg_match("/^[\[]WIDGET_/",$varname)) {
$classname = "";
$varname = str_replace('[','',$varname);
$varname = str_replace(']','',$varname);
if(count(explode('_',$varname))>3)
{
list($type,$classname,$tmp,$action)=explode('_',$varname);
$classname = $classname."_".$tmp;
}
else {
list($type,$classname,$action)=explode('_',$varname);
}
// pruefe ob es ein abgeleitetes gibt wenn nicht starte das generierte
$classnamecustom = $classname.'Custom';
$filenamecustom = strtolower($classname.'_custom');
if(file_exists("widgets/widget.".$filenamecustom.".php")) {
$classname = "Widget".ucfirst(strtolower($classname)).'Custom';
$filename = "widget.".$filenamecustom.".php";
include_once("widgets/$filename");
}elseif(file_exists("widgets/widget.".strtolower($classname).".php")) {
$filename = "widget.".strtolower($classname).".php";
$classname = "Widget".ucfirst(strtolower($classname));
$action = ucfirst(strtolower($action));
include_once("widgets/$filename");
} else {
$filename = "widget.gen.".strtolower($classname).".php";
$classname = "WidgetGen".ucfirst(strtolower($classname));
$action = ucfirst(strtolower($action));
include_once("widgets/_gen/$filename");
}
$mywidget = new $classname($this->app,$varname);
$mywidget->$action();
// $mywidget->__destruct();
}
}
}
$this->app->Tpl->Parse('PAGE',$tplfile);
}
}
?>
+144
View File
@@ -0,0 +1,144 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
/// special layer for webapplications
class phpWFAPI
{
function __construct(&$app)
{
$this->app=&$app;
}
function ReBuildPageFrame()
{
$this->app->Tpl->ResetParser();
$this->BuildPageFrame();
}
function BuildPageFrame()
{
$this->app->Tpl->ReadTemplatesFromPath(__DIR__."/../defaulttemplates/");
// build template tree
$this->app->Page->LoadTheme($this->app->WFconf['defaulttheme']);
if($this->app->User->GetType()=="")
$this->app->Page->CreateNavigation($this->app->WFconf['menu'][$this->app->WFconf['defaultgroup']]);
else
$this->app->Page->CreateNavigation($this->app->WFconf['menu'][$this->app->User->GetType()]);
// start acutally application instance
$this->app->Tpl->ReadTemplatesFromPath("pages/content/_gen");
$this->app->Tpl->ReadTemplatesFromPath("pages/content/");
}
function StartRequestedCommand()
{
$defaultpage = $this->app->WFconf['defaultpage'];
$defaultpageaction = $this->app->WFconf['defaultpageaction'];
$module = $this->app->Secure->GetGET('module','alpha');
$action = $this->app->Secure->GetGET('action','alpha');
if(!file_exists("pages/".$module.".php"))
$module = $defaultpage;
if($action=="")
$action = $defaultpageaction;
if(!$this->app->acl->Check($this->app->User->GetType(),$module,$action))
return;
// start module
if(file_exists("pages/".$module.".php"))
{
include("pages/".$module.".php");
//create dynamical an object
$constr=strtoupper($module[0]).substr($module, 1);
$myApp = new $constr($this->app);
}
else
{
echo $this->app->WFM->Error("Module <b>$module</b> doesn't exists in pages/");
}
$this->app->acl->CheckTimeOut();
}
/// mit dem "erstellen Formular" einfach bearbeiten liste + formular anzeigen
function EasyTableList($tablename,$cols,$parsetarget,$pkname,$delmsg,$delmsgcol)
{
// show list
// create html table
$table = new HTMLTable("0","100%");
$table->AddRowAsHeading($cols);
$all = $this->app->DB->SelectTable($tablename,$cols);
$table->AddField($all);
$action = $this->app->Secure->GetGET("action","alpha");
$module = $this->app->Secure->GetGET("module","alpha");
$table->AddCompleteCol(0,
"<a href=\"index.php?module=$module&action=$action&id=%col%\">bearbeiten</a>");
$table->AddCompleteCol(0,
"<a href=\"#\" onclick=\"str = confirm('{$delmsg}');
if(str!='' & str!=null)
window.document.location.href='index.php?module=$module&action=$action&id=%col%&formaction=delete';\">
loeschen</a>",$delmsgcol);
$table->ChangingRowColors('#ffffff','#dddddd');
$this->app->Tpl->Set($parsetarget,$table->Get());
}
function Message($msg,$parsetarget='MSGBOX')
{
$this->app->Tpl->Add('MSGBOXTEXT',$msg);
$this->app->Tpl->Parse($parsetarget,"messagebox.tpl");
}
// emailvorlage aus db senden
function EmailFromTemplate($template,$to,$values)
{
$betreff = $this->app->DB->Select("SELECT betreff
FROM emailvorlagen WHERE name='$template' LIMIT 1");
$nachricht = $this->app->DB->Select("SELECT nachricht
FROM emailvorlagen WHERE name='$template' LIMIT 1");
if(count($values) > 0)
{
foreach($values as $key=>$value)
{
$nachricht = str_replace("%".$key."%",$value,$nachricht);
$betreff = str_replace("%".$key."%",$value,$betreff);
}
}
$nachricht = str_replace('#BR#',"\n",$nachricht);
mail($to,$betreff,$nachricht,"From: ActConnect Team <info@actconnect.de>");
}
}
?>
+245
View File
@@ -0,0 +1,245 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
/**
* Login + Accesslayer for OTP Keys
*
* @package picosafeaes
* @subpackage class.picosafe.php
* @author WaWision GmbH
* @version 1.0
* ...
*/
class PicosafeLogin {
var $error_message;
var $timestamp_valid_password;
var $user_aes;
var $user_datablock;
var $user_counter;
var $last_valid_counter;
function __construct($timezone="Europe/Berlin")
{
// time zone for server + picosafe aes
date_default_timezone_set($timezone);
// 3 minutes
$this->seconds_valid_password=180;
}
// please overload these methods
function GetUserAES()
{
// PLEASE FILL WITH YOUR DATA!!
// 32 signs
//return "soopu9goBoay9vongooth2ooLu8keed1";
return $this->user_aes;//"soopu9goBoay9vongooth2ooLu8keed1";
}
function GetUserCounter()
{
// PLEASE FILL WITH YOUR DATA!!
return $this->user_counter;//179;
}
function GetUserDatablock()
{
// PLEASE FILL WITH YOUR DATA!!
// 10 signs
return $this->user_datablock;//"eeng5jo7th";
}
function SetUserLastCounter($username,$counter)
{
// PLEASE FILL WITH YOUR DATA!!
// set internal counter from user to new value givn from givenOtp
}
function IsPicosafeLocked($username)
{
// PLEASE FILL WITH YOUR DATA!!
return false;
}
function GetServerTimestamp()
{
// instead of the local time function a server time or something other can be used
date_default_timezone_set("UTC");
return time();
}
/************************************************/
// or use set methods to load user values from external
function SetUserAES($aes)
{
$this->user_aes = $aes;
}
function SetUserDatablock($datablock)
{
$this->user_datablock = $datablock;
}
function SetUserCounter($counter)
{
$this->user_counter = $counter;
}
function GetLastValidCounter()
{
return $this->last_valid_counter;
}
/************************************************/
function LoginOTP($givenOtp)//,$aes,$datablock,$counter)//$username)
{
$aes = $this->GetUserAES();
// $aes = substr($server_aes, 0, 32);
// $data = substr($server_aes, 32, 10);
$counter = $this->GetUserCounter();
$data = $this->GetUserDatablock();
$locked = $this->IsPicosafeLocked();
// check if device is locked? perhaps the user lost his device ....
if($locked)
{
$this->error_message = "Picosafe is locked";
return false;
}
$datablock = null;
$result = $this->ParseOTP($givenOtp,$aes,$datablock);
//check if is the right aes for the given user
if($result['datablock']!=$datablock && $datablock!="")
{
$this->error_message = "Wrong Key to given username";
return false;
}
// server counter is greater than aes counter
if($result['counter'] < $counter)
{
$this->error_message = "Server counter is greater than aes counter";
return false;
}
// time differences
$time_diff_abs_between_aes_server = abs($this->GetServerTimestamp() - $result['timestamp']);
if($time_diff_abs_between_aes_server > $this->seconds_valid_password)
{
$this->error_message = "Time difference between server and aes greater than ".$this->seconds_valid_password." seconds";
return false;
}
// Update Counter in server
//$this->SetUserLastCounter($username,$result['counter']);
$this->last_valid_counter = $result['counter'];
return true;
}
function ParseOTP($givenOtp,$aes,$datablock = null)
{
// base64 Kodierung des Sticks korrigieren
$givenOtp = rtrim($givenOtp);
// Sonderzeichen in korrekte Sonderzeichen umwandeln
// (diese werden vom Stick anders vorgegeben, um von
// unterschiedl. Tastaturlayouts unabhängig zu werden)
$cgivenOtp = strlen($givenOtp);
for($i = 0; $i < $cgivenOtp; $i++) {
if($givenOtp[$i] == "!") { $givenOtp[$i] = "/"; }
elseif($givenOtp[$i] == ".") { $givenOtp[$i] = "="; }
elseif($givenOtp[$i] == "-") { $givenOtp[$i] = "+"; }
}
// erstes Zeichen pruefen ob z oder y
// abhaengig davon alle y durch z ersetzen und umgekehrt
$z = $givenOtp[0];
$crypted = substr($givenOtp, 1);
if($z == "y" or $z == "Y") {
$ccrypted = strlen($crypted);
for($i = 0; $i < $ccrypted; $i++) {
if ($crypted[$i] == 'y') { $crypted[$i] = "z"; }
elseif($crypted[$i] == 'Y') { $crypted[$i] = "Z"; }
elseif($crypted[$i] == 'z') { $crypted[$i] = "y"; }
elseif($crypted[$i] == 'Z') { $crypted[$i] = "Y"; }
}
}
if($z == "Y" or $z == "Z") {
$ccrypted = strlen($crypted);
for($i = 0; $i < $ccrypted; $i++) {
if(ctype_upper($crypted[$i])) {
$crypted[$i] = strtolower($crypted[$i]);
} else {
$crypted[$i] = strtoupper($crypted[$i]);
}
}
}
$crypted = base64_decode($crypted);
// gegebenes One Time Passwort mit AES entschluesseln
$td = mcrypt_module_open("rijndael-128", "", "ecb", "");
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_DEV_URANDOM);
mcrypt_generic_init($td, $aes, $iv);
$plain = mdecrypt_generic($td, $crypted);
// aktueller Zaehlstand
$i = substr($plain, 0,1);
$j = substr($plain, 1,1);
$n = ord($i) + (ord($j) << 8);
$timestamp = (ord($plain[12]) << 24) + (ord($plain[13]) << 16) + (ord($plain[14]) << 8) + ord($plain[15]);
// entschluesseltes Passwort aufteilen in
// und Datenblock
$plain = substr($plain, 2, 10);
$result['counter']=$n;
$result['datablock']=$plain;
$result['timestamp']=$timestamp;
/*
echo "<br>";
echo "Nummer: " . $n . "<br>";
echo "Datenblock: " . $plain . " (" . $data . ") <br>";
echo "Timestamp: " . $timestamp . "<br>";
echo "Datetime: " . date("d.m.Y H:i:s",$timestamp) . "<br>";
*/
//printf("4 Byte: %x \n", substr($plain,10));
return $result;
}
}
+340
View File
@@ -0,0 +1,340 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
/// Secure Layer, SQL Inject. Check, Syntax Check
class Secure
{
public $GET;
public $POST;
/**
* Secure constructor.
*
* @param ApplicationCore $app
*/
public function __construct($app){
$this->app = $app;
// clear global variables, that everybody have to go over secure layer
$this->GET = $_GET;
if(isset($this->GET['msgs']) && isset($this->app->Location)) {
$this->GET['msg'] = $this->app->Location->getMessage($this->GET['msgs']);
}
// $_GET="";
$this->POST = $_POST;
// $_POST="";
if(!isset($this->app->stringcleaner) && file_exists(__DIR__. '/class.stringcleaner.php')) {
if(!class_exists('StringCleaner')) {
require_once __DIR__ . '/class.stringcleaner.php';
}
$this->app->stringcleaner = new StringCleaner($this->app);
}
$this->AddRule('notempty','reg','.'); // at least one sign
$this->AddRule('alpha','reg','[a-zA-Z]');
$this->AddRule('digit','reg','[0-9]');
$this->AddRule('space','reg','[ ]');
$this->AddRule('specialchars','reg','[_-]');
$this->AddRule('email','reg','^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.([a-zA-Z]{2,4})$');
$this->AddRule('datum','reg','([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{4})');
$this->AddRule('username','glue','alpha+digit');
$this->AddRule('password','glue','alpha+digit+specialchars');
}
/**
* @param string $name
* @param null $rule
* @param string $maxlength
* @param string $sqlcheckoff
*
* @return array|mixed|string
*/
public function GetGET($name,$rule=null,$maxlength='',$sqlcheckoff='')
{
if($name === 'msg' && isset($this->app->erp) && method_exists($this, 'xss_clean')) {
$ret = $this->Syntax(isset($this->GET[$name])?$this->GET[$name]:'','',$maxlength,$sqlcheckoff);
$ret = $this->app->erp->base64_url_decode($ret);
if(strpos($ret,'"button"') === false){
$ret = $this->xss_clean($ret);
}
return $this->app->erp->base64_url_encode($ret);
}
if($rule === null) {
$rule = $this->NameToRule($name);
}
return $this->Syntax(isset($this->GET[$name])?$this->GET[$name]:'',$rule,$maxlength,$sqlcheckoff);
}
function NameToRule($name)
{
switch($name)
{
case 'id':
return 'doppelid';
break;
case 'sid':
return 'alphadigits';
break;
case 'module':
case 'smodule':
case 'action':
case 'saction':
return 'module';
break;
case 'cmd':
return 'moduleminus';
break;
}
return 'nothtml';
}
public function GetPOST($name,$rule=null,$maxlength="",$sqlcheckoff="")
{
if($rule === null) {
$rule = $this->NameToRule($name);
if(isset($this->POST['ishtml_cke_'.$name]) && $this->POST['ishtml_cke_'.$name]) {
$rule = 'nojs';
}
}
return $this->Syntax(isset($this->POST[$name])?$this->POST[$name]:'',$rule,$maxlength,$sqlcheckoff);
}
public function GetPOSTForForms($name,$rule="",$maxlength="",$sqlcheckoff="")
{
return $this->SyntaxForForms($this->POST[$name],$rule,$maxlength,$sqlcheckoff);
}
public function CleanString($string, $rule='nohtml',$sqlcheckoff='')
{
return $this->Syntax($string, $rule, '', $sqlcheckoff);
}
public function xss_clean($data)
{
return $this->app->stringcleaner->xss_clean($data);
}
public function GetPOSTArray()
{
if(!empty($this->POST) && count($this->POST)>0)
{
foreach($this->POST as $key=>$value)
{
$key = $this->GetPOST($key,"alpha+digit+specialchars",20);
$ret[$key]=$this->GetPOST($value);
}
}
if(!empty($ret))
{
return $ret;
}
return null;
}
public function GetGETArray()
{
if(!empty($this->GET) && count($this->GET)>0)
{
foreach($this->GET as $key=>$value)
{
$key = $this->GetGET($key,"alpha+digit+specialchars",20);
$ret[$key]=$this->GetGET($value);
}
}
if(!empty($ret))
{
return $ret;
}
return null;
}
function stripallslashes($string) {
while(strstr($string,'\\')) {
$string = stripslashes($string);
}
return $string;
}
public function smartstripslashes($str) {
$cd1 = substr_count($str, "\"");
$cd2 = substr_count($str, "\\\"");
$cs1 = substr_count($str, "'");
$cs2 = substr_count($str, "\\'");
$tmp = strtr($str, array("\\\"" => "", "\\'" => ""));
$cb1 = substr_count($tmp, "\\");
$cb2 = substr_count($tmp, "\\\\");
if ($cd1 == $cd2 && $cs1 == $cs2 && $cb1 == 2 * $cb2) {
return strtr($str, array("\\\"" => "\"", "\\'" => "'", "\\\\" => "\\"));
}
return $str;
}
public function SyntaxForForms($value,$rule,$maxlength="",$sqlcheckoff="")
{
return $value;//mysqli_real_escape_string($this->app->DB->connection,$value);//mysqli_real_escape_string($value);
}
// check actual value with given rule
public function Syntax($value,$rule,$maxlength='',$sqlcheckoff='')
{
$striptags = false;
if(is_array($value))
{
if($sqlcheckoff != '')
{
return $value;
}
foreach($value as $k => $v)
{
if(is_array($v))
{
$value[$k] = $v;
}else{
$v = str_replace("\xef\xbb\xbf","NONBLOCKINGZERO",$v);
if($striptags){
$v = $this->stripallslashes($v);
$v = $this->smartstripslashes($v);
$v = $this->app->erp->superentities($v);
}
$value[$k] = $this->app->DB->real_escape_string($v);
}
}
return $value;
}
$value = str_replace("\xef\xbb\xbf","NONBLOCKINGZERO",$value);
if($striptags){
$value = $this->stripallslashes($value);
$value = $this->smartstripslashes($value);
$value = $this->app->erp->superentities($value);
}
if(!empty($this->app->stringcleaner)) {
if( $sqlcheckoff == '') {
return $this->app->DB->real_escape_string($this->app->stringcleaner->CleanString($value, $rule));
}
return $this->app->stringcleaner->CleanString($value, $rule);
}
if($rule === 'nohtml') {
if( $sqlcheckoff == '') {
return $this->app->DB->real_escape_string(strip_tags($value));
}
return strip_tags($value);
}
if($rule === 'nojs') {
if( $sqlcheckoff == '') {
return $this->app->DB->real_escape_string($this->xss_clean($value));
}
return $this->xss_clean($value);
}
if($rule=='' && $sqlcheckoff == '') {
return $this->app->DB->real_escape_string($value);//mysqli_real_escape_string($value);
}
if($rule=='' && $sqlcheckoff != '') {
return $value;
}
// build complete regexp
// check if rule exists
if($this->GetRegexp($rule)!=''){
//$v = '/^['.$this->GetRegexp($rule).']+$/';
$v = $this->GetRegexp($rule);
if (preg_match_all('/'.$v.'/i', $value, $teffer) ) {
if($sqlcheckoff==''){
return $this->app->DB->real_escape_string($value);//mysqli_real_escape_string($value);
}
return $value;
}
return '';
}
echo "<table border=\"1\" width=\"100%\" bgcolor=\"#FFB6C1\">
<tr><td>Rule <b>$rule</b> doesn't exists!</td></tr></table>";
return '';
}
function RuleCheck($value,$rule)
{
$found = false;
if(!empty($this->app->stringcleaner)) {
$value_ = $this->app->stringcleaner->RuleCheck($value, $rule, $found);
if($found) {
if($value_) {
return true;
}
return false;
}
}
$v = $this->GetRegexp($rule);
if (preg_match_all('/'.$v.'/i', $value, $teffer) ){
return true;
}
return false;
}
function AddRule($name,$type,$rule)
{
// type: reg = regular expression
// type: glue ( already exists rules copy to new e.g. number+digit)
$this->rules[$name]=array('type'=>$type,'rule'=>$rule);
}
// get complete regexp by rule name
function GetRegexp($rule)
{
$rules = explode('+',$rule);
$ret = '';
foreach($rules as $key) {
// check if rule is last in glue string
if($this->rules[$key]['type']==='glue') {
$subrules = explode('+',$this->rules[$key]['rule']);
if(count($subrules)>0) {
foreach($subrules as $subkey) {
$ret .= $this->GetRegexp($subkey);
}
}
}
elseif($this->rules[$key]['type']==='reg') {
$ret .= $this->rules[$key]['rule'];
}
}
if($ret==''){
$ret = 'none';
}
return $ret;
}
}
+443
View File
@@ -0,0 +1,443 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
class WawiString
{
function __construct()
{
}
function Convert($value,$input,$output)
{
if($input=="")
return $value;
/*if (strpos($a, '\\') !== false)
$input = str_replace('/','\/',$input);*/
$array = $this->FindPercentValues($input);
$regexp = $this->BuildRegExp($array);
$elements =
preg_split($regexp,$value,-1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
// input und elements stimmmen ueberein
$newout = $output;
$i = 0;
foreach($array as $key=>$value)
{
$newout = str_replace($key,isset($elements[$i])?$elements[$i]:'',$newout);
$i++;
}
return $newout;
}
/**
* @param string $string
*
* @return string
*/
public function removeUtf8Bom($string) {
if(!is_string($string) || strlen($string)< 3) {
return $string;
}
if(ord($string[0]) === 239 && ord($string[1]) === 187 && ord($string[2]) === 191) {
return substr($string,3);
}
return $string;
}
function BuildRegExp($array)
{
$regexp = '/^';
foreach($array as $value)
{
$value = str_replace('.','\.',$value);
$value = str_replace('+','\+',$value);
$value = str_replace('*','\*',$value);
$value = str_replace('?','\?',$value);
$regexp .= '(\S+)'.$value;
}
$regexp .= '/';
return $regexp;
}
function FindPercentValues($pattern)
{
preg_match_all('/(?:(%[0-9]+)|.)/i', $pattern, $matches);
$hash = '';
$collect = '';
$start = true;
foreach($matches[1] as $key=>$value)
{
if($value=="")
$collecting = true;
else
{
$collecting = false;
$oldhash = isset($hash)?$hash:null;
$hash = $value;
}
if(!$collecting)
{
if(!$start)
$replace[$oldhash] = $collect;
$collect="";
}
else
$collect .=$matches[0][$key];
$start = false;
}
$replace[$hash] = $collect;
return $replace;
}
function encodeText($string)
{
$string = str_replace("\\r\\n","#BR#",$string);
$string = str_replace("\n","#BR#",$string);
$encoded = htmlspecialchars(stripslashes($string), ENT_QUOTES);
return $encoded;
}
function decodeText($_str, $_form=true)
{
if ($_form) {
$_str = str_replace("#BR#", "\r\n", $_str);
}
else {
$_str = str_replace("#BR#", "<br>", $_str);
}
return($_str);
}
function valid_utf8( $string )
{
return !((bool)preg_match('~\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF\xC0\xC1~ms',$string));
}
/**
* @param mixed $text
*
* @return string
*/
public function fixeUmlaute($text) {
if(!is_string($text)) {
return $text;
}
$umlaute = $this->getUmlauteArray();
return str_replace(array_keys($umlaute),array_values($umlaute), $text);
}
/**
* @return array
*/
public function getUmlauteArray() {
return array( 'ü'=>'ü', 'ä'=>'ä', 'ö'=>'ö', 'Ö'=>'Ö', 'Ã?'=>'ß','ß'=>'ß', 'à '=>'à', 'á'=>'á', 'â'=>'â', 'ã'=>'ã', 'ù'=>'ù', 'ú'=>'ú', 'û'=>'û', 'Ù'=>'Ù', 'Ú'=>'Ú', 'Û'=>'Û', 'Ü'=>'Ü', 'ò'=>'ò', 'ó'=>'ó', 'ô'=>'ô', 'è'=>'è', 'é'=>'é', 'ê'=>'ê', 'ë'=>'ë', 'À'=>'À', 'Ã<81>'=>'Á', 'Â'=>'Â', 'Ã'=>'Ã', 'Ä'=>'Ä', 'Ã…'=>'Å', 'Ç'=>'Ç', 'È'=>'È', 'É'=>'É', 'Ê'=>'Ê', 'Ë'=>'Ë', 'ÃŒ'=>'Ì', 'Ã<8d>'=>'Í', 'ÃŽ'=>'Î', 'Ã<8f>'=>'Ï', 'Ñ'=>'Ñ', 'Ã’'=>'Ò', 'Ó'=>'Ó', 'Ô'=>'Ô', 'Õ'=>'Õ', 'Ø'=>'Ø', 'Ã¥'=>'å', 'æ'=>'æ', 'ç'=>'ç', 'ì'=>'ì', 'í'=>'í', 'î'=>'î', 'ï'=>'ï', 'ð'=>'ð', 'ñ'=>'ñ', 'õ'=>'õ', 'ø'=>'ø', 'ý'=>'ý', 'ÿ'=>'ÿ', '€'=>'€' );
}
function unicode_decode($content) {
$ISO10646XHTMLTrans = array(
"&"."#34;" => "&quot;",
"&"."#38;" => "&amp;",
"&"."#39;" => "&apos;",
"&"."#60;" => "&lt;",
"&"."#62;" => "&gt;",
"&"."#128;" => "&euro;",
"&"."#160;" => "",
"&"."#161;" => "&iexcl;",
"&"."#162;" => "&cent;",
"&"."#163;" => "&pound;",
"&"."#164;" => "&curren;",
"&"."#165;" => "&yen;",
"&"."#166;" => "&brvbar;",
"&"."#167;" => "&sect;",
"&"."#168;" => "&uml;",
"&"."#169;" => "&copy;",
"&"."#170;" => "&ordf;",
"&"."#171;" => "&laquo;",
"&"."#172;" => "&not;",
"&"."#173;" => "­",
"&"."#174;" => "&reg;",
"&"."#175;" => "&macr;",
"&"."#176;" => "&deg;",
"&"."#177;" => "&plusmn;",
"&"."#178;" => "&sup2;",
"&"."#179;" => "&sup3;",
"&"."#180;" => "&acute;",
"&"."#181;" => "&micro;",
"&"."#182;" => "&para;",
"&"."#183;" => "&middot;",
"&"."#184;" => "&cedil;",
"&"."#185;" => "&sup1;",
"&"."#186;" => "&ordm;",
"&"."#187;" => "&raquo;",
"&"."#188;" => "&frac14;",
"&"."#189;" => "&frac12;",
"&"."#190;" => "&frac34;",
"&"."#191;" => "&iquest;",
"&"."#192;" => "&Agrave;",
"&"."#193;" => "&Aacute;",
"&"."#194;" => "&Acirc;",
"&"."#195;" => "&Atilde;",
"&"."#196;" => "&Auml;",
"&"."#197;" => "&Aring;",
"&"."#198;" => "&AElig;",
"&"."#199;" => "&Ccedil;",
"&"."#200;" => "&Egrave;",
"&"."#201;" => "&Eacute;",
"&"."#202;" => "&Ecirc;",
"&"."#203;" => "&Euml;",
"&"."#204;" => "&Igrave;",
"&"."#205;" => "&Iacute;",
"&"."#206;" => "&Icirc;",
"&"."#207;" => "&Iuml;",
"&"."#208;" => "&ETH;",
"&"."#209;" => "&Ntilde;",
"&"."#210;" => "&Ograve;",
"&"."#211;" => "&Oacute;",
"&"."#212;" => "&Ocirc;",
"&"."#213;" => "&Otilde;",
"&"."#214;" => "&Ouml;",
"&"."#215;" => "&times;",
"&"."#216;" => "&Oslash;",
"&"."#217;" => "&Ugrave;",
"&"."#218;" => "&Uacute;",
"&"."#219;" => "&Ucirc;",
"&"."#220;" => "&Uuml;",
"&"."#221;" => "&Yacute;",
"&"."#222;" => "&THORN;",
"&"."#223;" => "&szlig;",
"&"."#224;" => "&agrave;",
"&"."#225;" => "&aacute;",
"&"."#226;" => "&acirc;",
"&"."#227;" => "&atilde;",
"&"."#228;" => "&auml;",
"&"."#229;" => "&aring;",
"&"."#230;" => "&aelig;",
"&"."#231;" => "&ccedil;",
"&"."#232;" => "&egrave;",
"&"."#233;" => "&eacute;",
"&"."#234;" => "&ecirc;",
"&"."#235;" => "&euml;",
"&"."#236;" => "&igrave;",
"&"."#237;" => "&iacute;",
"&"."#238;" => "&icirc;",
"&"."#239;" => "&iuml;",
"&"."#240;" => "&eth;",
"&"."#241;" => "&ntilde;",
"&"."#242;" => "&ograve;",
"&"."#243;" => "&oacute;",
"&"."#244;" => "&ocirc;",
"&"."#245;" => "&otilde;",
"&"."#246;" => "&ouml;",
"&"."#247;" => "&divide;",
"&"."#248;" => "&oslash;",
"&"."#249;" => "&ugrave;",
"&"."#250;" => "&uacute;",
"&"."#251;" => "&ucirc;",
"&"."#252;" => "&uuml;",
"&"."#253;" => "&yacute;",
"&"."#254;" => "&thorn;",
"&"."#255;" => "&yuml;",
"&"."#338;" => "&OElig;",
"&"."#339;" => "&oelig;",
"&"."#352;" => "&Scaron;",
"&"."#353;" => "&scaron;",
"&"."#376;" => "&Yuml;",
"&"."#402;" => "&fnof;",
"&"."#710;" => "&circ;",
"&"."#732;" => "&tilde;",
"&"."#913;" => "&Alpha;",
"&"."#914;" => "&Beta;",
"&"."#915;" => "&Gamma;",
"&"."#916;" => "&Delta;",
"&"."#917;" => "&Epsilon;",
"&"."#918;" => "&Zeta;",
"&"."#919;" => "&Eta;",
"&"."#920;" => "&Theta;",
"&"."#921;" => "&Iota;",
"&"."#922;" => "&Kappa;",
"&"."#923;" => "&Lambda;",
"&"."#924;" => "&Mu;",
"&"."#925;" => "&Nu;",
"&"."#926;" => "&Xi;",
"&"."#927;" => "&Omicron;",
"&"."#928;" => "&Pi;",
"&"."#929;" => "&Rho;",
"&"."#931;" => "&Sigma;",
"&"."#932;" => "&Tau;",
"&"."#933;" => "&Upsilon;",
"&"."#934;" => "&Phi;",
"&"."#935;" => "&Chi;",
"&"."#936;" => "&Psi;",
"&"."#937;" => "&Omega;",
"&"."#945;" => "&alpha;",
"&"."#946;" => "&beta;",
"&"."#947;" => "&gamma;",
"&"."#948;" => "&delta;",
"&"."#949;" => "&epsilon;",
"&"."#950;" => "&zeta;",
"&"."#951;" => "&eta;",
"&"."#952;" => "&theta;",
"&"."#953;" => "&iota;",
"&"."#954;" => "&kappa;",
"&"."#955;" => "&lambda;",
"&"."#956;" => "&mu;",
"&"."#957;" => "&nu;",
"&"."#958;" => "&xi;",
"&"."#959;" => "&omicron;",
"&"."#960;" => "&pi;",
"&"."#961;" => "&rho;",
"&"."#962;" => "&sigmaf;",
"&"."#963;" => "&sigma;",
"&"."#964;" => "&tau;",
"&"."#965;" => "&upsilon;",
"&"."#966;" => "&phi;",
"&"."#967;" => "&chi;",
"&"."#968;" => "&psi;",
"&"."#969;" => "&omega;",
"&"."#977;" => "&thetasym;",
"&"."#978;" => "&upsih;",
"&"."#982;" => "&piv;",
"&"."#8194;" => "&ensp;",
"&"."#8195;" => "&emsp;",
"&"."#8201;" => "&thinsp;",
"&"."#8204;" => "&zwnj;",
"&"."#8205;" => "&zwj;",
"&"."#8206;" => "&lrm;",
"&"."#8207;" => "&rlm;",
"&"."#8211;" => "&ndash;",
"&"."#8212;" => "&mdash;",
"&"."#8216;" => "&lsquo;",
"&"."#8217;" => "&rsquo;",
"&"."#8218;" => "&sbquo;",
"&"."#8220;" => "&ldquo;",
"&"."#8221;" => "&rdquo;",
"&"."#8222;" => "&bdquo;",
"&"."#8224;" => "&dagger;",
"&"."#8225;" => "&Dagger;",
"&"."#8226;" => "&bull;",
"&"."#8230;" => "&hellip;",
"&"."#8240;" => "&permil;",
"&"."#8242;" => "&prime;",
"&"."#8243;" => "&Prime;",
"&"."#8249;" => "&lsaquo;",
"&"."#8250;" => "&rsaquo;",
"&"."#8254;" => "&oline;",
"&"."#8260;" => "&frasl;",
"&"."#8364;" => "&euro;",
"&"."#8465;" => "&image;",
"&"."#8472;" => "&weierp;",
"&"."#8476;" => "&real;",
"&"."#8482;" => "&trade;",
"&"."#8501;" => "&alefsym;",
"&"."#8592;" => "&larr;",
"&"."#8593;" => "&uarr;",
"&"."#8594;" => "&rarr;",
"&"."#8595;" => "&darr;",
"&"."#8596;" => "&harr;",
"&"."#8629;" => "&crarr;",
"&"."#8656;" => "&lArr;",
"&"."#8657;" => "&uArr;",
"&"."#8658;" => "&rArr;",
"&"."#8659;" => "&dArr;",
"&"."#8660;" => "&hArr;",
"&"."#8704;" => "&forall;",
"&"."#8706;" => "&part;",
"&"."#8707;" => "&exist;",
"&"."#8709;" => "&empty;",
"&"."#8711;" => "&nabla;",
"&"."#8712;" => "&isin;",
"&"."#8713;" => "&notin;",
"&"."#8715;" => "&ni;",
"&"."#8719;" => "&prod;",
"&"."#8721;" => "&sum;",
"&"."#8722;" => "&minus;",
"&"."#8727;" => "&lowast;",
"&"."#8730;" => "&radic;",
"&"."#8733;" => "&prop;",
"&"."#8734;" => "&infin;",
"&"."#8736;" => "&ang;",
"&"."#8743;" => "&and;",
"&"."#8744;" => "&or;",
"&"."#8745;" => "&cap;",
"&"."#8746;" => "&cup;",
"&"."#8747;" => "&int;",
"&"."#8756;" => "&there4;",
"&"."#8764;" => "&sim;",
"&"."#8773;" => "&cong;",
"&"."#8776;" => "&asymp;",
"&"."#8800;" => "&ne;",
"&"."#8801;" => "&equiv;",
"&"."#8804;" => "&le;",
"&"."#8805;" => "&ge;",
"&"."#8834;" => "&sub;",
"&"."#8835;" => "&sup;",
"&"."#8836;" => "&nsub;",
"&"."#8838;" => "&sube;",
"&"."#8839;" => "&supe;",
"&"."#8853;" => "&oplus;",
"&"."#8855;" => "&otimes;",
"&"."#8869;" => "&perp;",
"&"."#8901;" => "&sdot;",
"&"."#8968;" => "&lceil;",
"&"."#8969;" => "&rceil;",
"&"."#8970;" => "&lfloor;",
"&"."#8971;" => "&rfloor;",
"&"."#9001;" => "&lang;",
"&"."#9002;" => "&rang;",
"&"."#9674;" => "&loz;",
"&"."#9824;" => "&spades;",
"&"."#9827;" => "&clubs;",
"&"."#9829;" => "&hearts;",
"&"."#9830;" => "&diams;"
);
return str_replace(array_keys($ISO10646XHTMLTrans), array_values($ISO10646XHTMLTrans), $content);
}
/**
* @param string $string
*
* @return string
*/
public function ReadyForPDF($string='')
{
return trim(
html_entity_decode(
str_replace(
['“','„','',"&rsquo;","&apos;","NONBLOCKINGZERO"],
['"','','-',"'","'",''],
$string
),
ENT_QUOTES,
'UTF-8'
)
);
}
}
+451
View File
@@ -0,0 +1,451 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
class StringCleaner
{
private $elements;
private $htmlpuriferconfig;
private $htmlpurifer;
private $ruleregexps;
/** @var Application */
private $app;
/**
* StringCleaner constructor.
*
* @param null|Application $app
*/
public function __construct($app = null)
{
$this->app = $app;
if(class_exists('HTMLPurifier_Config')) {
$this->htmlpuriferconfig = HTMLPurifier_Config::createDefault();
$this->htmlpuriferconfig->set('Core.Encoding', 'UTF-8');
$this->htmlpuriferconfig->set('Attr.AllowedFrameTargets', ['_blank']); // Allow hyperlinks with target="_blank"
//$this->htmlpuriferconfig->set('HTML.AllowedElements', 'h1,h2,h3,h4,h5,h6,p,a,strong,em,ol,ul,li,img,param,div,br,form,label,fieldset,input,textarea,select,option');
$this->htmlpurifer = new HTMLPurifier($this->htmlpuriferconfig);
}
$this->elements = array('nohtml'=> array('ust_befreit','abweichendelieferadresse','bestellungsart','bearbeiter','datum','lieferdatum','name','anrede','partner','packstation_inhaber','packstation_station','packstation_ident','packstation_plz','packstation_ort','partnerid','kennen','ihrebestellnummer'
,'abteilung','unterabteilung','ansprechpartner','adresszusatz','strasse','land','bundesstaat','plz','ort','versandart','internet','transaktionsnummer','vertrieb','zahlungsweise'
,'lieferabteilung','lieferunterabteilung','lieferansprechpartner','lieferadresszusatz','lieferstrasse','lieferland','lieferbundesstaat','lieferplz','lieferort'
,'bank_inhaber','bank_institut','bank_blz','bank_konto'
,'email','telefon','telefax','ustid','partner','projekt','herstellernummer','ean','nummer','name_de','name_ean'),
'nojs' => array('anabregstext','anabregstext_en','uebersicht_de','uebersicht_en','kurztext_de','kurztext_en','internebemerkung','internebezeichnung','freitext'));
$this->rulechecks = array('digit'=>'/^[0-9]+$/'
,'alpha'=>'/^[a-zA-Z]+$/'
,'alphadigit'=>'/^[0-9a-zA-Z]+$/'
,'username'=>'/^[0-9a-zA-Z\.\-]+$/'
,'space'=>'/^[\x20]+$/'
,'module'=>'/^[0-9a-zA-Z\_]$/'
,'password'=>'/^[^\s\n]{1}[^\n]{5}.*$/'
,'email'=>'/^[^@\s\x00-\x20]+@[^@\s\x00-\x20\.]+\.[^@\s\x00-\x20\.]+[^@\s\x00-\x20]*$/'
);
$this->ruleregexps = array(
'digit'=>'/[^0-9]/'
,'username'=>'/[^0-9a-zA-Z\.\-]/'
,'alpha'=>'/[^a-zA-Z]/'
,'alphadigits'=>'/[^0-9a-zA-Z]/'
,'module'=>'/[^0-9a-zA-Z\_]/'
,'moduleminus'=>'/[^0-9a-zA-Z\_\-]/'
,'alphadigitsspecial'=>'/[^0-9a-zA-Z\_\.\(\)]/'
,'base64'=>'/[^0-9a-zA-Z\=\+\-\_\/]/'
);
}
function SyntaxByElement($key, $default = '')
{
foreach($this->elements as $type => $arr) {
if(in_array($key, $arr)) {
return $type;
}
}
return $default;
}
function CleanSQLReturn($value, $columnname, $default = '')
{
if($value == '' || is_numeric($value))
{
return $value;
}
if(in_array($columnname, array('nummer','name','kundennummer','bezeichnung','bezeichnunglieferant','lieferantennummer','mitarbeiternummer','name_de','name_en',
'kurzbezeichnung','abkuerzung',
'strasse','plz','ort','land','ansprechpartner','abteilung','unterabteilung',
'liefername','lieferstrasse','lieferplz','lieferort','lieferland','lieferansprechpartner','lieferabteilung','lieferunterabteilung'))){
return strip_tags($value);
}
if($default == 'xss_clean')
{
return $this->xss_clean($value, false);
}
if($this->htmlpurifer)
{
return $this->htmlpurifer->purify($value);
}
return $value;
}
function RuleCheck($string, $rule = null, &$found = false)
{
if(isset($this->rulechecks[$rule]))
{
$found = true;
return preg_match_all($this->rulechecks[$rule], $string, $dummy);
}
switch($rule)
{
case 'datum':
$found = true;
if(preg_match_all('/([0-9]+)\.([0-9]+)\.$/', $string, $matches))
{
$string = $matches[1][0].'.'.$matches[2][0].'.'.date('Y');
}
try {
if($x = new DateTime($string)) {
return $x->format('Y') > 0;
}
}
catch (Exception $e) {
return false;
}
return false;
break;
}
}
function CheckSQLHtml($sql)
{
$start = 0;
$len = strlen($sql);
$lvl = 0;
$col = 0;
$ret = array(0);
$instring = false;
for($i = $start; $i < $len; $i++)
{
$char = $sql[$i];
switch($char)
{
case "'":
if($instring)
{
if($sql[$i-1] != '\\')
{
$instring = false;
}
}else{
if($sql[$i-1] != '\\'){
$instring = true;
}
}
break;
case "(":
if($instring)
{
}else{
$lvl++;
}
break;
case ")":
if($instring)
{
}else{
$lvl--;
}
break;
case "<":
if($instring)
{
if(preg_match('/<[a-zA-Z]/',$char.$sql[$i+1]))
{
if($ret[$col] != 2)
{
$ret[$col] = 1;
}
}
}
break;
case ',':
if($instring)
{
}else{
if($lvl == 0)
{
$col++;
$ret[$col] = 0;
}
}
break;
case 'o':
case 'O':
if($instring)
{
if($i < $len -4)
{
if(strtolower(substr($sql, $i, 2)) == 'on')
{
if(preg_match('/^on[a-z]+(\s*)=/', substr($sql, $i)))
{
$ret[$col] = 2;
}
}
}
}
break;
case 'F':
case 'f':
if($instring)
{
}else{
if($lvl == 0)
{
if($i < $len - 4)
{
if(strtolower(substr($sql, $i, 4)) == 'from')
{
break 2;
}
}
}
}
break;
}
}
$where = strripos($sql, 'where');
$restsql = substr($sql, $i, $where - $i);
if(preg_match('/<[a-zA-Z]/', $restsql))
{
if(preg_match('/on[a-z]+(\s*)=/',$restsql))
{
if($ret)
{
foreach($ret as $k => $v)
{
$ret[$k] = 2;
}
}
}else{
if($ret)
{
foreach($ret as $k => $v)
{
if($v != 2)
{
$ret[$k] = 1;
}
}
}
}
}
return $ret;
}
public function CleanString($string, $rule = null, &$found = false)
{
if(is_null($rule))
{
$rule = 'nothml';
}
switch($rule)
{
case 'email':
if($this->RuleCheck($string, $rule))
{
return $string;
}
return '';
break;
case 'nohtml':
$found = true;
if($string == '' || is_numeric($string))
{
return $string;
}
if(strpos($string,'<') === false)
{
return $string;
}
return strip_tags($string);
break;
case 'datum':
$found = true;
$string_ = $string;
if(preg_match_all('/([0-9]+)\.([0-9]+)\.$/', $string, $matches))
{
$string_ = $matches[1][0].'.'.$matches[2][0].'.'.date('Y');
}
try
{
if($x = new DateTime($string_))
{
if($x->format('Y') <= 0)
{
return '';
}
return $string;
}
} catch (Exception $e) {
return '';
}
return '';
break;
case 'xss_clean':
$found = true;
if($string == '' || is_numeric($string))
{
return $string;
}
if(strpos($string,'<') === false){
return $string;
}
return $this->xss_clean($string, false);
break;
case 'nojs':
$found = true;
if($string == '' || is_numeric($string))return $string;
if(strpos($string,'<') === false)return $string;
if($this->htmlpurifer)
{
return $this->htmlpurifer->purify($string);
}
return $this->xss_clean($string);
break;
case 'id':
$found = true;
if((String)$string === '')
{
return $string;
}
return (int)$string;
break;
case 'doppelid':
$found = true;
if((String)$string === '')
{
return $string;
}
$stringa = explode('-', $string, 2);
if(count($stringa) == 1)return (int)$stringa[0];
return ($stringa[0]===''?'':(int)$stringa[0]).'-'.(int)$stringa[1];
break;
case 'module':
$found = true;
return preg_replace ($this->ruleregexps[$rule], '' , $string);
break;
default:
if(isset($this->ruleregexps[$rule]))
{
$found = true;
return preg_replace ($this->ruleregexps[$rule], '' , $string);
}
break;
}
return $string;
}
public function xss_clean($data, $usepurify = true)
{
if($usepurify && !empty($this->htmlpurifer))
{
return $this->htmlpurifer->purify($data);
}
// Fix &entity\n;
$data = str_replace(array('&amp;','&lt;','&gt;'), array('&amp;amp;','&amp;lt;','&amp;gt;'), $data);
$data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data);
$data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data);
$data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');
return $data;
// Remove any attribute starting with "on" or xmlns
$data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);
// Remove javascript: and vbscript: protocols
$data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);
// Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);
// Remove namespaced elements (we do not need them)
$data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);
do
{
// Remove really unwanted tags
$old_data = $data;
$data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
}
while ($old_data !== $data);
return $data;
}
function XMLArray_clean(&$xml, $lvl = 0)
{
if(is_string($xml))
{
}elseif(is_array($xml))
{
if(count($xml) > 0)
{
foreach($xml as $k => $v)
{
if(is_string($v))
{
$xml[$k] = $this->CleanString($v, $this->SyntaxByElement($k,'nojs'));
}
if($lvl < 10)
{
$this->XMLArray_clean($v, $lvl + 1);
}
}
}
}elseif(is_object($xml))
{
if(count($xml) > 0)
{
foreach($xml as $k => $v)
{
if(count($v) > 0)
{
if($lvl < 10)
{
$this->XMLArray_clean($v, $lvl + 1);
}
}elseif((String)$v != '')
{
if(isset($xml->$k))
{
//$xml->$k = $this->CleanString($v, $this->SyntaxByElement($k,'nojs'));
}
}
}
}
}
return $xml;
}
}
+773
View File
@@ -0,0 +1,773 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
/****************************************************************************
1. zu jedem Template muss es in einem anderen Template eine Variable geben
in htmlheader.tpl PAGE fuer page.tpl
****************************************************************************/
/// represent a template (file.tpl)
class ThemeTemplate {
var $NAME; //Name des Templates
var $PATH; //PFAD des Templates
var $parsed; //Zustand
var $ORIGINAL; //Parse - Text Vorlage
var $VARS; //assoziatives Array mit Variablennamen als Index
var $Elements;
var $vararraycreated;
function __construct($_path, $_file){
/*
$fp=@fopen($_path.$_file,"r");
if($fp){
if(filesize($_path.$_file)>0)
$contents = fread ($fp, filesize($_path.$_file));
fclose($fp);
}*/
$this->vararraycreated = false;
$this->PATH=$_path;
$this->NAME=$_file;
$this->readFile();
}
function readFile()
{
$_path = $this->PATH;
$_file = $this->NAME;
$fp=@fopen($_path.$_file,"r");
if($fp){
if(filesize($_path.$_file)>0)
$contents = fread ($fp, filesize($_path.$_file));
fclose($fp);
}
$this->ORIGINAL=isset($contents)?$contents:'';
//$this->CreateVarArray();
}
function CreateVarArray(){
$this->vararraycreated = true;
$this->SetVar("",'');
$pattern = '/((\[[A-Z0-9_]+\]))/';
preg_match_all($pattern,$this->ORIGINAL,$matches, PREG_OFFSET_CAPTURE);
if(!$matches)return;
//TODO Parser umbauen, damit Variablen nicht doppelt genommen werden.
if(count($matches[0]) > 0)
{
$cmatches = count($matches[0]);
for($i=0;$i<$cmatches;$i++)
{
$this->Elements[$i]['before'] = substr($this->ORIGINAL, $i==0?0:($matches[0][$i-1][1] +strlen($matches[0][$i-1][0]) ), $matches[0][$i][1] - ($i==0 ?0 : ($matches[0][$i-1][1]+strlen($matches[0][$i-1][0])) ) );
$this->Elements[$i]['el'] = $matches[0][$i][0];
$this->Elements[$i]['el'] = str_replace('[','',$this->Elements[$i]['el']);
$this->Elements[$i]['el'] = str_replace(']','',$this->Elements[$i]['el']);
if($i > 0)$this->Elements[$i-1]['nach'] = $this->Elements[$i]['before'];
}
$this->Elements[count($matches[0])-1]['nach'] = substr($this->ORIGINAL, $matches[0][count($matches[0])-1][1]+strlen($matches[0][count($matches[0])-1][0]));
for($i=0;$i<$cmatches;$i++)
{
$matches[0][$i][0] = str_replace('[','',$matches[0][$i][0]);
$matches[0][$i][0] = str_replace(']','',$matches[0][$i][0]);
if(!isset($this->VARS[$matches[0][$i][0]]))
{
$this->SetVar($matches[0][$i][0],'');
}
}
}
}
function Parsed()
{
return 1;
if($this->parsed!=1)
{
$fp=@fopen($this->PATH.$this->NAME,"r");
if($fp){
$contents = fread ($fp, filesize($this->PATH.$this->FILE));
fclose($fp);
}
$this->ORIGINAL=$contents;
$this->CreateVarArray();
}
$this->parsed=1;
}
function AddVar($_var, $_value){ $this->VARS[$_var]=$this->VARS[$_var].$_value; }
function SetVar($_var, $_value){ $this->VARS[$_var]=$_value; }
}
/*********************** Class PcmsTemplate ****************************/
/// Main Parser for building the html skin (gui)
class TemplateParser {
var $TEMPLATELIST;
var $VARARRAY;
var $VARVARARRAY;
/**
* TemplateParser constructor.
*
* @param Application $app
*/
public function __construct($app){
$this->app = $app;
$this->TEMPLATELIST=null;
$this->VARVARARRAY = null;
}
public function htmlspecialchars($value)
{
$value = str_replace(array('&ouml;','&auml;','&uuml;','&Ouml;','&Auuml;','&Uuml;','&szlig;'),array('ö','ä','ü','Ö','Ä','Ü','ß'),$value);
$value = htmlspecialchars($value);
return $value;
}
public function addTextLink($_var, $link, $text, $target = null)
{
$ret = '<a href="'.$link.'"'.($target?' target="'.$target.'"':'').'>'.$this->htmlspecialchars($text).'</a>';
if($_var === 'return')
{
return $ret;
}
return $this->Add($_var, $ret);
}
public function addInput($_var, $value, $type = 'text', $class = '', $id = '', $name = '')
{
$options = array('type'=>$type);
if($id != '')
{
$options['id'] = $id;
}
if($name != '')
{
$options['name'] = $name;
}
return $this->addButton($_var, $value, null, null, $class, $options);
}
public function addMessage($class, $text, $html = false, $_var = 'MESSAGE')
{
$ret = '';
switch($class)
{
case 'error':
case 'warning':
case 'info':
break;
default:
$class = 'info';
break;
}
if(!$html)
{
$text = $this->htmlspecialchars($text);
}
$ret .= '<div class="'.$class.'">'.$text.'</div>';
if($_var === 'return')
{
return $ret;
}
return $this->app->Tpl->Add($_var, $ret);
}
public function addSelect($_var, $id, $name, $options, $selected = '', $class = '')
{
$extra = '';
foreach(array('id','name','class') as $k)
{
if($$k != '')
{
$extra .= ' '.$k.'="'.str_replace('"','&quot;',$$k).'"';
}
}
$ret = '<select'.$extra.'>';
if(is_array($options))
{
foreach($options as $k => $v)
{
$ret .= '<option'.
($k == $selected?' selected="selected"':'').' value="'.str_replace('"','&quot;',$k).
'">'.$this->htmlspecialchars($v).
'</option>';
}
}
$ret .= '</select>';
if($_var === 'return')
{
return $ret;
}
return $this->app->Tpl->Add($_var, $ret);
}
public function addButton($_var, $text, $link = null, $target = null, $class = '', $options = null)
{
$ret = '';
$type = 'button';
$extra = '';
$extraa = array();
if(isset($options['type'])) {
$type = $options['type'];
}
if($link) {
$ret .= '<a href="'.$link.'"'.($target?' target="'.$target.'"':'').'>';
}
if(is_array($options)) {
foreach($options as $k => $v) {
switch($k) {
case 'name':
case 'id':
$extraa[] = $k.'="'.str_replace('"','&quot;',(String)$v).'"';
break;
default:
if(strpos($k,'data-') === 0) {
$extraa[] = $k.'="'.str_replace('"','&quot;',(String)$v).'"';
}
break;
}
}
}
if(count($extraa) > 0){
$extra = ' ' . implode(' ', $extraa);
}
$ret .= '<input type="'.$type.'" value="'.str_replace('"','&quot;',$text).'" '.
($class!=''?' class="'.str_replace('"','',$class).'"':'').
$extra.' />';
if($link) {
$ret .= '</a>';
}
if($_var === 'return') {
return $ret;
}
$this->app->Tpl->Add($_var, $ret);
return '';
}
function GetVars($tplfile)
{
$fp=@fopen($tplfile,"r");
if($fp){
$contents = fread ($fp, filesize($tplfile));
fclose($fp);
}
$suchmuster = '/[\[][A-Z_]+[\]]/';
preg_match_all($suchmuster, $contents, $treffer);
return $treffer[0];
}
function ResetParser()
{
unset($this->TEMPLATELIST);
unset($this->VARARRAY);
}
function ReadTemplatesFromPath($_path){
$this->loadUebersetzung();
$this->addPath($_path);
$directory=opendir($_path);
$i = 1;
while ($file=readdir($directory)){
if(strstr($file, '.tpl')){
$i++;
$this->TEMPLATELIST[$file] = new ThemeTemplate($_path,$file);
}
}
closedir($directory);
}
private function loadUebersetzung(){
}
protected function addPath($_path)
{
$rpos = strrpos($_path, '/www/');
if($rpos !== false)
{
$this->pathes[] = substr($_path, $rpos);
}else{
$this->pathes[] = $_path;
}
}
protected function pathLoaded($_path)
{
if(!$this->pathes)return false;
$rpos = strrpos($_path, '/www/');
if($rpos !== false)
{
$_path = substr($_path, $rpos);
}
if(in_array($_path, $this->pathes))return true;
return false;
}
function LoadPathes()
{
$pathes = array(dirname(dirname(__DIR__))."/www/widgets/templates/_gen/",
dirname(dirname(__DIR__))."/www/widgets/templates/",
dirname(dirname(__DIR__))."/www/themes/".$this->app->Conf->WFconf['defaulttheme']."/templates/",
dirname(dirname(__DIR__))."/www/pages/content/_gen/",
dirname(dirname(__DIR__))."/www/pages/content/"
);
foreach($pathes as $path)
{
if(!$this->pathLoaded($path))$this->ReadTemplatesFromPath($path);
}
}
function CreateVarArray(){
foreach($this->TEMPLATELIST as $template=>$templatename){
if(count($this->TEMPLATELIST[$template]->VARS) > 0){
foreach($this->TEMPLATELIST[$template]->VARS as $key=>$value){
$this->VARARRAY[$key]=$value;
}
}
}
}
function ShowVariables(){
foreach($this->VARARRAY as $key=>$value)
echo "<b>$key =></b>".htmlspecialchars($value)."<br>";
}
function ParseVariables($text){
foreach($this->VARARRAY as $key=>$value)
{
if($key=!"")
$text = str_replace('['.$key.']',$value,$text);
}
// fill empty vars
return $text;
}
function ShowTemplates(){
foreach ($this->TEMPLATELIST as $key=> $value){
foreach ($value as $key1=> $text){
if(!is_array($text))echo "$key ".htmlspecialchars($text)."<br>";
if(is_array($text))foreach($text as $key2=>$value2) echo $key2." ".$value2;
}
echo '<br><br>';
}
}
function SetText($_var, $_value)
{
$this->VARARRAY[$_var]= $this->htmlspecialchars($_value);
}
function AddText($_var,$_value, $variable = false){
$this->VARARRAY[$_var]=isset($this->VARARRAY[$_var])?$this->VARARRAY[$_var].$this->htmlspecialchars($_value):$this->htmlspecialchars($_value);
if($variable)
$this->VARVARARRAY[$_var] = $variable;
}
function Set($_var,$_value, $variable = false){
$this->VARARRAY[$_var]=$_value;
if($variable)
$this->VARVARARRAY[$_var] = $variable;
}
function Add($_var,$_value, $variable = false){
$this->VARARRAY[$_var]=isset($this->VARARRAY[$_var])?$this->VARARRAY[$_var].$_value:$_value;
if($variable)
$this->VARVARARRAY[$_var] = $variable;
}
function Get($_var){
return $this->VARARRAY[$_var]." ";
}
function Output($_template)
{
echo $this->app->erp->ClearDataBeforeOutput($this->ParseTranslation($this->Parse("",$_template,1)));
}
function OutputAsString($_template)
{
return $this->app->erp->ClearDataBeforeOutput($this->Parse("",$_template,1));
}
function pruefeuebersetzung($text, $_type = 'page', $element = null, $withspan = true)
{
if(is_null($this->uebersetzungmodulvorhanden))
{
$this->uebersetzungmodulvorhanden = true;
if(!$this->app->erp->ModulVorhanden('wawision_uebersetzung'))$this->uebersetzungmodulvorhanden = false;
}
if(!$this->uebersetzungmodulvorhanden)return $text;
if(is_array($text))
{
foreach($text as $k => $v)
{
$text[$k] = $this->pruefeuebersetzung($v, $_type, $element, $withspan);
}
return $text;
}
if($text === '')return '';
if(is_null($element) && isset($this->app->Secure) && method_exists($this->app->Secure, 'GetGET'))$element = $this->app->Secure->GetGET('module');
$start = '';
$end = '';
return $start.$text.$end;
}
function ParseTranslation($text)
{
$pattern = '/((\{\|)(.*?)(\|\}))/s';
$ok = preg_match_all($pattern,$text,$matches, PREG_OFFSET_CAPTURE);
if(!$ok)return $text;
//TODO Parser umbauen, damit Variablen nicht doppelt genommen werden.
if(count($matches[0]) > 0)
{
$cmatches = count($matches[0]);
for($i=0;$i<$cmatches;$i++)
{
$Elements[$i]['before'] = substr($text, $i==0?0:($matches[0][$i-1][1] +strlen($matches[0][$i-1][0]) ), $matches[0][$i][1] - ($i==0 ?0 : ($matches[0][$i-1][1]+strlen($matches[0][$i-1][0])) ) );
$Elements[$i]['el'] = $matches[0][$i][0];
$Elements[$i]['el'] = str_replace('{|','',$Elements[$i]['el']);
$Elements[$i]['el'] = str_replace('|}','',$Elements[$i]['el']);
if($i > 0)$Elements[$i-1]['nach'] = $Elements[$i]['before'];
}
$Elements[count($matches[0])-1]['nach'] = substr($text, $matches[0][count($matches[0])-1][1]+strlen($matches[0][count($matches[0])-1][0]));
}else return $text;
$cmatches = count($matches[0]);
for($i=0;$i<$cmatches;$i++)
{
$matches[0][$i][0] = str_replace('{|','',$matches[0][$i][0]);
$matches[0][$i][0] = str_replace('|}','',$matches[0][$i][0]);
}
$ret = "";
if($Elements){
foreach($Elements as $k => $v)
{
if(isset($v['before']) && $k == 0)$ret .= $v['before'];
if(isset($v['before']) && strlen((String)$v['before']) > 0 && substr($v['before'],-1) == '"')
{
$pos1 = strripos($v['before'],'input');
$pos2 = strripos($v['before'],'<');
if($pos2 !== false && $pos1 !== false && $pos2 < $pos1)
{
$ret .= $this->pruefeuebersetzung($v['el'],'page',null, '****');
}else{
$ret .= $this->pruefeuebersetzung($v['el'],'page',null, false);
}
}else{
$ret .= $this->pruefeuebersetzung($v['el']);
}
if(isset($v['nach']))$ret .= $v['nach'];
}
}
return $ret;
}
function Parse($_var, $_template,$return=0){
if(!isset($this->TEMPLATELIST[$_template]))
{
$this->LoadPathes();
}
// check if custom template exists_template
$checkcustom = str_replace('.tpl','_custom.tpl',$_template);
if(isset($this->TEMPLATELIST[$checkcustom])) $_template = $checkcustom;
//$this->AjaxParse();
if($_var == 'PAGE')$this->app->erp->ParseMenu();
$this->ParseVarVars();
if($_template!=""){
if(isset($this->TEMPLATELIST[$_template]) && !($this->TEMPLATELIST[$_template]->vararraycreated))
{
$this->TEMPLATELIST[$_template]->CreateVarArray();
}
//alle template variablen aufuellen mit den werten aus VARARRAY
if(isset($this->TEMPLATELIST[$_template]) && isset($this->TEMPLATELIST[$_template]->VARS) && count($this->TEMPLATELIST[$_template]->VARS)>0){
foreach ($this->TEMPLATELIST[$_template]->VARS as $key=> $value){
$this->TEMPLATELIST[$_template]->SetVar($key,isset($this->VARARRAY[$key])?$this->VARARRAY[$key]:'');
}
//ORIGINAL auffuellen
$tmptpl = $this->TEMPLATELIST[$_template]->ORIGINAL;
foreach ($this->TEMPLATELIST[$_template]->VARS as $key=>$value){
if(!is_numeric($key) && $key!="")
$tmptpl = str_replace("[".$key."]",$value, $tmptpl);
}
} else $tmptpl = '';
//aufgefuelltes ORIGINAL in $t_var add($_var,ORIGINAL)
if($return==1)
return $tmptpl;
else
$this->Add($_var,$tmptpl);
}
}
function AddAndParse($_var, $_value, $_varparse, $_templateparse){
$this->Set($_var, $_value);
$this->Parse($_varparse,$_templateparse);
}
function ParseVarVars()
{
$pattern = '/((\[[A-Z0-9_]+\]))/';
if(!empty($this->VARVARARRAY) && is_array($this->VARVARARRAY))
{
foreach($this->VARVARARRAY as $k => $el)
{
preg_match_all($pattern,$this->VARARRAY[$k],$matches, PREG_OFFSET_CAPTURE);
$cmatches = $matches?count($matches[0]):0;
for($i=0;$i<$cmatches;$i++)
{
$matches[0][$i][0] = str_replace('[','',$matches[0][$i][0]);
$matches[0][$i][0] = str_replace(']','',$matches[0][$i][0]);
if(isset($this->VARARRAY[$matches[0][$i][0]]))
{
$this->VARARRAY[$k] = str_replace('['.$matches[0][$i][0].']',$this->VARARRAY[$matches[0][$i][0]],$this->VARARRAY[$k]);
}
}
unset($matches);
}
}
}
function FinalParse($_template){
$printtype = '';
if(isset($this->TEMPLATELIST[substr($_template,0,strlen($_template)-4).'_custom.tpl']))
{
$_template = substr($_template,0,strlen($_template)-4).'_custom.tpl';
}
$this->app->erp->ParseMenu();
$this->ParseVarVars();
if(isset($this->TEMPLATELIST[$_template]) && !($this->TEMPLATELIST[$_template]->vararraycreated))
{
$this->TEMPLATELIST[$_template]->CreateVarArray();
}
$print = $this->app->Secure->GetGET("print");
$printcontent = $this->app->Secure->GetGET("printcontent");
if($printcontent=="") $printcontent="TAB1";
if($print=="true") {
switch($printtype)
{
default:
$out = str_replace("[PRINT]",$this->VARARRAY[$printcontent],$this->TEMPLATELIST['print.tpl']->ORIGINAL);
echo $this->ParseTranslation($out);
}
exit;
}
if($_template!="" && isset($this->TEMPLATELIST)){
//alle template variablen aufuellen mit den werten aus VARARRAY
if(count($this->TEMPLATELIST[$_template]->VARS)>0){
foreach ($this->TEMPLATELIST[$_template]->VARS as $key=> $value)
{
$this->TEMPLATELIST[$_template]->SetVar($key,(isset($this->VARARRAY[$key])?$this->VARARRAY[$key]:''));
}
}
}
//ORIGINAL auffuellen
$new = false;
if($new)
{
//macht Noch Probleme
$tmptpl = '';
if(!empty($this->TEMPLATELIST[$_template]->Elements))
{
foreach($this->TEMPLATELIST[$_template]->Elements as $k)
{
$tmptpl .= $this->ParseTranslation($k['before']);
if(!empty($this->TEMPLATELIST[$_template]->VARS[$k['el']]))
{
$tmptpl .= $this->TEMPLATELIST[$_template]->VARS[$k['el']];
}
}
$tmptpl .= $this->ParseTranslation($this->TEMPLATELIST[$_template]->Elements[count($this->TEMPLATELIST[$_template]->Elements)-1]['nach']);
}else $tmptpl = $this->TEMPLATELIST[$_template]->ORIGINAL;
}else
{
$tmptpl = isset($this->TEMPLATELIST[$_template]->ORIGINAL)?$this->TEMPLATELIST[$_template]->ORIGINAL:'';
if(isset($this->TEMPLATELIST[$_template]->VARS) && count($this->TEMPLATELIST[$_template]->VARS)>0){
foreach ($this->TEMPLATELIST[$_template]->VARS as $key=>$value)
{
if($key!="")
$tmptpl = str_replace("[".$key."]",$value, $tmptpl);
}
}
if(count($this->VARARRAY)>0)
foreach($this->VARARRAY as $key=>$value)
{
if($key!="")
$tmptpl = str_replace('['.$key.']',$value,$tmptpl);
}
}
// In Auftrags-Positionen-IFrame: Leere Form-Actions nicht durch # ersetzen; ansonsten springt das IFrame im Chrome
$replaceEmptyFormAction = !$this->IsVorgangPositionenIframe();
$tmptpl = $this->ParseTranslation($this->app->erp->ClearDataBeforeOutput($tmptpl, $replaceEmptyFormAction));
if(isset($this->edittranslation) && $this->edittranslation)$tmptpl = $this->FormatTranslation($tmptpl);
return $tmptpl;
}
function FormatTranslation($text)
{
$start = '<span class="edittranslation">';
//$end = '</span>';
$texta = explode($start, $text);
//$anz = count($texta);
$script = false;
$textres = '';
foreach($texta as $k => $v)
{
$scriptpos = strripos($v, '<script');
$scriptendpos = strripos($v, '</script>');
if($scriptpos !== false && $scriptendpos !== false)
{
if($scriptendpos > $scriptpos)
{
$script = false;
}else{
$script = true;
}
}elseif($scriptpos !== false)
{
$script = true;
}elseif($scriptendpos !== false)
{
$script = false;
}else{
//Keine Aenderung
}
if($k > 0)
{
$pipe1 = (int)strpos($v, '|');
$pipe2 = (int)strpos($v, '|', (int)$pipe1+1);
$pipe3 = (int)strpos($v, '|', (int)$pipe2+1);
$pipe4 = (int)strpos($v, '|', (int)$pipe3+1);
$spos = 0;
$_text = '';
$_type = '';
$_elem = '';
if($pipe4 > $pipe3 && $pipe3 > $pipe2 && $pipe2 > $pipe1)
{
$_text = substr($v,$pipe1+1, $pipe2 - $pipe1 - 1);
$_type = substr($v,$pipe2+1, $pipe3 - $pipe2 - 1);
$_elem = substr($v,$pipe3+1, $pipe4 - $pipe3 - 1);
$spos = $pipe4 + 1;
}
$endespan = strpos($v, '</span>');
$erlaubt = true;
$starttag = strpos($v, '<', $endespan+6);
$startquote = strpos($v, '"', $endespan+6);
if($starttag && strtolower(substr($v,$starttag,5)) != '</td>' && strtolower(substr($v,$starttag,5)) != '</th>' && strtolower(substr($v,$starttag,4)) != '</a>' && strtolower(substr($v,$starttag,6)) != '</div>' && strtolower(substr($v,$starttag,4)) != '</i>' && strtolower(substr($v,$starttag,9)) != '</legend>' && strtolower(substr($v,$starttag,8)) != '</label>')
{
$erlaubt = false;
}
if(substr($v,$endespan+8,1) == '"' || substr($v,$endespan+7,1) == '"')
{
$erlaubt = false;
}
if($endespan !== false && $starttag !== false && $startquote !== false && $startquote < $starttag)
{
$erlaubt = false;
}
if($script || !$erlaubt)
{
if(!$script)
{
$substr = $texta[$k-1];
$pos1 = strripos($substr, 'input');
$pos2 = strrpos($substr, '<');
if($pos1 !== false && $pos2 !== false && $pos2 < $pos1)
{
$textres .= '****'.substr($v,$spos, $endespan - $spos).substr($v,$endespan+7);
}else{
$textres .= substr($v,$spos, $endespan - $spos).substr($v,$endespan+7);
}
}else{
$textres .= substr($v,$spos, $endespan - $spos).substr($v,$endespan+7);
}
}else{
$textres .= $start.substr($v,$spos, $endespan - $spos).'</span><span><input type="hidden" class="wawision_uebersetzung_text" value="'.base64_encode($_text).'" /><input type="hidden" class="wawision_uebersetzung_type" value="'.base64_encode($_type).'" /><input type="hidden" class="wawision_uebersetzung_elem" value="'.base64_encode($_elem).'" /></span>'.substr($v,$endespan+7);
}
}else{
$textres .= $v;
}
}
return $textres;
}
function AjaxParse()
{
foreach($this->TEMPLATELIST as $key=>$value)
{
foreach ($this->TEMPLATELIST[$key]->VARS as $var=>$tmp)
{
if(strstr($var,"AJAX"))
{
//$this->Set(AJAX_SELECT_PROJEKT,"Hallo");
//$this->VARARRAY[$var]="XVZ";
//print_r($this->VARARRAY);
}
}
}
}
function KeywordParse()
{
foreach($this->TEMPLATELIST as $key=>$value)
{
foreach ($this->TEMPLATELIST[$key]->VARS as $var=>$tmp)
if(strstr($var,"AJAX"))
{
echo $var;
}
}
}
function IsVorgangPositionenIframe()
{
$vorgaenge = ['anfrage','angebot','arbeitsnachweis','auftrag','bestellung','gutschrift','kalkulation','lieferschein','preisanfrage','produktion','proformarechnung','rechnung','reisekosten','verbindlichkeit'];
$isPopup = ($this->app->BuildNavigation !== true);
$isVorgangModule = in_array($this->app->Secure->GetGET('module'), $vorgaenge);
$isPositionenAction = (strpos($this->app->Secure->GetGET('action'), 'position') !== false);
return ($isPopup && $isVorgangModule && $isPositionenAction) ? true : false;
}
}
+735
View File
@@ -0,0 +1,735 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
class User
{
/** @var array */
var $cache;
/**
* User constructor.
*
* @param ApplicationCore $app
*/
public function __construct($app)
{
$this->app = $app;
}
/**
* @return array
*/
public function getUserProjects()
{
return $this->getUserProjectsByParameter($this->GetAdresse(), $this->GetType());
}
/**
* @return array
*/
public function getPublicProjects()
{
$cacheKey = $this->getCacheKey();
if(!empty($this->cache[$cacheKey]['public_projects'])) {
return $this->cache[$cacheKey]['public_projects'];
}
$this->loadProjectsInCacheProperty();
return $this->cache[$cacheKey]['public_projects'];
}
/**
* @return array
*/
public function getAllProjects()
{
$cacheKey = $this->getCacheKey();
if(!empty($this->cache[$cacheKey]['all_projects'])) {
return $this->cache[$cacheKey]['all_projects'];
}
$this->loadProjectsInCacheProperty();
return $this->cache[$cacheKey]['all_projects'];
}
/**
* @return array
*/
public function createCache()
{
$allProjects = $this->getAllProjects();
$file = $this->app->getTmpFolder().'cache_useronline';
$arr = $this->app->DB->SelectArr(
"SELECT uo.user_id, uo.sessionid, u.type, u.adresse
FROM `useronline` AS `uo`
INNER JOIN `user` AS `u` ON uo.user_id = u.id AND u.activ = 1
WHERE uo.login = 1"
);
$ret = [];
if(is_file($file)) {
$ret = file_get_contents($file);
if(empty(!$ret)) {
$ret = json_decode($ret, true);
}
if(empty($ret)) {
$ret = [];
}
}
$cacheKey = $this->getCacheKey();
$ret[$cacheKey] = [];
if(!empty($arr)) {
foreach($arr as $row) {
if($row['type'] === 'admin') {
$projects = $allProjects;
} else {
$projects = $this->getUserProjectsByParameter($row['adresse'], $row['type']);
}
$sessionId = $row['sessionid'];
$sha1SessionId = sha1($sessionId);
$ret[$cacheKey][$sha1SessionId] = ['type'=>$row['type'],'project'=>$projects];
}
}
file_put_contents($file, json_encode($ret));
return $ret[$cacheKey];
}
/**
* @param bool $createIfEmpty
*
* @return array|null
*/
public function getUserByCache($createIfEmpty = true)
{
$file = $this->app->getTmpFolder().'cache_useronline';
if(isset($_COOKIE['CH42SESSION']) && $_COOKIE['CH42SESSION']!='') {
$tmp = $_COOKIE['CH42SESSION'];
} else {
$tmp = session_id();
}
$sha1Tmp = sha1($tmp);
$content = '';
if(is_file($file)){
$content = file_get_contents($file);
}
$cacheKey = $this->getCacheKey();
if(!empty($content)) {
$content = json_decode($content, true);
if(empty($content[$cacheKey])) {
$content[$cacheKey] = $this->createCache();
}
$content = $content[$cacheKey];
if(!empty($content[$sha1Tmp])) {
return $content[$sha1Tmp];
}
} else {
if(!$createIfEmpty) {
return null;
}
}
if(!empty($tmp)) {
$content = $this->createCache();
if(!empty($content[$sha1Tmp])) {
return $content[$sha1Tmp];
}
}
return null;
}
/**
* @param int $projektId
*
* @return bool
*/
public function projectOk($projektId): ?bool
{
$user = $this->getUserByCache(false);
if(empty($user)) {
return null;
}
if($projektId <= 0) {
return true;
}
if($user['type'] === 'admin') {
return true;
}
if(empty($user['project'])) {
return false;
}
if(in_array($projektId, $user['project'])) {
return true;
}
//@todo Projekt aus Cache holen
return false;
}
/**
* @return int
*/
public function GetID(): int
{
if(isset($_COOKIE['CH42SESSION']) && $_COOKIE['CH42SESSION']!='') {
$tmp = $_COOKIE['CH42SESSION'];
} else {
$tmp = session_id();
}
$cacheKey = $this->getCacheKey();
if(empty($this->cache[$cacheKey])
|| !isset($this->cache[$cacheKey]['time']) || !isset($this->cache[$cacheKey]['tmp'])
|| $this->cache[$cacheKey]['time'] + 10 < microtime(true) || $this->cache[$cacheKey]['tmp'] != $tmp) {
$this->cache = null;
$user_id = (int)$this->app->DB->Select(
sprintf(
"SELECT `user_id`
FROM `useronline`
WHERE `sessionid` != '' AND `sessionid` = '%s' AND `login` = 1
LIMIT 1",
$this->app->DB->real_escape_string($tmp)
)
);
if($user_id > 0) {
$this->cache[$cacheKey]['user_id'] = $user_id;
$this->cache[$cacheKey]['tmp'] = $tmp;
$this->cache[$cacheKey]['time'] = microtime(true);
}
return $user_id;
}
return (int)$this->cache[$cacheKey]['user_id'];
}
/**
* @return string
*/
public function GetType(): string
{
$userId = (int)$this->GetID();
if($userId <= 0) {
return (string)$this->app->Conf->WFconf['defaultgroup'];
}
$cacheKey = $this->getCacheKey();
if(!empty($this->cache[$cacheKey]) && isset($this->cache[$cacheKey]['type'])) {
return (string)$this->cache[$cacheKey]['type'];
}
$this->loadUserRowInCacheProperty($userId);
return (string)$this->cache[$cacheKey]['type'];
}
/**
* @param null|string|array $settings
*/
function SettingsToUserKonfiguration($settings = null)
{
$id = (int)$this->GetID();
if(!$id) {
return;
}
if($settings === null) {
$settings = $this->app->DB->Select(sprintf('SELECT `settings` FROM `user` WHERE `id` = %d LIMIT 1', $id));
$cacheKey = $this->getCacheKey();
$this->cache[$cacheKey]['settings'] = $settings;
}
if(empty($settings)) {
return;
}
if($settings != '') {
$settings = @unserialize($settings);
}
if(empty($settings) || !is_array($settings)) {
return;
}
foreach($settings as $k => $v) {
$check = $this->app->DB->Select("SELECT `id` FROM `userkonfiguration` WHERE `name` = '".$this->app->DB->real_escape_string($k)."' AND `user` = '$id' LIMIT 1");
if($check) {
$this->app->DB->Update("UPDATE `userkonfiguration` set `value` = '".$this->app->DB->real_escape_string($v)."' WHERE `id` = '$check' LIMIT 1");
}else{
$this->app->DB->Insert("INSERT INTO `userkonfiguration` (`user`,`name`,`value`) VALUES ('$id','".$this->app->DB->real_escape_string($k)."','".$this->app->DB->real_escape_string($v)."')");
}
}
if(!$this->app->DB->error()) {
$this->app->DB->Update(sprintf("UPDATE `user` SET `settings` = '' WHERE `id` = %d LIMIT 1", $id));
$cacheKey = $this->getCacheKey();
$this->cache[$cacheKey]['settings'] = '';
}
}
/**
* @var int|null $userId
*
* @return string|null
*/
public function GetSettings($userId = null)
{
$cacheKey = $this->getCacheKey();
if(!empty($this->cache[$cacheKey]) && isset($this->cache[$cacheKey]['settings'])) {
return $this->cache[$cacheKey]['settings'];
}
$this->loadUserRowInCacheProperty($userId);
return $this->cache[$cacheKey]['settings'];
}
/**
* @param string|array $index
*
* @return array|mixed|string|null
*/
public function GetParameter($index)
{
$userId = (int)$this->GetID();
$settings = $this->GetSettings($userId);
if(!empty($settings)) {
$this->SettingsToUserKonfiguration($settings);
}
if((is_array($index) && count($index) === 0) || (!is_array($index) && (string)$index === '')) {
return null;
}
if(is_array($index)) {
$index = array_map('trim', $index);
$indexNames = array_map([$this->app->DB, 'real_escape_string'], $index);
$sql = sprintf(
"SELECT `name`, MAX(`value`) AS `value`
FROM `userkonfiguration`
WHERE `user` = %d AND `name` IN ('%s')
GROUP BY `name`",
$userId, implode("', '", $indexNames)
);
$arr = $this->app->DB->SelectPairs($sql);
$ret = null;
foreach($index as $ind) {
if(isset($arr[$ind])) {
$ret[] = [ 'name'=>$ind, 'value'=> $arr[$ind] ];
}
else {
$ret[] = [ 'name'=>$ind, 'value'=> '' ];
}
}
return $ret;
}
return $this->app->DB->Select(
sprintf(
"SELECT `value`
FROM `userkonfiguration`
WHERE `name` = '%s' AND `user` = %d
LIMIT 1",
$this->app->DB->real_escape_string($index), $userId
)
);
}
// value koennen beliebige Datentypen aus php sein (serialisiert)
/**
* @param string $index
* @param mixed $value
*/
public function SetParameter($index, $value)
{
if((string)$index === '' || $value === null) {
return;
}
$id = (int)$this->GetID();
$settings = $this->GetSettings($id);
if(!empty($settings)) {
$this->SettingsToUserKonfiguration($settings);
}
$check = $this->app->DB->SelectRow(
sprintf(
"SELECT `id`, `value`
FROM `userkonfiguration` WHERE `name` = '%s' AND `user` = %d
LIMIT 1",
$this->app->DB->real_escape_string($index), $id
)
);
if(empty($check)) {
$this->app->DB->Insert(
sprintf(
"INSERT INTO `userkonfiguration` (`user`, `name`, `value`) VALUES (%d, '%s', '%s')",
$id, $this->app->DB->real_escape_string($index), $this->app->DB->real_escape_string($value)
)
);
$this->cache = null;
return;
}
if((string)$value === (string)$check['value']) {
return;
}
$this->app->DB->Update(
sprintf(
"UPDATE `userkonfiguration`
SET `value` = '%s'
WHERE `id` = %d
LIMIT 1",
$this->app->DB->real_escape_string($value), $check['id']
)
);
$this->cache = null;
}
/**
* @param string $index
*/
public function deleteParameter($index)
{
if(empty($index)) {
return;
}
$id = $this->GetID();
$this->app->DB->Delete(
sprintf(
'DELETE FROM `userkonfiguration` WHERE `user` = %d AND `name` = \'%s\'',
$id, $this->app->DB->real_escape_string($index)
)
);
}
/**
* @param string $prefix
*/
public function deleteParameterPrefix($prefix)
{
if(empty($prefix)) {
return;
}
$id = $this->GetID();
$this->app->DB->Delete(
sprintf(
'DELETE FROM `userkonfiguration` WHERE `user` = %d AND `name` LIKE \'%s%%\'',
$id, $this->app->DB->real_escape_string($prefix)
)
);
}
/**
* @return string|null
*/
public function GetUsername()
{
$cacheKey = $this->getCacheKey();
if(!empty($this->cache[$cacheKey]) && isset($this->cache[$cacheKey]['username'])) {
return $this->cache[$cacheKey]['username'];
}
$this->loadUserRowInCacheProperty();
return $this->cache[$cacheKey]['username'];
}
/**
* @return string|null
*/
public function GetDescription()
{
return $this->GetName();
}
/**
* @return string|null
*/
public function GetMail()
{
$cacheKey = $this->getCacheKey();
if(!empty($this->cache[$cacheKey]) && isset($this->cache[$cacheKey]['email'])) {
return $this->cache[$cacheKey]['email'];
}
$this->loadAddressRowInCacheProperty();
return $this->cache[$cacheKey]['email'];
}
/**
* @return string|null
*/
public function GetName()
{
$cacheKey = $this->getCacheKey();
if(!empty($this->cache[$cacheKey]) && isset($this->cache[$cacheKey]['name'])) {
return $this->cache[$cacheKey]['name'];
}
$this->loadAddressRowInCacheProperty();
return $this->cache[$cacheKey]['name'];
}
/**
* @return array
*/
public function GetSprachen()
{
$userId = (int)$this->GetId();
$cacheKey = $this->getCacheKey();
if(empty($this->cache[$cacheKey]) || !isset($this->cache[$cacheKey]['sprachebevorzugen'])) {
$this->loadUserRowInCacheProperty($userId);
}
$defaultLanguages = ['german','english'];
$languages = $this->cache[$cacheKey]['sprachebevorzugen'];
if(empty($languages)) {
return $defaultLanguages;
}
$ret = [];
$languagesArray = explode(';',str_replace(',',';',$languages));
foreach($languagesArray as $language) {
$language = trim($language);
if($language != '') {
$ret[] = $language;
}
}
if(empty($ret)) {
return $ret;
}
return $defaultLanguages;
}
/**
* @return string
*/
public function GetSprache()
{
$sprachen = $this->GetSprachen();
return reset($sprachen);
}
/**
* @return int|null
*/
public function GetAdresse()
{
$cacheKey = $this->getCacheKey();
if(!empty($this->cache[$cacheKey]) && isset($this->cache[$cacheKey]['adresse'])) {
return $this->cache[$cacheKey]['adresse'];
}
$this->loadUserRowInCacheProperty();
return $this->cache[$cacheKey]['adresse'];
}
/**
* @return bool
*/
function GetProjektleiter()
{
$result = $this->app->DB->SelectRow(
"SELECT `parameter`
FROM `adresse_rolle`
WHERE `subjekt` = 'Projektleiter' AND (`bis` = '0000-00-00' OR `bis` <= CURDATE())
AND `adresse` = '".$this->app->User->GetAdresse()."'
LIMIT 1"
);
return !empty($result);
}
/**
* @return int
*/
function DefaultProjekt()
{
$adresse = $this->GetAdresse();
$cacheKey = $this->getCacheKey();
if(empty($this->cache[$cacheKey]) || !isset($this->cache[$cacheKey]['projekt'])) {
$this->loadAddressRowInCacheProperty($adresse);
$projekt = $this->cache[$cacheKey]['projekt'];
}
else {
$projekt = $this->cache[$cacheKey]['projekt'];
}
if($projekt <=0){
$projekt = $this->app->DB->Select(
"SELECT `standardprojekt` FROM `firma` WHERE `id`='" . $this->app->User->GetFirma() . "' LIMIT 1"
);
}
return $projekt;
}
/**
* @return string|null
*/
function GetEmail()
{
$cacheKey = $this->getCacheKey();
if(!empty($this->cache[$cacheKey]) && isset($this->cache[$cacheKey]['email'])) {
return $this->cache[$cacheKey]['email'];
}
$this->loadAddressRowInCacheProperty();
return $this->cache[$cacheKey]['email'];
}
/**
* @return int
*/
public function GetFirma(): int
{
return 1;
}
/**
* @return string
*/
function GetFirmaName()
{
$cacheKey = $this->getCacheKey();
if(!empty($this->cache[$cacheKey]) && isset($this->cache[$cacheKey]['firmaname'])) {
return $this->cache[$cacheKey]['firmaname'];
}
$name = $this->app->DB->Select(sprintf('SELECT `name` FROM `firma` WHERE `id` = %d', $this->GetFirma()));
$this->cache[$cacheKey]['firmaname'] = $name;
return $name;
}
/**
* @param string $field
*
* @return mixed
*/
public function GetField($field)
{
$value = $this->app->DB->Select(
sprintf(
'SELECT `%s` FROM `user` WHERE id = %d ',
$field, $this->GetID()
)
);
if(in_array($value, ['settings', 'type', 'username', 'adresse', 'sprachebevorzugen'])) {
$cacheKey = $this->getCacheKey();
$this->cache[$cacheKey][$field] = $value;
}
return $value;
}
/**
* @param int|null $userId
*/
protected function loadUserRowInCacheProperty(?int $userId = null): void
{
if($userId === null){
$userId = (int)$this->GetID();
}
$cacheKey = $this->getCacheKey();
$userData = (array)$this->app->DB->SelectRow(
sprintf(
'SELECT `settings`, `type`, `username`, `adresse`, `sprachebevorzugen` FROM `user` WHERE `id` = %d LIMIT 1',
$userId
)
);
if(!isset($this->cache[$cacheKey])) {
$this->cache[$cacheKey] = $userData;
}
else{
$this->cache[$cacheKey] = array_merge($this->cache[$cacheKey], $userData);
}
}
/**
* @param int|null $addressId
*/
protected function loadAddressRowInCacheProperty(?int $addressId = null): void
{
if($addressId === null){
$addressId = (int)$this->GetAdresse();
}
$cacheKey = $this->getCacheKey();
$addressData = (array)$this->app->DB->SelectRow(
sprintf('SELECT `name`, `email`, `projekt` FROM `adresse` WHERE `id` = %d LIMIT 1', $addressId)
);
if(!isset($this->cache[$cacheKey])) {
$this->cache[$cacheKey] = $addressData;
}
else{
$this->cache[$cacheKey] = array_merge($this->cache[$cacheKey], $addressData);
}
}
/**
* @return string
*/
protected function getCacheKey(): string
{
return (string)$this->app->Conf->WFdbname;
}
protected function loadProjectsInCacheProperty(): void
{
$cacheKey = $this->getCacheKey();
$projects = $this->app->DB->SelectPairs('SELECT `id`, `oeffentlich` FROM `projekt` WHERE `geloescht` <> 1');
$this->cache[$cacheKey]['all_projects'] = array_keys($projects);
$this->cache[$cacheKey]['public_projects'] = [];
foreach($projects as $projectId => $public) {
if($public) {
$this->cache[$cacheKey]['public_projects'][] = $projectId;
}
}
}
/**
* @param int $addressId
* @param string $type
*
* @return array
*/
protected function getUserProjectsByParameter($addressId, $type)
{
if($type==='admin' ||
$this->app->DB->Select(
"SELECT `id`
FROM `adresse_rolle`
WHERE (`bis` IS NULL OR `bis` = '0000-00-00' OR `bis` <= CURDATE()) AND `adresse` = '".$addressId."'
AND (`parameter` = '' OR `parameter` = '0')"
)
) {
return $this->getAllProjects();
}
$public = $this->getPublicProjects();
$roles = $this->app->DB->SelectFirstCols(
sprintf(
"SELECT DISTINCT `parameter`
FROM `adresse_rolle`
WHERE (`bis` IS NULL OR `bis` = '0000-00-00' OR `bis` <= CURDATE()) AND `adresse` = %d
AND `parameter` >= 0 AND `objekt` LIKE 'Projekt'",
$addressId
)
);
$projects = $this->app->DB->SelectFirstCols(
sprintf(
"SELECT DISTINCT `projekt`
FROM `adresse_rolle`
WHERE (`bis` IS NULL OR `bis` = '0000-00-00' OR bis <= CURDATE()) AND `adresse` = %d AND `projekt` > 0",
$addressId
)
);
return array_unique(array_merge($public, $roles, $projects));
}
}
+154
View File
@@ -0,0 +1,154 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
//include("xtea.class.php");
/*
$serial = "abcdefghijklmNopqrstuvwxyz";
$key = pack('V*', 0x01,0x02,0x03,0x04);
$pad = "4371353838310545596909623831103272086622087173752843453214777855055965572268047010384215";
*/
//print(wawision_pad_verify($pad,$key,$serial));
//print(wawision_pad_verify($pad,$key,$serial));
class WaWisionOTP
{
function wawision_encode($base64) {
$output = "";
for($i = 0; $i < strlen($base64)-1; $i++) {
$c = ord($base64[$i])-ord('+');
$output .= chr($c/10 + ord('0'));
$output .= chr($c%10 + ord('0'));
}
return $output;
}
function wawision_decode($input)
{
$base64_str = "";
for ($i=0; $i<strlen($input)/2; $i++) {
$ten = ord($input[2*$i]) - ord('0');
$one = ord($input[2*$i+1]) - ord('0');
/* check if input is valid */
$value = $ten*10+$one;
if($ten < 0 || $ten > 9 || $one < 0 || $one > 9) {
return FALSE;
}
$base64_str .= chr($value + ord("+"));
}
return $base64_str;
}
function wawision_pad_verify($pad,$key,$serial)
{
$cipher = $this->wawision_decode($pad);
if($cipher == FALSE) {
return FALSE;
}
$xtea = new XTEA($key);
$plain = $xtea->decrypt($cipher);
if($plain == FALSE)
return FALSE;
/* check serial */
if($plain[0] != $serial[0] ||
$plain[1] != $serial[1] ||
$plain[2] != $serial[2] ||
$plain[3] != $serial[3] ||
$plain[4] != $serial[4] ||
$plain[8] != $serial[5] ||
$plain[9] != $serial[6] ||
$plain[10] != $serial[7] ||
$plain[11] != $serial[8] ||
$plain[12] != $serial[9] ||
$plain[16] != $serial[10] ||
$plain[17] != $serial[11] ||
$plain[18] != $serial[12] ||
$plain[19] != $serial[13] ||
$plain[20] != $serial[14]) {
return FALSE;
}
/* check rnd */
$rnd1 = ord($plain[7]);
$rnd2 = ord($plain[15]);
$rnd12 = ord($plain[23]);
if(($rnd1 + $rnd2) % 256 != $rnd12)
return FALSE;
/* extract counter */
$counter = ord($plain[5]) << 24;
$counter += ord($plain[6]) << 16;
$counter += ord($plain[13]) << 8;
$counter += ord($plain[14]);
/* success */
return $counter;
}
function wawision_pad_create($key, $serial, $counter)
{
/* 1st block */
$plain = $serial[0];
$plain .= $serial[1];
$plain .= $serial[2];
$plain .= $serial[3];
$plain .= $serial[4];
$plain .= chr($counter >> 24);
$plain .= chr($counter >> 16);
$plain .= chr(rand());
/* 2nd block */
$plain .= $serial[5];
$plain .= $serial[6];
$plain .= $serial[7];
$plain .= $serial[8];
$plain .= $serial[9];
$plain .= chr($counter >> 8);
$plain .= chr($counter);
$plain .= chr(rand());
/* 3rd block */
$plain .= $serial[10];
$plain .= $serial[11];
$plain .= $serial[12];
$plain .= $serial[13];
$plain .= $serial[14];
$plain .= chr(rand());
$plain .= chr(rand());
$plain .= chr((ord($plain[7])+ord($plain[15])) % 256);
/* encrypt using XTEA CBC */
$xtea = new XTEA($key);
$cipher = $xtea->encrypt($plain);
/* encode using wawision_encode */
return $this->wawision_encode($cipher);
}
}
+44
View File
@@ -0,0 +1,44 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
class WFMonitor
{
function __construct(&$app)
{
$this->app = &$app;
}
function Error($msg)
{
$this->ErrorBox($msg);
}
function ErrorBox($content)
{
$box .="
<table border=\"1\" width=\"100%\" bgcolor=\"#ffB6C1\">
<tr><td>phpWebFrame Error: $content</td></tr>
</table>";
echo $box;
}
}
?>
+44
View File
@@ -0,0 +1,44 @@
<?php
/*
**** COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*
* Xentral (c) Xentral ERP Sorftware GmbH, Fuggerstrasse 11, D-86150 Augsburg, * Germany 2019
*
* This file is licensed under the Embedded Projects General Public License *Version 3.1.
*
* You should have received a copy of this license from your vendor and/or *along with this file; If not, please visit www.wawision.de/Lizenzhinweis
* to obtain the text of the corresponding license version.
*
**** END OF COPYRIGHT & LICENSE NOTICE *** DO NOT REMOVE ****
*/
?>
<?php
class WidgetAPI
{
private $app;
function __construct(&$app)
{
$this->app = &$app;
}
function Get($name, $parsetarget)
{
if(file_exists("widgets/widget.$name.php")) {
include_once("widgets/widget.$name.php");
//echo "es gibt ein modifiziertes objecy";
$classname = "Widget".ucfirst($name);
return new $classname($this->app,$parsetarget);
} else {
//echo "es gibt nur das generiewrte";
include_once("widgets/_gen/widget.gen.$name.php");
//echo "es gibt ein modifiziertes objecy";
$classname = "WidgetGen".ucfirst($name);
return new $classname($this->app,$parsetarget);
}
}
}
?>
File diff suppressed because it is too large Load Diff