add files
|
@ -0,0 +1 @@
|
||||||
|
config.php
|
|
@ -0,0 +1 @@
|
||||||
|
Deny from all
|
|
@ -0,0 +1,5 @@
|
||||||
|
1148b04d-7a93-19e9-b3c9-ea1cdeec38f7
|
||||||
|
1148b04d-7a93-29e9-b3c9-ea1cdeec38f7
|
||||||
|
1148b04d-7a93-39e9-b3c9-ea1cdeec38f7
|
||||||
|
1148b04d-7a93-49e9-b3c9-ea1cdeec38f7
|
||||||
|
1148b04d-7a93-59e9-b3c9-ea1cdeec38f7
|
|
@ -0,0 +1,34 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="refresh" content="15">
|
||||||
|
</head>
|
||||||
|
<body style="background-image: url('./style/images/fabric-pattern.png')">
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$statement = $RUNTIME['PDO']->prepare("SELECT * FROM Presence WHERE RegionID != '00000000-0000-0000-0000-000000000000' ORDER BY RegionID ASC");
|
||||||
|
$statement->execute();
|
||||||
|
|
||||||
|
if($statement->rowCount() == 0)
|
||||||
|
{
|
||||||
|
echo "<h1>Es ist niemand online!</h1>";
|
||||||
|
}else{
|
||||||
|
|
||||||
|
echo '<table style="width:350px;margin-left:auto;margin-right:auto;margin-top:25px"><tr><th align="left" style="background-color: #FF8000;">Name</th><th align="left" style="background-color: #FF8000;">Region</th></tr>';
|
||||||
|
$entryColor = TRUE;
|
||||||
|
while($row = $statement->fetch())
|
||||||
|
{
|
||||||
|
if($entryColor == TRUE)
|
||||||
|
$entry = '<tr style="background-color: #F2F2F2;"><td>'.trim($RUNTIME['OPENSIM']->getUserName($row['UserID'])).'</td><td>'.$RUNTIME['OPENSIM']->getRegionName($row['RegionID']).'</td></tr>';
|
||||||
|
|
||||||
|
if($entryColor == FALSE)
|
||||||
|
$entry = '<tr style="background-color: #E6E6E6;"><td>'.trim($RUNTIME['OPENSIM']->getUserName($row['UserID'])).'</td><td>'.$RUNTIME['OPENSIM']->getRegionName($row['RegionID']).'</td></tr>';
|
||||||
|
|
||||||
|
echo $entry;
|
||||||
|
$entryColor = !$entryColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</table>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
$HTML = new HTML();
|
||||||
|
$HTML->setHTMLTitle("Spalsh");
|
||||||
|
$HTML->importHTML("style/viewerWelcomeSite/default.html");
|
||||||
|
|
||||||
|
$IMAGES = array();
|
||||||
|
if ($handle = opendir('./data/viewerWelcomeImages'))
|
||||||
|
{
|
||||||
|
while (false !== ($entry = readdir($handle)))
|
||||||
|
{
|
||||||
|
if ($entry != "." && $entry != "..")
|
||||||
|
{
|
||||||
|
$IMAGES = array_merge($IMAGES, array("./data/viewerWelcomeImages/".$entry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir($handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
shuffle($IMAGES);
|
||||||
|
|
||||||
|
$HTML->importSeitenInhalt("pages/HTML/viewerWelcomeImages.html");
|
||||||
|
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%JSONIMAGEARRAY%%", json_encode($IMAGES));
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%GRIDNAME%%", $RUNTIME['GRID']['NAME']);
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%SHOWNEWS%%", $RUNTIME['GRID']['MAIN_NEWS']);
|
||||||
|
|
||||||
|
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%SHOWSTATS%%", "Registrierte User: ".$RUNTIME['OPENSIM']->getUserCount()."<br>Regionen: ".$RUNTIME['OPENSIM']->getRegionCount()."<br>Aktuell Online: ".$RUNTIME['OPENSIM']->getOnlineCount());
|
||||||
|
|
||||||
|
|
||||||
|
$HTML->build();
|
||||||
|
echo $HTML->ausgabe();
|
||||||
|
?>
|
|
@ -0,0 +1,252 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHP Class for handling Google Authenticator 2-factor authentication.
|
||||||
|
*
|
||||||
|
* @author Michael Kliewe
|
||||||
|
* @copyright 2012 Michael Kliewe
|
||||||
|
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||||
|
*
|
||||||
|
* @link http://www.phpgangsta.de/
|
||||||
|
*/
|
||||||
|
class PHPGangsta_GoogleAuthenticator
|
||||||
|
{
|
||||||
|
protected $_codeLength = 6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new secret.
|
||||||
|
* 16 characters, randomly chosen from the allowed base32 characters.
|
||||||
|
*
|
||||||
|
* @param int $secretLength
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function createSecret($secretLength = 16)
|
||||||
|
{
|
||||||
|
$validChars = $this->_getBase32LookupTable();
|
||||||
|
|
||||||
|
// Valid secret lengths are 80 to 640 bits
|
||||||
|
if ($secretLength < 16 || $secretLength > 128) {
|
||||||
|
throw new Exception('Bad secret length');
|
||||||
|
}
|
||||||
|
$secret = '';
|
||||||
|
$rnd = false;
|
||||||
|
if (function_exists('random_bytes')) {
|
||||||
|
$rnd = random_bytes($secretLength);
|
||||||
|
} elseif (function_exists('mcrypt_create_iv')) {
|
||||||
|
$rnd = mcrypt_create_iv($secretLength, MCRYPT_DEV_URANDOM);
|
||||||
|
} elseif (function_exists('openssl_random_pseudo_bytes')) {
|
||||||
|
$rnd = openssl_random_pseudo_bytes($secretLength, $cryptoStrong);
|
||||||
|
if (!$cryptoStrong) {
|
||||||
|
$rnd = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($rnd !== false) {
|
||||||
|
for ($i = 0; $i < $secretLength; ++$i) {
|
||||||
|
$secret .= $validChars[ord($rnd[$i]) & 31];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Exception('No source of secure random');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the code, with given secret and point in time.
|
||||||
|
*
|
||||||
|
* @param string $secret
|
||||||
|
* @param int|null $timeSlice
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCode($secret, $timeSlice = null)
|
||||||
|
{
|
||||||
|
if ($timeSlice === null) {
|
||||||
|
$timeSlice = floor(time() / 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
$secretkey = $this->_base32Decode($secret);
|
||||||
|
|
||||||
|
// Pack time into binary string
|
||||||
|
$time = chr(0).chr(0).chr(0).chr(0).pack('N*', $timeSlice);
|
||||||
|
// Hash it with users secret key
|
||||||
|
$hm = hash_hmac('SHA1', $time, $secretkey, true);
|
||||||
|
// Use last nipple of result as index/offset
|
||||||
|
$offset = ord(substr($hm, -1)) & 0x0F;
|
||||||
|
// grab 4 bytes of the result
|
||||||
|
$hashpart = substr($hm, $offset, 4);
|
||||||
|
|
||||||
|
// Unpak binary value
|
||||||
|
$value = unpack('N', $hashpart);
|
||||||
|
$value = $value[1];
|
||||||
|
// Only 32 bits
|
||||||
|
$value = $value & 0x7FFFFFFF;
|
||||||
|
|
||||||
|
$modulo = pow(10, $this->_codeLength);
|
||||||
|
|
||||||
|
return str_pad($value % $modulo, $this->_codeLength, '0', STR_PAD_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get QR-Code URL for image, from google charts.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param string $secret
|
||||||
|
* @param string $title
|
||||||
|
* @param array $params
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array())
|
||||||
|
{
|
||||||
|
$width = !empty($params['width']) && (int) $params['width'] > 0 ? (int) $params['width'] : 200;
|
||||||
|
$height = !empty($params['height']) && (int) $params['height'] > 0 ? (int) $params['height'] : 200;
|
||||||
|
$level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M';
|
||||||
|
|
||||||
|
$urlencoded = urlencode('otpauth://totp/'.$name.'?secret='.$secret.'');
|
||||||
|
if (isset($title)) {
|
||||||
|
$urlencoded .= urlencode('&issuer='.urlencode($title));
|
||||||
|
}
|
||||||
|
|
||||||
|
return "https://api.qrserver.com/v1/create-qr-code/?data=$urlencoded&size=${width}x${height}&ecc=$level";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the code is correct. This will accept codes starting from $discrepancy*30sec ago to $discrepancy*30sec from now.
|
||||||
|
*
|
||||||
|
* @param string $secret
|
||||||
|
* @param string $code
|
||||||
|
* @param int $discrepancy This is the allowed time drift in 30 second units (8 means 4 minutes before or after)
|
||||||
|
* @param int|null $currentTimeSlice time slice if we want use other that time()
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null)
|
||||||
|
{
|
||||||
|
if ($currentTimeSlice === null) {
|
||||||
|
$currentTimeSlice = floor(time() / 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen($code) != 6) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
|
||||||
|
$calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);
|
||||||
|
if ($this->timingSafeEquals($calculatedCode, $code)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the code length, should be >=6.
|
||||||
|
*
|
||||||
|
* @param int $length
|
||||||
|
*
|
||||||
|
* @return PHPGangsta_GoogleAuthenticator
|
||||||
|
*/
|
||||||
|
public function setCodeLength($length)
|
||||||
|
{
|
||||||
|
$this->_codeLength = $length;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class to decode base32.
|
||||||
|
*
|
||||||
|
* @param $secret
|
||||||
|
*
|
||||||
|
* @return bool|string
|
||||||
|
*/
|
||||||
|
protected function _base32Decode($secret)
|
||||||
|
{
|
||||||
|
if (empty($secret)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$base32chars = $this->_getBase32LookupTable();
|
||||||
|
$base32charsFlipped = array_flip($base32chars);
|
||||||
|
|
||||||
|
$paddingCharCount = substr_count($secret, $base32chars[32]);
|
||||||
|
$allowedValues = array(6, 4, 3, 1, 0);
|
||||||
|
if (!in_array($paddingCharCount, $allowedValues)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for ($i = 0; $i < 4; ++$i) {
|
||||||
|
if ($paddingCharCount == $allowedValues[$i] &&
|
||||||
|
substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$secret = str_replace('=', '', $secret);
|
||||||
|
$secret = str_split($secret);
|
||||||
|
$binaryString = '';
|
||||||
|
for ($i = 0; $i < count($secret); $i = $i + 8) {
|
||||||
|
$x = '';
|
||||||
|
if (!in_array($secret[$i], $base32chars)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for ($j = 0; $j < 8; ++$j) {
|
||||||
|
$x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
|
||||||
|
}
|
||||||
|
$eightBits = str_split($x, 8);
|
||||||
|
for ($z = 0; $z < count($eightBits); ++$z) {
|
||||||
|
$binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $binaryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get array with all 32 characters for decoding from/encoding to base32.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function _getBase32LookupTable()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
|
||||||
|
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
|
||||||
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
|
||||||
|
'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
|
||||||
|
'=', // padding char
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A timing safe equals comparison
|
||||||
|
* more info here: http://blog.ircmaxell.com/2014/11/its-all-about-time.html.
|
||||||
|
*
|
||||||
|
* @param string $safeString The internal (safe) value to be checked
|
||||||
|
* @param string $userString The user submitted (unsafe) value
|
||||||
|
*
|
||||||
|
* @return bool True if the two strings are identical
|
||||||
|
*/
|
||||||
|
private function timingSafeEquals($safeString, $userString)
|
||||||
|
{
|
||||||
|
if (function_exists('hash_equals')) {
|
||||||
|
return hash_equals($safeString, $userString);
|
||||||
|
}
|
||||||
|
$safeLen = strlen($safeString);
|
||||||
|
$userLen = strlen($userString);
|
||||||
|
|
||||||
|
if ($userLen != $safeLen) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = 0;
|
||||||
|
|
||||||
|
for ($i = 0; $i < $userLen; ++$i) {
|
||||||
|
$result |= (ord($safeString[$i]) ^ ord($userString[$i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// They are only identical strings if $result is exactly 0...
|
||||||
|
return $result === 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,242 @@
|
||||||
|
<?php
|
||||||
|
class HTML
|
||||||
|
{
|
||||||
|
|
||||||
|
//Hier wird der HTML Code zum Ausgeben vorbereitet.
|
||||||
|
//Dieser kann aus einer fertigen HTML Seite ausgelesen werden, oder aber auch st<73>ck f<>r St<53>ck
|
||||||
|
//Zusammen gebaut werden.
|
||||||
|
|
||||||
|
//Die Einzelnen Daten k<>nnen nicht direkt von Au<41>en ver<65>ndert werden, sondern m<>ssen durch die Bereitgestellten Optionen gesetzt werden.
|
||||||
|
|
||||||
|
private $HTMLTitle = " "; //Wird in den <header> als <title> Geschrieben.
|
||||||
|
private $StatusMeldung = " "; //Falls Vorhenden eine Statusmeldung vom Script im HTML Text.
|
||||||
|
private $DasMenu = " "; //Beinhaltet das Fertige Men<65>
|
||||||
|
private $DerInhalt = " "; //Beinhaltet den Fertigen Inhalt
|
||||||
|
private $HTMLDatei = " "; //Der inhalt der eingelesen wurde.
|
||||||
|
private $HTMLHeader = " "; //Der HTML HEADER der eingelesen wurde.
|
||||||
|
private $FertigesHTML = " "; //Das Fertige HTML bereit zum Ausgeben.
|
||||||
|
private $isBuild = false; //Hier wird festgehalten ob $FertigesHTML aktuell ist oder nicht.
|
||||||
|
|
||||||
|
//Der <title> wird Generiert.(%%EchoTitle%%)
|
||||||
|
//Dieser wird im HTML Code sp<73>ter als %%HTMLTitle%% aufgerufen.
|
||||||
|
|
||||||
|
public function setHTMLTitle($neuerTitle){
|
||||||
|
//Der Bisherige Title wird komplett <20>berschrieben und gleichzeitig ein neuer Gesetzt.
|
||||||
|
$this->HTMLTitle = $neuerTitle;
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addHTMLTitle($Hinzufugen){
|
||||||
|
//Zu dem Bisherigen Titel wird noch etwas am ende hinzugef<65>gt.
|
||||||
|
$this->HTMLTitle = $this->$HTMLTitle.$Hinzufugen;
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function RemoveHTMLTitle(){
|
||||||
|
//Der Titel wird Komplett gel<65>scht.
|
||||||
|
$this->HTMLTitle = " ";
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Der HTML HEADER wird Generiert.(%%echoHeader%%)
|
||||||
|
//Dieser wird im HTML Code sp<73>ter als %%echoHeader%% aufgerufen.
|
||||||
|
|
||||||
|
public function setHTMLHeader($neuerHeader){
|
||||||
|
//Der Bisherige Header wird komplett <20>berschrieben und gleichzeitig ein neuer Gesetzt.
|
||||||
|
$this->HTMLHeader = $neuerHeader;
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addHTMLHeader($Hinzufugen){
|
||||||
|
//Zu dem Bisherigen Header wird noch etwas am ende hinzugef<65>gt.
|
||||||
|
$this->HTMLHeader = $this->HTMLHeader.$Hinzufugen;
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function RemoveHTMLHeader(){
|
||||||
|
//Der Header wird Komplett gel<65>scht.
|
||||||
|
$this->HTMLHeader = " ";
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function importHTMLHeader($file){
|
||||||
|
//Der HTML Header wird aus einer Datei eingelesen und der bisherige gel<65>scht.
|
||||||
|
$this->HTMLHeader = file_get_contents($file);
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Der StatusText wird ge<67>ndert.(%%StatusMeldung%%)
|
||||||
|
//Dieser wird im HTML Code sp<73>ter als %%StatusMeldung%% aufgerufen.
|
||||||
|
|
||||||
|
public function setStatusMeldung($neueMeldung){
|
||||||
|
//Die bisherige Status meldung wird komplett <20>berschrieben und gleichzeitig ein neuer Gesetzt.
|
||||||
|
$this->StatusMeldung = $neueMeldung;
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function RemoveStatusMeldung(){
|
||||||
|
//Die Meldung wird Komplett gel<65>scht.
|
||||||
|
$this->StatusMeldung = " ";
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ab hier wird das Men<65> Zusammengebaut. (%%EchoMenu%%)
|
||||||
|
|
||||||
|
public function importTextMenu($neuesMenu){
|
||||||
|
//Das Komplette Men<65> wird direkt importiert und das alte <20>berschreiben.
|
||||||
|
$this->DasMenu = $neuesMenu;
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function importHTMLMenu($file){
|
||||||
|
//Das Komplette Men<65> wird aus einer Datei ausgelesen und das alte <20>berschrieben.
|
||||||
|
$this->DasMenu = file_get_contents($file);
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addToMenu($html){
|
||||||
|
//Es wird noch etwas ans Men<65> angehengt.
|
||||||
|
$this->DasMenu = $this->$DasMenu.$html;
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Der Seiten HTML Quelcode wird eingelesen.
|
||||||
|
|
||||||
|
public function importHTML($file){
|
||||||
|
//Der HTML Quelltext wird aus einer Datei eingelesen.
|
||||||
|
$this->HTMLDatei = file_get_contents($file);
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setHTML($htmlCode){
|
||||||
|
//Der HTML Quelltext wird direkt gesetzt.
|
||||||
|
$this->HTMLDatei = $htmlCode;
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addNachHTML($htmlCode){
|
||||||
|
//Der HTML Quelltext wird direkt gesetzt.
|
||||||
|
$this->HTMLDatei = $this->HTMLDatei.$htmlCode;
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addVorHTML($htmlCode){
|
||||||
|
//Der HTML Quelltext wird direkt gesetzt.
|
||||||
|
$this->HTMLDatei = $htmlCode.$this->HTMLDatei;
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function DeleteHTML(){
|
||||||
|
//Der HTML Quelltext wird gel<65>scht.
|
||||||
|
$this->HTMLDatei = " ";
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Der inhalt der Seite wird zusammen gesetzt (nicht der quelltext) (%%EchoInhalt%%)
|
||||||
|
|
||||||
|
public function importSeitenInhalt($file){
|
||||||
|
//L<>d einen fertigen Text aus einer datei.
|
||||||
|
$this->DerInhalt = file_get_contents($file);
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSeitenInhalt($html){
|
||||||
|
//Setz den Seiteninhalt und L<>scht den alten Komplett.
|
||||||
|
$this->DerInhalt = $html;
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function importAndAddSeitenInhalt($file){
|
||||||
|
//L<>d einen fertigen Text aus einer datei.
|
||||||
|
$this->DerInhalt = $this->DerInhalt.file_get_contents($file);
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addToSeitenInhalt($html){
|
||||||
|
//Es wird noch weitere Text an den Seiteninhalt angeh<65>ngt.
|
||||||
|
$this->DerInhalt = $this->DerInhalt.$html;
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetSeitenInhalt(){
|
||||||
|
//Der Seiteninhalt wird zur<75>ckgegeben.
|
||||||
|
return $this->DerInhalt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function DeleteSeitenInhalt(){
|
||||||
|
//L<>scht den Seiten inhalt.
|
||||||
|
$this->DerInhalt = " ";
|
||||||
|
$this->isBuild = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ReplaceSeitenInhalt($tag, $text){
|
||||||
|
//Ersezt Seiten Inhalt
|
||||||
|
$this->DerInhalt = str_replace($tag, $text, $this->DerInhalt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ReplaceLayoutInhalt($tag, $text){
|
||||||
|
//Ersezt Layout Inhalt
|
||||||
|
$this->HTMLDatei = str_replace($tag, $text, $this->HTMLDatei);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function CompressHTML(){
|
||||||
|
if($this->isBuild){
|
||||||
|
$this->FertigesHTML = str_replace(" ", "", $this->FertigesHTML);
|
||||||
|
|
||||||
|
$this->FertigesHTML = str_replace(" ", "", $this->FertigesHTML);
|
||||||
|
}else{
|
||||||
|
die("Es kann nur Fertiger HTML Code kompremiert werden.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Hier wird der Fertige HTML Code generiert.
|
||||||
|
//Und alle 3 Teile, Men<65> Titel und inhalt zusammengef<65>gt.
|
||||||
|
public function build(){
|
||||||
|
//Der HTML Code wird zusammen gesetzt.
|
||||||
|
|
||||||
|
$this->FertigesHTML = null; //Der Speicher wird gellert, falls schon einmal Quelltext generiert wurde.
|
||||||
|
$this->FertigesHTML = $this->HTMLDatei; //Und der Unverarbeitete HTML Quelltext eingelesen.
|
||||||
|
|
||||||
|
//Das Men<65> wird in den HTML Quellcode eingef<65>gt.
|
||||||
|
$this->FertigesHTML = str_replace("%%EchoMenu%%", $this->DasMenu, $this->FertigesHTML);
|
||||||
|
|
||||||
|
//Der inhalt wird in den HTML Quellcode eingef<65>gt.
|
||||||
|
$this->FertigesHTML = str_replace("%%EchoInhalt%%", $this->DerInhalt, $this->FertigesHTML);
|
||||||
|
|
||||||
|
//Die Status Meldung wird in den HTML Quellcode eingef<65>gt.
|
||||||
|
$this->FertigesHTML = str_replace("%%StatusMeldung%%", $this->StatusMeldung, $this->FertigesHTML);
|
||||||
|
|
||||||
|
//Der Titel wird in den HTML Quellcode eingef<65>gt.
|
||||||
|
$this->FertigesHTML = str_replace("%%EchoTitle%%", $this->HTMLTitle, $this->FertigesHTML);
|
||||||
|
|
||||||
|
//Der HTML Header wird in den HTML Quellcode eingef<65>gt.
|
||||||
|
$this->FertigesHTML = str_replace("%%echoHeader%%", $this->HTMLHeader, $this->FertigesHTML);
|
||||||
|
|
||||||
|
//Der Titel wird in den HTML Quellcode eingef<65>gt.
|
||||||
|
$this->FertigesHTML = str_replace("%%datum%%", date("Y-m-dTH:i+2"), $this->FertigesHTML);
|
||||||
|
|
||||||
|
//Der Counter wird in den HTML Quellcode eingef<65>gt.
|
||||||
|
$this->FertigesHTML = str_replace("%%GET_SITE%%", @$_GET['seite'], $this->FertigesHTML);
|
||||||
|
|
||||||
|
//Die IP Adresse wird in den HTML Quellcode eingef<65>gt.
|
||||||
|
$this->FertigesHTML = str_replace("%%GET_IP%%", @$_SERVER["REMOTE_ADDR"], $this->FertigesHTML);
|
||||||
|
|
||||||
|
$this->isBuild = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Hier wird der Fertige HTML ausgegeben
|
||||||
|
public function ausgabe(){
|
||||||
|
if($this->isBuild){
|
||||||
|
return $this->FertigesHTML;
|
||||||
|
}else{
|
||||||
|
die("Bitte erst den HTML Code zusammensetzen.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PHPMailer Exception class.
|
||||||
|
* PHP Version 5.5.
|
||||||
|
*
|
||||||
|
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
|
||||||
|
*
|
||||||
|
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||||
|
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||||
|
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||||
|
* @author Brent R. Matzelle (original founder)
|
||||||
|
* @copyright 2012 - 2017 Marcus Bointon
|
||||||
|
* @copyright 2010 - 2012 Jim Jagielski
|
||||||
|
* @copyright 2004 - 2009 Andy Prevost
|
||||||
|
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||||
|
* @note This program is distributed in the hope that it will be useful - WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPMailer exception handler.
|
||||||
|
*
|
||||||
|
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
|
||||||
|
*/
|
||||||
|
class Exception extends \Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Prettify error message output.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function errorMessage()
|
||||||
|
{
|
||||||
|
return '<strong>' . htmlspecialchars($this->getMessage()) . "</strong><br />\n";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PHPMailer - PHP email creation and transport class.
|
||||||
|
* PHP Version 5.5.
|
||||||
|
*
|
||||||
|
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
|
||||||
|
*
|
||||||
|
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||||
|
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||||
|
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||||
|
* @author Brent R. Matzelle (original founder)
|
||||||
|
* @copyright 2012 - 2015 Marcus Bointon
|
||||||
|
* @copyright 2010 - 2012 Jim Jagielski
|
||||||
|
* @copyright 2004 - 2009 Andy Prevost
|
||||||
|
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||||
|
* @note This program is distributed in the hope that it will be useful - WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use League\OAuth2\Client\Grant\RefreshToken;
|
||||||
|
use League\OAuth2\Client\Provider\AbstractProvider;
|
||||||
|
use League\OAuth2\Client\Token\AccessToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAuth - OAuth2 authentication wrapper class.
|
||||||
|
* Uses the oauth2-client package from the League of Extraordinary Packages.
|
||||||
|
*
|
||||||
|
* @see http://oauth2-client.thephpleague.com
|
||||||
|
*
|
||||||
|
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||||
|
*/
|
||||||
|
class OAuth
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* An instance of the League OAuth Client Provider.
|
||||||
|
*
|
||||||
|
* @var AbstractProvider
|
||||||
|
*/
|
||||||
|
protected $provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current OAuth access token.
|
||||||
|
*
|
||||||
|
* @var AccessToken
|
||||||
|
*/
|
||||||
|
protected $oauthToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user's email address, usually used as the login ID
|
||||||
|
* and also the from address when sending email.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $oauthUserEmail = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client secret, generated in the app definition of the service you're connecting to.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $oauthClientSecret = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client ID, generated in the app definition of the service you're connecting to.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $oauthClientId = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The refresh token, used to obtain new AccessTokens.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $oauthRefreshToken = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAuth constructor.
|
||||||
|
*
|
||||||
|
* @param array $options Associative array containing
|
||||||
|
* `provider`, `userName`, `clientSecret`, `clientId` and `refreshToken` elements
|
||||||
|
*/
|
||||||
|
public function __construct($options)
|
||||||
|
{
|
||||||
|
$this->provider = $options['provider'];
|
||||||
|
$this->oauthUserEmail = $options['userName'];
|
||||||
|
$this->oauthClientSecret = $options['clientSecret'];
|
||||||
|
$this->oauthClientId = $options['clientId'];
|
||||||
|
$this->oauthRefreshToken = $options['refreshToken'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a new RefreshToken.
|
||||||
|
*
|
||||||
|
* @return RefreshToken
|
||||||
|
*/
|
||||||
|
protected function getGrant()
|
||||||
|
{
|
||||||
|
return new RefreshToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a new AccessToken.
|
||||||
|
*
|
||||||
|
* @return AccessToken
|
||||||
|
*/
|
||||||
|
protected function getToken()
|
||||||
|
{
|
||||||
|
return $this->provider->getAccessToken(
|
||||||
|
$this->getGrant(),
|
||||||
|
['refresh_token' => $this->oauthRefreshToken]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a base64-encoded OAuth token.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getOauth64()
|
||||||
|
{
|
||||||
|
// Get a new token if it's not available or has expired
|
||||||
|
if (null === $this->oauthToken || $this->oauthToken->hasExpired()) {
|
||||||
|
$this->oauthToken = $this->getToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
return base64_encode(
|
||||||
|
'user=' .
|
||||||
|
$this->oauthUserEmail .
|
||||||
|
"\001auth=Bearer " .
|
||||||
|
$this->oauthToken .
|
||||||
|
"\001\001"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,419 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PHPMailer POP-Before-SMTP Authentication Class.
|
||||||
|
* PHP Version 5.5.
|
||||||
|
*
|
||||||
|
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
|
||||||
|
*
|
||||||
|
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||||
|
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||||
|
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||||
|
* @author Brent R. Matzelle (original founder)
|
||||||
|
* @copyright 2012 - 2019 Marcus Bointon
|
||||||
|
* @copyright 2010 - 2012 Jim Jagielski
|
||||||
|
* @copyright 2004 - 2009 Andy Prevost
|
||||||
|
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||||
|
* @note This program is distributed in the hope that it will be useful - WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHPMailer POP-Before-SMTP Authentication Class.
|
||||||
|
* Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication.
|
||||||
|
* 1) This class does not support APOP authentication.
|
||||||
|
* 2) Opening and closing lots of POP3 connections can be quite slow. If you need
|
||||||
|
* to send a batch of emails then just perform the authentication once at the start,
|
||||||
|
* and then loop through your mail sending script. Providing this process doesn't
|
||||||
|
* take longer than the verification period lasts on your POP3 server, you should be fine.
|
||||||
|
* 3) This is really ancient technology; you should only need to use it to talk to very old systems.
|
||||||
|
* 4) This POP3 class is deliberately lightweight and incomplete, implementing just
|
||||||
|
* enough to do authentication.
|
||||||
|
* If you want a more complete class there are other POP3 classes for PHP available.
|
||||||
|
*
|
||||||
|
* @author Richard Davey (original author) <rich@corephp.co.uk>
|
||||||
|
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
|
||||||
|
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
|
||||||
|
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
class POP3
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The POP3 PHPMailer Version number.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const VERSION = '6.1.5';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default POP3 port number.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
const DEFAULT_PORT = 110;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default timeout in seconds.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
const DEFAULT_TIMEOUT = 30;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debug display level.
|
||||||
|
* Options: 0 = no, 1+ = yes.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $do_debug = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POP3 mail server hostname.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $host;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POP3 port number.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $port;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POP3 Timeout Value in seconds.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $tval;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POP3 username.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $username;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POP3 password.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource handle for the POP3 connection socket.
|
||||||
|
*
|
||||||
|
* @var resource
|
||||||
|
*/
|
||||||
|
protected $pop_conn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are we connected?
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $connected = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error container.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $errors = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Line break constant.
|
||||||
|
*/
|
||||||
|
const LE = "\r\n";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple static wrapper for all-in-one POP before SMTP.
|
||||||
|
*
|
||||||
|
* @param string $host The hostname to connect to
|
||||||
|
* @param int|bool $port The port number to connect to
|
||||||
|
* @param int|bool $timeout The timeout value
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @param int $debug_level
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function popBeforeSmtp(
|
||||||
|
$host,
|
||||||
|
$port = false,
|
||||||
|
$timeout = false,
|
||||||
|
$username = '',
|
||||||
|
$password = '',
|
||||||
|
$debug_level = 0
|
||||||
|
) {
|
||||||
|
$pop = new self();
|
||||||
|
|
||||||
|
return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate with a POP3 server.
|
||||||
|
* A connect, login, disconnect sequence
|
||||||
|
* appropriate for POP-before SMTP authorisation.
|
||||||
|
*
|
||||||
|
* @param string $host The hostname to connect to
|
||||||
|
* @param int|bool $port The port number to connect to
|
||||||
|
* @param int|bool $timeout The timeout value
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @param int $debug_level
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0)
|
||||||
|
{
|
||||||
|
$this->host = $host;
|
||||||
|
// If no port value provided, use default
|
||||||
|
if (false === $port) {
|
||||||
|
$this->port = static::DEFAULT_PORT;
|
||||||
|
} else {
|
||||||
|
$this->port = (int) $port;
|
||||||
|
}
|
||||||
|
// If no timeout value provided, use default
|
||||||
|
if (false === $timeout) {
|
||||||
|
$this->tval = static::DEFAULT_TIMEOUT;
|
||||||
|
} else {
|
||||||
|
$this->tval = (int) $timeout;
|
||||||
|
}
|
||||||
|
$this->do_debug = $debug_level;
|
||||||
|
$this->username = $username;
|
||||||
|
$this->password = $password;
|
||||||
|
// Reset the error log
|
||||||
|
$this->errors = [];
|
||||||
|
// connect
|
||||||
|
$result = $this->connect($this->host, $this->port, $this->tval);
|
||||||
|
if ($result) {
|
||||||
|
$login_result = $this->login($this->username, $this->password);
|
||||||
|
if ($login_result) {
|
||||||
|
$this->disconnect();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We need to disconnect regardless of whether the login succeeded
|
||||||
|
$this->disconnect();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to a POP3 server.
|
||||||
|
*
|
||||||
|
* @param string $host
|
||||||
|
* @param int|bool $port
|
||||||
|
* @param int $tval
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function connect($host, $port = false, $tval = 30)
|
||||||
|
{
|
||||||
|
// Are we already connected?
|
||||||
|
if ($this->connected) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//On Windows this will raise a PHP Warning error if the hostname doesn't exist.
|
||||||
|
//Rather than suppress it with @fsockopen, capture it cleanly instead
|
||||||
|
set_error_handler([$this, 'catchWarning']);
|
||||||
|
|
||||||
|
if (false === $port) {
|
||||||
|
$port = static::DEFAULT_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect to the POP3 server
|
||||||
|
$errno = 0;
|
||||||
|
$errstr = '';
|
||||||
|
$this->pop_conn = fsockopen(
|
||||||
|
$host, // POP3 Host
|
||||||
|
$port, // Port #
|
||||||
|
$errno, // Error Number
|
||||||
|
$errstr, // Error Message
|
||||||
|
$tval
|
||||||
|
); // Timeout (seconds)
|
||||||
|
// Restore the error handler
|
||||||
|
restore_error_handler();
|
||||||
|
|
||||||
|
// Did we connect?
|
||||||
|
if (false === $this->pop_conn) {
|
||||||
|
// It would appear not...
|
||||||
|
$this->setError(
|
||||||
|
"Failed to connect to server $host on port $port. errno: $errno; errstr: $errstr"
|
||||||
|
);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increase the stream time-out
|
||||||
|
stream_set_timeout($this->pop_conn, $tval, 0);
|
||||||
|
|
||||||
|
// Get the POP3 server response
|
||||||
|
$pop3_response = $this->getResponse();
|
||||||
|
// Check for the +OK
|
||||||
|
if ($this->checkResponse($pop3_response)) {
|
||||||
|
// The connection is established and the POP3 server is talking
|
||||||
|
$this->connected = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log in to the POP3 server.
|
||||||
|
* Does not support APOP (RFC 2828, 4949).
|
||||||
|
*
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function login($username = '', $password = '')
|
||||||
|
{
|
||||||
|
if (!$this->connected) {
|
||||||
|
$this->setError('Not connected to POP3 server');
|
||||||
|
}
|
||||||
|
if (empty($username)) {
|
||||||
|
$username = $this->username;
|
||||||
|
}
|
||||||
|
if (empty($password)) {
|
||||||
|
$password = $this->password;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the Username
|
||||||
|
$this->sendString("USER $username" . static::LE);
|
||||||
|
$pop3_response = $this->getResponse();
|
||||||
|
if ($this->checkResponse($pop3_response)) {
|
||||||
|
// Send the Password
|
||||||
|
$this->sendString("PASS $password" . static::LE);
|
||||||
|
$pop3_response = $this->getResponse();
|
||||||
|
if ($this->checkResponse($pop3_response)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnect from the POP3 server.
|
||||||
|
*/
|
||||||
|
public function disconnect()
|
||||||
|
{
|
||||||
|
$this->sendString('QUIT');
|
||||||
|
//The QUIT command may cause the daemon to exit, which will kill our connection
|
||||||
|
//So ignore errors here
|
||||||
|
try {
|
||||||
|
@fclose($this->pop_conn);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
//Do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a response from the POP3 server.
|
||||||
|
*
|
||||||
|
* @param int $size The maximum number of bytes to retrieve
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getResponse($size = 128)
|
||||||
|
{
|
||||||
|
$response = fgets($this->pop_conn, $size);
|
||||||
|
if ($this->do_debug >= 1) {
|
||||||
|
echo 'Server -> Client: ', $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send raw data to the POP3 server.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function sendString($string)
|
||||||
|
{
|
||||||
|
if ($this->pop_conn) {
|
||||||
|
if ($this->do_debug >= 2) { //Show client messages when debug >= 2
|
||||||
|
echo 'Client -> Server: ', $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fwrite($this->pop_conn, $string, strlen($string));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the POP3 server response.
|
||||||
|
* Looks for for +OK or -ERR.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function checkResponse($string)
|
||||||
|
{
|
||||||
|
if (strpos($string, '+OK') !== 0) {
|
||||||
|
$this->setError("Server reported an error: $string");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an error to the internal error store.
|
||||||
|
* Also display debug output if it's enabled.
|
||||||
|
*
|
||||||
|
* @param string $error
|
||||||
|
*/
|
||||||
|
protected function setError($error)
|
||||||
|
{
|
||||||
|
$this->errors[] = $error;
|
||||||
|
if ($this->do_debug >= 1) {
|
||||||
|
echo '<pre>';
|
||||||
|
foreach ($this->errors as $e) {
|
||||||
|
print_r($e);
|
||||||
|
}
|
||||||
|
echo '</pre>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an array of error messages, if any.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getErrors()
|
||||||
|
{
|
||||||
|
return $this->errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POP3 connection error handler.
|
||||||
|
*
|
||||||
|
* @param int $errno
|
||||||
|
* @param string $errstr
|
||||||
|
* @param string $errfile
|
||||||
|
* @param int $errline
|
||||||
|
*/
|
||||||
|
protected function catchWarning($errno, $errstr, $errfile, $errline)
|
||||||
|
{
|
||||||
|
$this->setError(
|
||||||
|
'Connecting to the POP3 server raised a PHP warning:' .
|
||||||
|
"errno: $errno errstr: $errstr; errfile: $errfile; errline: $errline"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,156 @@
|
||||||
|
<?php
|
||||||
|
class OpenSim
|
||||||
|
{
|
||||||
|
public function isLoginValid($name, $password)
|
||||||
|
{
|
||||||
|
global $RUNTIME;
|
||||||
|
|
||||||
|
$statementUser = $RUNTIME['PDO']->prepare("SELECT * FROM UserAccounts WHERE FirstName = ? AND LastName = ? LIMIT 1");
|
||||||
|
$statementUser->execute(explode(" ", trim($name)));
|
||||||
|
|
||||||
|
while($rowUser = $statementUser->fetch())
|
||||||
|
{
|
||||||
|
$statementAuth = $RUNTIME['PDO']->prepare("SELECT * FROM auth WHERE UUID = ? LIMIT 1");
|
||||||
|
$statementAuth->execute(array($rowUser['PrincipalID']));
|
||||||
|
|
||||||
|
while($rowAuth = $statementAuth->fetch())
|
||||||
|
{
|
||||||
|
if(md5(md5($password).":".$rowAuth['passwordSalt']) == $rowAuth['passwordHash'])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserName($userID)
|
||||||
|
{
|
||||||
|
global $RUNTIME;
|
||||||
|
|
||||||
|
if(isset($RUNTIME['CACHE']['USERNAME'][$userID]))
|
||||||
|
return $RUNTIME['CACHE']['USERNAME'][$userID];
|
||||||
|
|
||||||
|
$statementUser = $RUNTIME['PDO']->prepare("SELECT * FROM UserAccounts WHERE PrincipalID = ?");
|
||||||
|
$statementUser->execute(array($userID));
|
||||||
|
|
||||||
|
while($rowUser = $statementUser->fetch())
|
||||||
|
{
|
||||||
|
$RUNTIME['CACHE']['USERNAME'][$userID] = $rowUser['FirstName']." ".$rowUser['LastName'];
|
||||||
|
return $rowUser['FirstName']." ".$rowUser['LastName'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown User";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserUUID($UserName)
|
||||||
|
{
|
||||||
|
global $RUNTIME;
|
||||||
|
|
||||||
|
$statementUser = $RUNTIME['PDO']->prepare("SELECT * FROM UserAccounts");
|
||||||
|
$statementUser->execute();
|
||||||
|
|
||||||
|
while($rowUser = $statementUser->fetch())
|
||||||
|
{
|
||||||
|
$SQLUserName = $rowUser['FirstName']." ".$rowUser['LastName'];
|
||||||
|
|
||||||
|
if($SQLUserName == $UserName)
|
||||||
|
{
|
||||||
|
return $rowUser['PrincipalID'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRegionName($regionID)
|
||||||
|
{
|
||||||
|
global $RUNTIME;
|
||||||
|
|
||||||
|
$statementRegion = $RUNTIME['PDO']->prepare("SELECT * FROM regions WHERE uuid = ?");
|
||||||
|
$statementRegion->execute(array($regionID));
|
||||||
|
|
||||||
|
while($rowRegion = $statementRegion->fetch())
|
||||||
|
{
|
||||||
|
return $rowRegion['regionName'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown Region";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPartner($userID)
|
||||||
|
{
|
||||||
|
global $RUNTIME;
|
||||||
|
|
||||||
|
$statement = $RUNTIME['PDO']->prepare("SELECT * FROM userprofile WHERE useruuid = ?");
|
||||||
|
$statement->execute(array($userID));
|
||||||
|
|
||||||
|
while($row = $statement->fetch())
|
||||||
|
{
|
||||||
|
if($row['profilePartner'] != "00000000-0000-0000-0000-000000000000")
|
||||||
|
return $row['profilePartner'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function allowOfflineIM($userID)
|
||||||
|
{
|
||||||
|
global $RUNTIME;
|
||||||
|
|
||||||
|
$statement = $RUNTIME['PDO']->prepare("SELECT * FROM usersettings WHERE useruuid = ?");
|
||||||
|
$statement->execute(array($userID));
|
||||||
|
|
||||||
|
while($row = $statement->fetch())
|
||||||
|
{
|
||||||
|
return strtoupper($row['imviaemail']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "FALSE";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserMail($userID)
|
||||||
|
{
|
||||||
|
global $RUNTIME;
|
||||||
|
|
||||||
|
$statement = $RUNTIME['PDO']->prepare("SELECT * FROM UserAccounts WHERE PrincipalID = ?");
|
||||||
|
$statement->execute(array($userID));
|
||||||
|
|
||||||
|
while($row = $statement->fetch())
|
||||||
|
{
|
||||||
|
return $row['Email'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserCount()
|
||||||
|
{
|
||||||
|
global $RUNTIME;
|
||||||
|
|
||||||
|
$statementUser = $RUNTIME['PDO']->prepare("SELECT * FROM UserAccounts");
|
||||||
|
$statementUser->execute();
|
||||||
|
return $statementUser->rowCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRegionCount()
|
||||||
|
{
|
||||||
|
global $RUNTIME;
|
||||||
|
|
||||||
|
$statementUser = $RUNTIME['PDO']->prepare("SELECT * FROM regions");
|
||||||
|
$statementUser->execute();
|
||||||
|
return $statementUser->rowCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOnlineCount()
|
||||||
|
{
|
||||||
|
global $RUNTIME;
|
||||||
|
|
||||||
|
|
||||||
|
$statementUser = $RUNTIME['PDO']->prepare("SELECT * FROM Presence");
|
||||||
|
$statementUser->execute();
|
||||||
|
return $statementUser->rowCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
function fillString($string, $targetlength)
|
||||||
|
{
|
||||||
|
while(strlen($string) < $targetlength)
|
||||||
|
{
|
||||||
|
$string = "0".$string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function left($str, $length)
|
||||||
|
{
|
||||||
|
return substr($str, 0, $length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function right($str, $length)
|
||||||
|
{
|
||||||
|
return substr($str, -$length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDataFromHTTP($URL, $contend = "", $requestTyp = "application/text")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if($contend != "")
|
||||||
|
{
|
||||||
|
return @file_get_contents($URL, true, stream_context_create(array('http' => array('header' => 'Content-type: '.$requestTyp, 'method' => 'POST', 'timeout' => 0.5, 'content' => $contend))));
|
||||||
|
}else{
|
||||||
|
return @file_get_contents($URL);
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo "(HTTP REQUEST) error while conntect to remote server. : ".$URL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendInworldIM($fromUUID, $toUUID, $fromName, $targetURL, $text)
|
||||||
|
{
|
||||||
|
$rawXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?><methodCall><methodName>grid_instant_message</methodName><params><param><value><struct><member><name>position_x</name><value><string>0</string></value></member><member><name>position_y</name><value><string>0</string></value></member><member><name>position_z</name><value><string>0</string></value></member><member><name>to_agent_id</name><value><string>".$toUUID."</string></value></member><member><name>from_agent_session</name><value><string>00000000-0000-0000-0000-000000000000</string></value></member><member><name>im_session_id</name><value><string>".$fromUUID."</string></value></member><member><name>from_agent_name</name><value><string>".$fromName."</string></value></member><member><name>from_agent_id</name><value><string>".$fromUUID."</string></value></member><member><name>binary_bucket</name><value><string>AA==</string></value></member><member><name>region_handle</name><value><i4>0</i4></value></member><member><name>region_id</name><value><string>00000000-0000-0000-0000-000000000000</string></value></member><member><name>parent_estate_id</name><value><string>1</string></value></member><member><name>timestamp</name><value><string>".time()."</string></value></member><member><name>dialog</name><value><string>AA==</string></value></member><member><name>offline</name><value><string>AA==</string></value></member><member><name>from_group</name><value><string>FALSE</string></value></member><member><name>message</name><value><string>".$text."</string></value></member></struct></value></param></params></methodCall>";
|
||||||
|
getDataFromHTTP($targetURL, $rawXML, "text/xml");
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
$RUNTIME['PDO'] = new PDO('mysql:host=...;dbname=...', '...', '...'); //The Robust DB
|
||||||
|
|
||||||
|
$RUNTIME['SMTP']['SERVER'] = "localhost";
|
||||||
|
$RUNTIME['SMTP']['PORT'] = 25;
|
||||||
|
$RUNTIME['SMTP']['ADRESS'] = "noreplay@localhost";
|
||||||
|
$RUNTIME['SMTP']['USER'] = "noreplay@localhost";
|
||||||
|
$RUNTIME['SMTP']['PASS'] = "...";
|
||||||
|
|
||||||
|
$RUNTIME['GRID']['NAME'] = "OpenSim";
|
||||||
|
$RUNTIME['GRID']['MAIN_NEWS'] = "Yet an other OpenSim Grid.";
|
||||||
|
$RUNTIME['GRID']['HOMEURL'] = "http://...:8002";
|
||||||
|
?>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
$InventarObjektStatement = $RUNTIME['PDO']->prepare("SELECT * FROM inventoryitems ORDER BY avatarID ASC LIMIT 50000");
|
||||||
|
$InventarObjektStatement->execute();
|
||||||
|
|
||||||
|
while($InventarObjektRow = $InventarObjektStatement->fetch())
|
||||||
|
{
|
||||||
|
//echo "Check Inventory Item '".$InventarObjektRow['inventoryName']."' from '".$InventarObjektRow['avatarID']."'.\n";
|
||||||
|
|
||||||
|
$AssetMetaDataStatement = $RUNTIME['PDO']->prepare("SELECT * FROM fsassets WHERE id = ?");
|
||||||
|
$AssetMetaDataStatement->execute(array($InventarObjektRow['assetID']));
|
||||||
|
|
||||||
|
if($AssetMetaDataStatement->rowCount() == 0)
|
||||||
|
{
|
||||||
|
if(!(left($InventarObjektRow['inventoryName'], 8) == '[DEFEKT]'))
|
||||||
|
{
|
||||||
|
$renameQuery = $RUNTIME['PDO']->prepare("UPDATE inventoryitems SET inventoryName = ? WHERE inventoryID = ? AND assetID = ?");
|
||||||
|
$renameQuery->execute(array(substr('[DEFEKT] '.$InventarObjektRow['inventoryName'], 0, 64), $InventarObjektRow['inventoryID'], $InventarObjektRow['assetID']));
|
||||||
|
|
||||||
|
echo "Found new missing asset for item '".$InventarObjektRow['inventoryName']."' from '".$RUNTIME['OPENSIM']->getUserName($InventarObjektRow['avatarID'])."'.\n";
|
||||||
|
sendInworldIM("00000000-0000-0000-0000-000000000000", $InventarObjektRow['avatarID'], "Inventory", $RUNTIME['GRID']['HOMEURL'], "WARNUNG: Die Assetdaten von einem deiner Inventarobjekte wurden nicht in der DB gefunden! Item Name: '".$InventarObjektRow['inventoryName']."'.");
|
||||||
|
}else{
|
||||||
|
echo "Found missing asset for item '".$InventarObjektRow['inventoryName']."' from '".$RUNTIME['OPENSIM']->getUserName($InventarObjektRow['avatarID'])."'.\n";
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
echo "Checking asset for item '".$InventarObjektRow['inventoryName']."' from '".$RUNTIME['OPENSIM']->getUserName($InventarObjektRow['avatarID'])."'.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1,102 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$statement = $RUNTIME['PDO']->prepare("CREATE TABLE IF NOT EXISTS im_offline_send (`id` int(6) NOT NULL DEFAULT 0) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci");
|
||||||
|
$statement->execute();
|
||||||
|
|
||||||
|
function isMailAllreadySend($id)
|
||||||
|
{
|
||||||
|
GLOBAL $RUNTIME;
|
||||||
|
|
||||||
|
$statement = $RUNTIME['PDO']->prepare("SELECT * FROM im_offline_send WHERE id = ?");
|
||||||
|
$statement->execute(array($id));
|
||||||
|
|
||||||
|
if($statement->rowCount() != 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$IMTYP = array(
|
||||||
|
"0" => "eine Nachricht",
|
||||||
|
"3" => "eine Gruppeneinladung",
|
||||||
|
"4" => "ein Inventaritem",
|
||||||
|
"5" => "eine Bestätigung zur Annahme von Inventar",
|
||||||
|
"6" => "eine Information zur Ablehnung von Inventar",
|
||||||
|
"7" => "eine Aufforderung zur Gruppenwahl",
|
||||||
|
"9" => "ein Inventaritem von einem Script",
|
||||||
|
"19" => "eine Nachricht von einem Script",
|
||||||
|
"32" => "eine Gruppennachricht",
|
||||||
|
"38" => "eine Freundschaftsanfrage",
|
||||||
|
"39" => "eine Bestätigung über die Annahme der Freundschaft",
|
||||||
|
"40" => "eine Information über das Ablehnen der Freundschaft"
|
||||||
|
);
|
||||||
|
|
||||||
|
//$statement = $RUNTIME['PDO']->prepare("SELECT * FROM im_offline WHERE PrincipalID = '1148b04d-7a93-49e9-b3c9-ea0cdeec38f7'");
|
||||||
|
$statement = $RUNTIME['PDO']->prepare("SELECT * FROM im_offline");
|
||||||
|
$statement->execute();
|
||||||
|
|
||||||
|
while($row = $statement->fetch())
|
||||||
|
{
|
||||||
|
$email = $RUNTIME['OPENSIM']->getUserMail($row['PrincipalID']);
|
||||||
|
$allowOfflineIM = $RUNTIME['OPENSIM']->allowOfflineIM($row['PrincipalID']);
|
||||||
|
|
||||||
|
if($email != "" && $allowOfflineIM == "TRUE")
|
||||||
|
{
|
||||||
|
if(isMailAllreadySend($row['ID']) == FALSE)
|
||||||
|
{
|
||||||
|
$statementSend = $RUNTIME['PDO']->prepare('INSERT INTO im_offline_send (id) VALUES (:idnummer)');
|
||||||
|
$statementSend->execute(['idnummer' => $row['ID']]);
|
||||||
|
|
||||||
|
$mail = new PHPMailer(true);
|
||||||
|
|
||||||
|
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
|
||||||
|
$mail->isSMTP();
|
||||||
|
$mail->Host = $RUNTIME['SMTP']['SERVER'];
|
||||||
|
$mail->SMTPAuth = true;
|
||||||
|
$mail->Username = $RUNTIME['SMTP']['USER'];
|
||||||
|
$mail->Password = $RUNTIME['SMTP']['PASS'];
|
||||||
|
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
|
||||||
|
$mail->Port = $RUNTIME['SMTP']['PORT'];
|
||||||
|
|
||||||
|
$mail->setFrom($RUNTIME['SMTP']['ADRESS'], $RUNTIME['GRID']['NAME']);
|
||||||
|
$mail->addAddress($email, $RUNTIME['OPENSIM']->getUserName($row['PrincipalID']));
|
||||||
|
|
||||||
|
$XMLMESSAGE = new SimpleXMLElement($row['Message']);
|
||||||
|
|
||||||
|
$HTMLMESSAGE = "Du hast ".$IMTYP["".$XMLMESSAGE->dialog.""]." in ".$RUNTIME['GRID']['NAME']." bekommen. <br><p><ul><li>".htmlspecialchars($XMLMESSAGE->message)."</li></ul></p>Gesendet von: ";
|
||||||
|
|
||||||
|
if(isset($XMLMESSAGE->fromAgentName))
|
||||||
|
$HTMLMESSAGE .= $XMLMESSAGE->fromAgentName;
|
||||||
|
|
||||||
|
if(isset($XMLMESSAGE->RegionID) && isset($XMLMESSAGE->Position))
|
||||||
|
{
|
||||||
|
if($XMLMESSAGE->Position->X != 0 || $XMLMESSAGE->Position->X != 0 || $XMLMESSAGE->Position->X != 0)
|
||||||
|
{
|
||||||
|
$HTMLMESSAGE .= " @ ".$RUNTIME['OPENSIM']->getRegionName($XMLMESSAGE->RegionID)."/".$XMLMESSAGE->Position->X."/".$XMLMESSAGE->Position->Y."/".$XMLMESSAGE->Position->Z;
|
||||||
|
}else{
|
||||||
|
$HTMLMESSAGE .= " @ ".$RUNTIME['OPENSIM']->getRegionName($XMLMESSAGE->RegionID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//die($HTMLMESSAGE);
|
||||||
|
|
||||||
|
$HTML = new HTML();
|
||||||
|
$HTML->importHTML("style/mail.html");
|
||||||
|
$HTML->setSeitenInhalt($HTMLMESSAGE);
|
||||||
|
$HTML->build();
|
||||||
|
|
||||||
|
$mail->isHTML(true);
|
||||||
|
$mail->Subject = "Du hast ".$IMTYP["".$XMLMESSAGE->dialog.""]." in ".$RUNTIME['GRID']['NAME'].".";
|
||||||
|
$mail->Body = $HTML->ausgabe();
|
||||||
|
$mail->AltBody = strip_tags($HTMLMESSAGE);
|
||||||
|
|
||||||
|
//print_r($mail);
|
||||||
|
$mail->send();
|
||||||
|
}else{
|
||||||
|
//echo $row['ID']." wurde bereits gesendet.";
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//echo $row['PrincipalID']." möchte keine offline IM oder hat keine E-MAIL Adresse hinterlegt.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
date_default_timezone_set("Europe/Berlin");
|
||||||
|
header('Strict-Transport-Security: max-age=657000');
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
include_once 'classen/MAIL/PHPMailer.php';
|
||||||
|
include_once 'classen/MAIL/SMTP.php';
|
||||||
|
|
||||||
|
include_once("classen/utils.php");
|
||||||
|
include_once("classen/HTML.php");
|
||||||
|
include_once("classen/GoogleAuthenticator.php");
|
||||||
|
include_once("classen/OpenSim.php");
|
||||||
|
|
||||||
|
$RUNTIME = array();
|
||||||
|
$RUNTIME['OPENSIM'] = new OpenSim();
|
||||||
|
|
||||||
|
include_once("config.php");
|
||||||
|
|
||||||
|
|
||||||
|
if ($handle = opendir('./cron/'))
|
||||||
|
{
|
||||||
|
while (false !== ($entry = readdir($handle)))
|
||||||
|
{
|
||||||
|
if ($entry != "." && $entry != "..")
|
||||||
|
{
|
||||||
|
include_once "./cron/".$entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir($handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"54.1","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"6088","AtvPrm":"0","AtvScr":"246","ScrLPS":"39.34","PktsIn":"13","PktOut":"210","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"234","Uptime":"09:42:09.8938510","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"3182","Mesh Objects":"2906","XEngine Thread Count":"5","Util Thread Count":"3","System Thread Count":"1","ProcMem":"884,304"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"55","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"8416","AtvPrm":"0","AtvScr":"293","ScrLPS":"186.66","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0.59","OthrFt":"0.01","AgntFt":"0","ImgsFt":"0","Memory":"84","Uptime":"01:06:11.6632650","Version":"OpenSim 0.9.2.0.05 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"2868","Mesh Objects":"5548","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"0","ProcMem":"419,948"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"54.9","PhyFPS":"52.2","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"7258","AtvPrm":"0","AtvScr":"492","ScrLPS":"271.85","PktsIn":"9","PktOut":"38","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.21","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"247","Uptime":"09:42:24.3060582","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"4045","Mesh Objects":"3213","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"1","ProcMem":"727,100"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"55","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"0","AtvPrm":"0","AtvScr":"0","ScrLPS":"0","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"11","Uptime":"01:37:09.3444630","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"0","Mesh Objects":"0","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"0","ProcMem":"130,996"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"52.2","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"1472","AtvPrm":"0","AtvScr":"80","ScrLPS":"29.65","PktsIn":"11","PktOut":"12","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.19","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"32","Uptime":"2.18:08:48.7446913","Version":"OpenSim 0.9.2.0.04 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"1411","Mesh Objects":"61","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"1","ProcMem":"96,288"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"54.9","PhyFPS":"52.2","AgntUp":"0","RootAg":"5","ChldAg":"0","Prims":"6518","AtvPrm":"0","AtvScr":"358","ScrLPS":"511.42","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.22","NetFt":"0","PhysFt":"0.01","OthrFt":"0.03","AgntFt":"0","ImgsFt":"0","Memory":"129","Uptime":"09:42:39.2045040","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"3382","Mesh Objects":"3136","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"1","ProcMem":"303,228"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"55","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"322","AtvPrm":"0","AtvScr":"31","ScrLPS":"5","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"26","Uptime":"00:37:32.8217740","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"46","Mesh Objects":"276","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"0","ProcMem":"152,316"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"52.2","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"31674","AtvPrm":"0","AtvScr":"588","ScrLPS":"27.08","PktsIn":"18","PktOut":"109","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.19","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"433","Uptime":"3.13:59:59.6505372","Version":"OpenSim 0.9.2.0.04 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"25395","Mesh Objects":"6279","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"1","ProcMem":"766,840"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"55","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"4214","AtvPrm":"0","AtvScr":"50","ScrLPS":"0","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0.02","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"103","Uptime":"00:17:43.2901890","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"4093","Mesh Objects":"121","XEngine Thread Count":"0","Util Thread Count":"5","System Thread Count":"0","ProcMem":"344,652"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"54.8","PhyFPS":"52.1","AgntUp":"9.29","RootAg":"7","ChldAg":"0","Prims":"27102","AtvPrm":"0","AtvScr":"1565","ScrLPS":"37.48","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.25","NetFt":"0","PhysFt":"0.01","OthrFt":"0.12","AgntFt":"0.46","ImgsFt":"0","Memory":"611","Uptime":"3.13:57:45.1766615","Version":"OpenSim 0.9.2.0.04 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"17068","Mesh Objects":"10034","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"4","ProcMem":"787,972"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55.2","PhyFPS":"52.4","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"407","AtvPrm":"0","AtvScr":"-9","ScrLPS":"0","PktsIn":"21","PktOut":"5","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.12","NetFt":"0","PhysFt":"0","OthrFt":"0.02","AgntFt":"0","ImgsFt":"0","Memory":"17","Uptime":"3.14:15:40.0902327","Version":"OpenSim 0.9.2.0.04 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"258","Mesh Objects":"149","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"1","ProcMem":"68,496"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"53.8","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"6","AtvPrm":"0","AtvScr":"3","ScrLPS":"0","PktsIn":"22","PktOut":"125","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"12","Uptime":"09:35:02.8857695","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"6","Mesh Objects":"0","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"1","ProcMem":"100,708"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"45.5","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"1531","AtvPrm":"0","AtvScr":"18","ScrLPS":"0","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0","OthrFt":"0.04","AgntFt":"0","ImgsFt":"0","Memory":"61","Uptime":"2.18:50:04.2946060","Version":"OpenSim 0.9.2.0.04 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"1413","Mesh Objects":"118","XEngine Thread Count":"0","Util Thread Count":"4","System Thread Count":"1","ProcMem":"141,532"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"55","AgntUp":"0","RootAg":"1","ChldAg":"0","Prims":"510","AtvPrm":"0","AtvScr":"37","ScrLPS":"16.99","PktsIn":"2","PktOut":"1","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0.01","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"24","Uptime":"01:36:38.4254190","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"217","Mesh Objects":"293","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"0","ProcMem":"181,164"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"55","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"0","AtvPrm":"0","AtvScr":"0","ScrLPS":"0","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.19","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"11","Uptime":"00:37:27.4469320","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"0","Mesh Objects":"0","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"0","ProcMem":"115,048"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"55","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"4214","AtvPrm":"0","AtvScr":"50","ScrLPS":"0","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0.01","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"108","Uptime":"00:17:48.0557620","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"4093","Mesh Objects":"121","XEngine Thread Count":"0","Util Thread Count":"5","System Thread Count":"0","ProcMem":"344,652"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"55","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"4160","AtvPrm":"0","AtvScr":"0","ScrLPS":"0","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"40","Uptime":"01:37:03.0917460","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"1617","Mesh Objects":"2543","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"0","ProcMem":"225,808"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"45.5","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"1531","AtvPrm":"0","AtvScr":"18","ScrLPS":"0","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0","OthrFt":"0.04","AgntFt":"0","ImgsFt":"0","Memory":"85","Uptime":"2.18:50:06.6707772","Version":"OpenSim 0.9.2.0.04 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"1413","Mesh Objects":"118","XEngine Thread Count":"0","Util Thread Count":"4","System Thread Count":"3","ProcMem":"136,644"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"55","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"4160","AtvPrm":"0","AtvScr":"0","ScrLPS":"0","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"41","Uptime":"00:37:33.1846060","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"1617","Mesh Objects":"2543","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"0","ProcMem":"229,888"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55.2","PhyFPS":"54","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"6124","AtvPrm":"0","AtvScr":"370","ScrLPS":"1055.39","PktsIn":"11","PktOut":"187","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.12","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"304","Uptime":"09:42:04.1113902","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"2014","Mesh Objects":"4110","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"1","ProcMem":"872,408"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"53.8","AgntUp":"0","RootAg":"2","ChldAg":"0","Prims":"9533","AtvPrm":"0","AtvScr":"344","ScrLPS":"143.6","PktsIn":"15","PktOut":"205","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0.01","OthrFt":"0.01","AgntFt":"0","ImgsFt":"0","Memory":"183","Uptime":"09:34:54.2774399","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"7261","Mesh Objects":"2272","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"1","ProcMem":"502,532"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"54","AgntUp":"222.11","RootAg":"5","ChldAg":"0","Prims":"60159","AtvPrm":"0","AtvScr":"2959","ScrLPS":"1038.3","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.19","NetFt":"0","PhysFt":"0.01","OthrFt":"0.03","AgntFt":"0.02","ImgsFt":"0","Memory":"1757","Uptime":"09:42:43.7007040","Version":"OpenSim 0.9.2.0.02 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"20819","Mesh Objects":"39340","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"1","ProcMem":"3,293,856"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"53.9","PhyFPS":"49.7","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"21568","AtvPrm":"0","AtvScr":"1226","ScrLPS":"290.71","PktsIn":"46","PktOut":"41","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.55","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"1138","Uptime":"14:22:36.3878739","Version":"OpenSim 0.9.2.0.04 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"5440","Mesh Objects":"16128","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"3","ProcMem":"1,914,624"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55.3","PhyFPS":"52.5","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"7079","AtvPrm":"0","AtvScr":"608","ScrLPS":"23.32","PktsIn":"18","PktOut":"17","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.1","NetFt":"0","PhysFt":"0","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"219","Uptime":"2.18:28:44.6906436","Version":"OpenSim 0.9.2.0.04 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"4369","Mesh Objects":"2710","XEngine Thread Count":"0","Util Thread Count":"3","System Thread Count":"1","ProcMem":"391,580"}
|
|
@ -0,0 +1 @@
|
||||||
|
{"Dilatn":"1","SimFPS":"55","PhyFPS":"55","AgntUp":"0","RootAg":"0","ChldAg":"0","Prims":"4214","AtvPrm":"0","AtvScr":"50","ScrLPS":"0","PktsIn":"0","PktOut":"0","PendDl":"0","PendUl":"0","UnackB":"0","TotlFt":"18.18","NetFt":"0","PhysFt":"0.01","OthrFt":"0","AgntFt":"0","ImgsFt":"0","Memory":"104","Uptime":"00:17:45.6773380","Version":"OpenSim 0.9.2.0.06 Yeti Dev ","FrameDilatn":"1","Logging in Users":"0","GeoPrims":"4093","Mesh Objects":"121","XEngine Thread Count":"0","Util Thread Count":"5","System Thread Count":"0","ProcMem":"344,652"}
|
After Width: | Height: | Size: 2.9 MiB |
After Width: | Height: | Size: 3.1 MiB |
After Width: | Height: | Size: 3.4 MiB |
After Width: | Height: | Size: 2.4 MiB |
After Width: | Height: | Size: 2.8 MiB |
After Width: | Height: | Size: 2.7 MiB |
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
date_default_timezone_set("Europe/Berlin");
|
||||||
|
header('Strict-Transport-Security: max-age=657000');
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
include_once 'classen/MAIL/PHPMailer.php';
|
||||||
|
include_once 'classen/MAIL/SMTP.php';
|
||||||
|
|
||||||
|
include_once("classen/utils.php");
|
||||||
|
include_once("classen/HTML.php");
|
||||||
|
include_once("classen/GoogleAuthenticator.php");
|
||||||
|
include_once("classen/OpenSim.php");
|
||||||
|
|
||||||
|
$RUNTIME = array();
|
||||||
|
$RUNTIME['OPENSIM'] = new OpenSim();
|
||||||
|
|
||||||
|
include_once("config.php");
|
||||||
|
|
||||||
|
if(isset($_REQUEST['api']))
|
||||||
|
{
|
||||||
|
if(file_exists("./api/".$_REQUEST['api'].".php")){
|
||||||
|
if($_REQUEST['api'] == str_replace("/"," ",$_REQUEST['api']) and $_REQUEST['api'] == str_replace("\\"," ",$_REQUEST['api']) and $_REQUEST['api'] == str_replace(".."," ",$_REQUEST['api'])){
|
||||||
|
include "./api/".$_REQUEST['api'].".php";
|
||||||
|
}else{
|
||||||
|
die("ERROR; ENDPOINT NOT EXIST");
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
die("ERROR; ENDPOINT NOT EXIST");
|
||||||
|
}
|
||||||
|
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($_REQUEST['logout']))
|
||||||
|
if($_REQUEST['logout'] == '1')
|
||||||
|
$_SESSION = array();
|
||||||
|
|
||||||
|
if(isset($_SESSION['LOGIN']))
|
||||||
|
if($_SESSION['LOGIN'] == 'true')
|
||||||
|
{
|
||||||
|
if(!isset($_REQUEST['page']))
|
||||||
|
$_REQUEST['page'] = 'dashboard';
|
||||||
|
|
||||||
|
if(file_exists("./pages/".$_REQUEST['page'].".php")){
|
||||||
|
if($_REQUEST['page'] == str_replace("/"," ",$_REQUEST['page']) and $_REQUEST['page'] == str_replace("\\"," ",$_REQUEST['page']) and $_REQUEST['page'] == str_replace(".."," ",$_REQUEST['page'])){
|
||||||
|
include "./pages/".$_REQUEST['page'].".php";
|
||||||
|
}else{
|
||||||
|
include "./pages/error.php";
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
include "./pages/error.php";
|
||||||
|
}
|
||||||
|
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(@$_REQUEST['page'] == "register")
|
||||||
|
{
|
||||||
|
include "./pages/register.php";
|
||||||
|
}else{
|
||||||
|
include "./pages/login.php";
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
|
@ -0,0 +1 @@
|
||||||
|
Deny from all
|
|
@ -0,0 +1,33 @@
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-3 col-sm-6 mb-3">
|
||||||
|
<div class="card text-white bg-primary o-hidden h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="card-body-icon">
|
||||||
|
<i class="fas fa-fw fa-door-closed"></i>
|
||||||
|
</div>
|
||||||
|
<div class="mr-5">%%GLOBAL-USER-COUNT%%</div>
|
||||||
|
</div>
|
||||||
|
<span class="card-footer text-white clearfix small z-1 float-left">Benutzer / Online</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xl-3 col-sm-6 mb-3">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-xl-3 col-sm-6 mb-3">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-xl-3 col-sm-6 mb-3">
|
||||||
|
<div class="card text-white bg-primary o-hidden h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="card-body-icon">
|
||||||
|
<i class="fas fa-fw fa-thermometer-half"></i>
|
||||||
|
</div>
|
||||||
|
<div class="mr-5">%%GLOBAL-REGION-COUNT%%</div>
|
||||||
|
</div>
|
||||||
|
<span class="card-footer text-white clearfix small z-1 float-left">Regionen</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1 @@
|
||||||
|
%%REGION-LIST%%
|
|
@ -0,0 +1 @@
|
||||||
|
%%ONLINE-LIST%%
|
|
@ -0,0 +1,163 @@
|
||||||
|
|
||||||
|
|
||||||
|
<div style="width: 400px; margin: auto; left: 50%;">
|
||||||
|
<form action="index.php?page=profile" method="post">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<label for="inputVorname">Vorname</label>
|
||||||
|
<input type="text" class="form-control" id="inputVorname" name="formInputFeldVorname" placeholder="%%firstname%%">
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<label for="inputNachname">Nachname</label>
|
||||||
|
<input type="text" class="form-control" id="inputNachname" name="formInputFeldNachname" placeholder="%%lastname%%">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" style="margin-top: 15px;">
|
||||||
|
<div class="col">
|
||||||
|
<label for="inputVorname">E-Mail</label>
|
||||||
|
<input type="text" class="form-control" id="inputEmail" name="formInputFeldEMail" placeholder="%%email%%">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" style="margin-top: 15px;">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" name="formInputFeldOfflineIM" type="checkbox" id="gridCheck"%%offlineIMSTATE%%>
|
||||||
|
<label class="form-check-label" for="gridCheck"> Offline IM</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" style="margin-top: 15px;">
|
||||||
|
<div class="col">
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" style="margin-top: 15px;">
|
||||||
|
<div class="col">
|
||||||
|
<label for="dropdownPartner">Partner</label>
|
||||||
|
<input type="text" class="form-control" name="formInputFeldPartnerName" id="inputpartner" placeholder="%%partner%%">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" style="margin-top: 15px;">
|
||||||
|
<div class="col">
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" style="margin-top: 15px;">
|
||||||
|
<div class="col">
|
||||||
|
<button type="submit" name="saveProfileData" class="btn btn-primary btn-lg">Speichern</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var countries = [%%listAllResidentsAsJSArray%%];
|
||||||
|
|
||||||
|
function autocomplete(inp, arr) {
|
||||||
|
/*the autocomplete function takes two arguments,
|
||||||
|
the text field element and an array of possible autocompleted values:*/
|
||||||
|
var currentFocus;
|
||||||
|
/*execute a function when someone writes in the text field:*/
|
||||||
|
inp.addEventListener("input", function(e) {
|
||||||
|
var a, b, i, val = this.value;
|
||||||
|
/*close any already open lists of autocompleted values*/
|
||||||
|
closeAllLists();
|
||||||
|
if (!val) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
currentFocus = -1;
|
||||||
|
/*create a DIV element that will contain the items (values):*/
|
||||||
|
a = document.createElement("DIV");
|
||||||
|
a.setAttribute("id", this.id + "autocomplete-list");
|
||||||
|
a.setAttribute("class", "autocomplete-items");
|
||||||
|
/*append the DIV element as a child of the autocomplete container:*/
|
||||||
|
this.parentNode.appendChild(a);
|
||||||
|
/*for each item in the array...*/
|
||||||
|
for (i = 0; i < arr.length; i++) {
|
||||||
|
/*check if the item starts with the same letters as the text field value:*/
|
||||||
|
if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
|
||||||
|
/*create a DIV element for each matching element:*/
|
||||||
|
b = document.createElement("DIV");
|
||||||
|
/*make the matching letters bold:*/
|
||||||
|
b.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
|
||||||
|
b.innerHTML += arr[i].substr(val.length);
|
||||||
|
/*insert a input field that will hold the current array item's value:*/
|
||||||
|
b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
|
||||||
|
/*execute a function when someone clicks on the item value (DIV element):*/
|
||||||
|
b.addEventListener("click", function(e) {
|
||||||
|
/*insert the value for the autocomplete text field:*/
|
||||||
|
inp.value = this.getElementsByTagName("input")[0].value;
|
||||||
|
/*close the list of autocompleted values,
|
||||||
|
(or any other open lists of autocompleted values:*/
|
||||||
|
closeAllLists();
|
||||||
|
});
|
||||||
|
a.appendChild(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/*execute a function presses a key on the keyboard:*/
|
||||||
|
inp.addEventListener("keydown", function(e) {
|
||||||
|
var x = document.getElementById(this.id + "autocomplete-list");
|
||||||
|
if (x) x = x.getElementsByTagName("div");
|
||||||
|
if (e.keyCode == 40) {
|
||||||
|
/*If the arrow DOWN key is pressed,
|
||||||
|
increase the currentFocus variable:*/
|
||||||
|
currentFocus++;
|
||||||
|
/*and and make the current item more visible:*/
|
||||||
|
addActive(x);
|
||||||
|
} else if (e.keyCode == 38) { //up
|
||||||
|
/*If the arrow UP key is pressed,
|
||||||
|
decrease the currentFocus variable:*/
|
||||||
|
currentFocus--;
|
||||||
|
/*and and make the current item more visible:*/
|
||||||
|
addActive(x);
|
||||||
|
} else if (e.keyCode == 13) {
|
||||||
|
/*If the ENTER key is pressed, prevent the form from being submitted,*/
|
||||||
|
e.preventDefault();
|
||||||
|
if (currentFocus > -1) {
|
||||||
|
/*and simulate a click on the "active" item:*/
|
||||||
|
if (x) x[currentFocus].click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function addActive(x) {
|
||||||
|
/*a function to classify an item as "active":*/
|
||||||
|
if (!x) return false;
|
||||||
|
/*start by removing the "active" class on all items:*/
|
||||||
|
removeActive(x);
|
||||||
|
if (currentFocus >= x.length) currentFocus = 0;
|
||||||
|
if (currentFocus < 0) currentFocus = (x.length - 1);
|
||||||
|
/*add class "autocomplete-active":*/
|
||||||
|
x[currentFocus].classList.add("autocomplete-active");
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeActive(x) {
|
||||||
|
/*a function to remove the "active" class from all autocomplete items:*/
|
||||||
|
for (var i = 0; i < x.length; i++) {
|
||||||
|
x[i].classList.remove("autocomplete-active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeAllLists(elmnt) {
|
||||||
|
/*close all autocomplete lists in the document,
|
||||||
|
except the one passed as an argument:*/
|
||||||
|
var x = document.getElementsByClassName("autocomplete-items");
|
||||||
|
for (var i = 0; i < x.length; i++) {
|
||||||
|
if (elmnt != x[i] && elmnt != inp) {
|
||||||
|
x[i].parentNode.removeChild(x[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*execute a function when someone clicks in the document:*/
|
||||||
|
document.addEventListener("click", function(e) {
|
||||||
|
closeAllLists(e.target);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
autocomplete(document.getElementById("inputpartner"), countries);
|
||||||
|
</script>
|
|
@ -0,0 +1,202 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: rgb(0, 0, 0);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
font-family: 'Arial';
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InfoBox {
|
||||||
|
width: 300px;
|
||||||
|
height: auto;
|
||||||
|
background: rgba(0, 0, 0, 0.85);
|
||||||
|
color: rgb(220, 220, 220);
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InfoBox a {
|
||||||
|
color: rgb(220, 220, 220);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InfoBox a:hover {
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InfoBoxTitle {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
padding: 0;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
border: 0px dashed rgb(128, 128, 128);
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
color: rgb(220, 220, 220);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GridLogo {
|
||||||
|
position: absolute;
|
||||||
|
top: 50px;
|
||||||
|
left: 50px;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ScrollBar::-webkit-scrollbar {
|
||||||
|
width: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ScrollBar::-webkit-scrollbar-track {
|
||||||
|
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ScrollBar::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(38, 38, 38, 0.9);
|
||||||
|
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<img src='' style='border: 0; display: block; opacity; 0; position: absolute;' id='Image1' />
|
||||||
|
<img src='' style='border: 0; display: block; opacity: 0; position: absolute;' id='Image2' />
|
||||||
|
<script type='text/javascript'>
|
||||||
|
var Images = %%JSONIMAGEARRAY%%;
|
||||||
|
var MakeAnimation = true;
|
||||||
|
var CurrentIndex = 2;
|
||||||
|
var CurrentImage = -1;
|
||||||
|
var ImageTimeout = 0;
|
||||||
|
var CurrentImageTranslation = -1;
|
||||||
|
var ImagePositions = [{'x': -50, 'y': -50, 'px': 1, 'py': 1},
|
||||||
|
{'x': -50, 'y': -50, 'px': 1, 'py': 1}];
|
||||||
|
document.getElementById('Image1').onload = function() {
|
||||||
|
if (MakeAnimation)
|
||||||
|
{
|
||||||
|
this.style.width = (window.innerWidth + 100) + 'px';
|
||||||
|
if (this.offsetHeight < window.innerHeight + 100)
|
||||||
|
{
|
||||||
|
this.style.width = null;
|
||||||
|
this.style.height = (window.innerHeight + 100) + 'px';
|
||||||
|
}
|
||||||
|
ImagePositions[0].x = -50;
|
||||||
|
ImagePositions[0].y = -50;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.style.width = window.innerWidth + 'px';
|
||||||
|
if (this.offsetHeight < window.innerHeight)
|
||||||
|
{
|
||||||
|
this.style.width = null;
|
||||||
|
this.style.height = window.innerHeight + 'px';
|
||||||
|
}
|
||||||
|
ImagePositions[0].x = 0;
|
||||||
|
ImagePositions[0].y = 0;
|
||||||
|
}
|
||||||
|
CurrentImageTranslation = 0;
|
||||||
|
};
|
||||||
|
document.getElementById('Image2').onload = function() {
|
||||||
|
if (MakeAnimation)
|
||||||
|
{
|
||||||
|
this.style.width = (window.innerWidth + 100) + 'px';
|
||||||
|
if (this.offsetHeight < window.innerHeight + 100)
|
||||||
|
{
|
||||||
|
this.style.width = null;
|
||||||
|
this.style.height = (window.innerHeight + 100) + 'px';
|
||||||
|
}
|
||||||
|
ImagePositions[1].x = -50;
|
||||||
|
ImagePositions[1].y = -50;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.style.width = window.innerWidth + 'px';
|
||||||
|
if (this.offsetHeight < window.innerHeight)
|
||||||
|
{
|
||||||
|
this.style.width = null;
|
||||||
|
this.style.height = window.innerHeight + 'px';
|
||||||
|
}
|
||||||
|
ImagePositions[0].x = 0;
|
||||||
|
ImagePositions[0].y = 0;
|
||||||
|
}
|
||||||
|
CurrentImageTranslation = 0;
|
||||||
|
};
|
||||||
|
window.setInterval(function() {
|
||||||
|
ImageTimeout = ImageTimeout - 1;
|
||||||
|
if (ImageTimeout <= 0)
|
||||||
|
{
|
||||||
|
ImageTimeout = 10;
|
||||||
|
CurrentImage = CurrentImage + 1;
|
||||||
|
if (CurrentImage >= Images.length)
|
||||||
|
{CurrentImage = 0;}
|
||||||
|
if (CurrentIndex == 1)
|
||||||
|
{CurrentIndex = 2;}
|
||||||
|
else
|
||||||
|
{CurrentIndex = 1;}
|
||||||
|
document.getElementById('Image' + CurrentIndex).style.width = null;
|
||||||
|
document.getElementById('Image' + CurrentIndex).style.height = null;
|
||||||
|
document.getElementById('Image' + CurrentIndex).src = Images[CurrentImage];
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
window.setInterval(function() {
|
||||||
|
if (MakeAnimation)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 2; ++i)
|
||||||
|
{
|
||||||
|
ImagePositions[i].x = ImagePositions[i].x + ImagePositions[i].px;
|
||||||
|
ImagePositions[i].y = ImagePositions[i].y + ImagePositions[i].py;
|
||||||
|
var OffWidth = document.getElementById('Image' + (i + 1)).offsetWidth;
|
||||||
|
var OffHeight = document.getElementById('Image' + (i + 1)).offsetHeight;
|
||||||
|
if (ImagePositions[i].x >= 0 || ImagePositions[i].x + OffWidth <= window.innerWidth)
|
||||||
|
{ImagePositions[i].px = -ImagePositions[i].px;}
|
||||||
|
if (ImagePositions[i].y >= 0 || ImagePositions[i].y + OffHeight <= window.innerHeight)
|
||||||
|
{ImagePositions[i].py = -ImagePositions[i].py;}
|
||||||
|
document.getElementById('Image' + (i + 1)).style.left = ImagePositions[i].x + 'px';
|
||||||
|
document.getElementById('Image' + (i + 1)).style.top = ImagePositions[i].y + 'px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CurrentImageTranslation > -1)
|
||||||
|
{
|
||||||
|
var DoReset = false;
|
||||||
|
CurrentImageTranslation = CurrentImageTranslation + 0.025;
|
||||||
|
if (CurrentImageTranslation >= 1.0)
|
||||||
|
{
|
||||||
|
CurrentImageTranslation = 1.0;
|
||||||
|
DoReset = true;
|
||||||
|
}
|
||||||
|
if (CurrentIndex == 1)
|
||||||
|
{
|
||||||
|
document.getElementById('Image1').style.opacity = CurrentImageTranslation;
|
||||||
|
document.getElementById('Image2').style.opacity = 1 - CurrentImageTranslation;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
document.getElementById('Image2').style.opacity = CurrentImageTranslation;
|
||||||
|
document.getElementById('Image1').style.opacity = 1 - CurrentImageTranslation;
|
||||||
|
}
|
||||||
|
if (DoReset)
|
||||||
|
{CurrentImageTranslation = -1;}
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
</script>
|
||||||
|
<div class='InfoBox' style='position: absolute; right: 50px; top: 50px;'>
|
||||||
|
<div class='InfoBoxTitle'>%%GRIDNAME%%</div>
|
||||||
|
Willkommen<br />
|
||||||
|
Bitte melde dich an, um %%GRIDNAME%% zu betreten.<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
%%SHOWNEWS%%
|
||||||
|
</div>
|
||||||
|
<div class='InfoBox' style='position: absolute; left: 50px; bottom: 50px;'>
|
||||||
|
<div class='InfoBoxTitle'>
|
||||||
|
Status: <span style='color: rgb(0, 255, 0);'>Online</span>
|
||||||
|
</div>
|
||||||
|
%%SHOWSTATS%%
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
$HTML = new HTML();
|
||||||
|
$HTML->setHTMLTitle("Dashboard");
|
||||||
|
$HTML->importHTML("style/default/dashboard.html");
|
||||||
|
|
||||||
|
$HTML->importSeitenInhalt("pages/HTML/dashboard.html");
|
||||||
|
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%GLOBAL-USER-COUNT%%", $RUNTIME['OPENSIM']->getUserCount());
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%GLOBAL-REGION-COUNT%%", $RUNTIME['OPENSIM']->getRegionCount());
|
||||||
|
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%USERNAME%%", $_SESSION['DISPLAYNAME']);
|
||||||
|
|
||||||
|
$HTML->build();
|
||||||
|
echo $HTML->ausgabe();
|
||||||
|
?>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
$HTML = new HTML();
|
||||||
|
$HTML->setHTMLTitle("Seite nicht gefunden");
|
||||||
|
$HTML->importHTML("style/default/dashboard.html");
|
||||||
|
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%USERNAME%%", $_SESSION['DISPLAYNAME']);
|
||||||
|
|
||||||
|
$HTML->build();
|
||||||
|
header("HTTP/1.0 404 Not Found");
|
||||||
|
echo $HTML->ausgabe();
|
||||||
|
?>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
$HTML = new HTML();
|
||||||
|
$HTML->setHTMLTitle("Gruppen");
|
||||||
|
$HTML->importHTML("style/default/dashboard.html");
|
||||||
|
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%USERNAME%%", $_SESSION['DISPLAYNAME']);
|
||||||
|
$HTML->importSeitenInhalt("pages/HTML/deine-regionen.html");
|
||||||
|
|
||||||
|
$table = '<table class="table"><thead><tr><th scope="col">Name</th><th scope="col">Gründer</th><th scope="col">Aktionen</th></thead><tbody>%%ENTRY%%</tbody></table>';
|
||||||
|
|
||||||
|
$statementMembership = $RUNTIME['PDO']->prepare("SELECT * FROM os_groups_membership WHERE PrincipalID = ? ORDER BY GroupID ASC");
|
||||||
|
$statementMembership->execute(array($_SESSION['UUID']));
|
||||||
|
|
||||||
|
while($rowMembership = $statementMembership->fetch())
|
||||||
|
{
|
||||||
|
$statementGroups = $RUNTIME['PDO']->prepare("SELECT * FROM os_groups_groups WHERE GroupID = ? LIMIT 1");
|
||||||
|
$statementGroups->execute(array($rowMembership['GroupID']));
|
||||||
|
|
||||||
|
while($rowGroups = $statementGroups->fetch())
|
||||||
|
{
|
||||||
|
$entry = '<tr><td>'.$rowGroups['Name'].'</td><td>'.$RUNTIME['OPENSIM']->getUserName($rowGroups['FounderID']).'</td><td>VERLASSEN</td></tr>';
|
||||||
|
$table = str_replace("%%ENTRY%%", $entry."%%ENTRY%%", $table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = str_replace("%%ENTRY%%", "", $table);
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%REGION-LIST%%", $table);
|
||||||
|
|
||||||
|
$HTML->build();
|
||||||
|
echo $HTML->ausgabe();
|
||||||
|
?>
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
$HTML = new HTML();
|
||||||
|
$HTML->setHTMLTitle("Login");
|
||||||
|
$HTML->importHTML("style/login/login.html");
|
||||||
|
|
||||||
|
if(isset($_POST['login']))
|
||||||
|
{
|
||||||
|
if(!isset($_POST['username']) || !isset($_POST['password']))
|
||||||
|
{
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%LOGINMESSAGE%%", "Bitte gebe Benutzername und Passwort an.");
|
||||||
|
}else{
|
||||||
|
$statementUser = $RUNTIME['PDO']->prepare("SELECT * FROM UserAccounts WHERE FirstName = ? AND LastName = ? LIMIT 1");
|
||||||
|
$statementUser->execute(explode(" ", trim($_POST['username'])));
|
||||||
|
|
||||||
|
$RUNTIME['MESSAGE']['LOGINERROR'] = "Benutzername nicht gefunden!";
|
||||||
|
|
||||||
|
while($rowUser = $statementUser->fetch())
|
||||||
|
{
|
||||||
|
$statementAuth = $RUNTIME['PDO']->prepare("SELECT * FROM auth WHERE UUID = ? LIMIT 1");
|
||||||
|
$statementAuth->execute(array($rowUser['PrincipalID']));
|
||||||
|
|
||||||
|
$RUNTIME['DEBUG']['LOGIN']['UUID'] = $rowUser['PrincipalID'];
|
||||||
|
|
||||||
|
while($rowAuth = $statementAuth->fetch())
|
||||||
|
{
|
||||||
|
if(md5(md5($_POST['password']).":".$rowAuth['passwordSalt']) == $rowAuth['passwordHash'])
|
||||||
|
{
|
||||||
|
$_SESSION['USERNAME'] = trim($_POST['username']);
|
||||||
|
$_SESSION['FIRSTNAME'] = trim($rowUser['FirstName']);
|
||||||
|
$_SESSION['LASTNAME'] = trim($rowUser['LastName']);
|
||||||
|
$_SESSION['EMAIL'] = trim($rowUser['Email']);
|
||||||
|
$_SESSION['UUID'] = $rowUser['PrincipalID'];
|
||||||
|
$_SESSION['LEVEL'] = $rowUser['UserLevel'];
|
||||||
|
$_SESSION['DISPLAYNAME'] = strtoupper(trim($_POST['username']));
|
||||||
|
$_SESSION['LOGIN'] = 'true';
|
||||||
|
include "./pages/".@$_REQUEST['page'].".php";
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$RUNTIME['MESSAGE']['LOGINERROR'] = "Passwort falsch!";
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%LOGINMESSAGE%%", $RUNTIME['MESSAGE']['LOGINERROR']);
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%LASTUSERNAME%%", $_POST['username']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(file_exists("./pages/".@$_REQUEST['page'].".php"))
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%PAGENAME%%", @$_REQUEST['page']);
|
||||||
|
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%LOGINMESSAGE%%", "");
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%LASTUSERNAME%%", "");
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%PAGENAME%%", "dashboard");
|
||||||
|
|
||||||
|
$HTML->build();
|
||||||
|
echo $HTML->ausgabe();
|
||||||
|
?>
|
|
@ -0,0 +1,139 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if(isset($_REQUEST['formInputFeldVorname']) || @$_REQUEST['formInputFeldVorname'] != "")
|
||||||
|
{
|
||||||
|
$NewFirstName = trim($_REQUEST['formInputFeldVorname']);
|
||||||
|
|
||||||
|
if($NewFirstName != "")
|
||||||
|
{
|
||||||
|
if($_SESSION['FIRSTNAME'] != $NewFirstName)
|
||||||
|
{
|
||||||
|
$statement = $RUNTIME['PDO']->prepare('UPDATE UserAccounts SET FirstName = :FirstName WHERE PrincipalID = :PrincipalID');
|
||||||
|
$statement->execute(['FirstName' => $NewFirstName, 'PrincipalID' => $_SESSION['UUID']]);
|
||||||
|
$_SESSION['FIRSTNAME'] = $NewFirstName;
|
||||||
|
$_SESSION['USERNAME'] = $_SESSION['FIRSTNAME']." ".$_SESSION['LASTNAME'];
|
||||||
|
$_SESSION['DISPLAYNAME'] = strtoupper($_SESSION['USERNAME']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($_REQUEST['formInputFeldNachname']) || @$_REQUEST['formInputFeldNachname'] != "")
|
||||||
|
{
|
||||||
|
$NewLastName = trim($_REQUEST['formInputFeldNachname']);
|
||||||
|
|
||||||
|
if($NewLastName != "")
|
||||||
|
{
|
||||||
|
if($_SESSION['LASTNAME'] != $NewLastName)
|
||||||
|
{
|
||||||
|
$statement = $RUNTIME['PDO']->prepare('UPDATE UserAccounts SET LastName = :LastName WHERE PrincipalID = :PrincipalID');
|
||||||
|
$statement->execute(['LastName' => $NewLastName, 'PrincipalID' => $_SESSION['UUID']]);
|
||||||
|
$_SESSION['LASTNAME'] = $NewLastName;
|
||||||
|
$_SESSION['USERNAME'] = $_SESSION['FIRSTNAME']." ".$_SESSION['LASTNAME'];
|
||||||
|
$_SESSION['DISPLAYNAME'] = strtoupper($_SESSION['USERNAME']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($_REQUEST['formInputFeldEMail']) || @$_REQUEST['formInputFeldEMail'] != "")
|
||||||
|
{
|
||||||
|
$NewEMail = trim($_REQUEST['formInputFeldEMail']);
|
||||||
|
|
||||||
|
if($NewEMail != "")
|
||||||
|
{
|
||||||
|
if($_SESSION['EMAIL'] != $NewEMail)
|
||||||
|
{
|
||||||
|
$statement = $RUNTIME['PDO']->prepare('UPDATE UserAccounts SET Email = :Email WHERE PrincipalID = :PrincipalID');
|
||||||
|
$statement->execute(['Email' => $NewEMail, 'PrincipalID' => $_SESSION['UUID']]);
|
||||||
|
|
||||||
|
$statement = $RUNTIME['PDO']->prepare('UPDATE usersettings SET email = :Email WHERE useruuid = :PrincipalID');
|
||||||
|
$statement->execute(['Email' => $NewEMail, 'PrincipalID' => $_SESSION['UUID']]);
|
||||||
|
|
||||||
|
$_SESSION['EMAIL'] = $NewEMail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($_REQUEST['formInputFeldOfflineIM']) || @$_REQUEST['formInputFeldOfflineIM'] != "")
|
||||||
|
{
|
||||||
|
$NewOfflineIM = trim($_REQUEST['formInputFeldOfflineIM']);
|
||||||
|
|
||||||
|
if($NewOfflineIM != "")
|
||||||
|
{
|
||||||
|
if($NewOfflineIM == "on" || $NewOfflineIM == "true")
|
||||||
|
{
|
||||||
|
$statement = $RUNTIME['PDO']->prepare('UPDATE usersettings SET imviaemail = :IMState WHERE useruuid = :PrincipalID');
|
||||||
|
$statement->execute(['IMState' => 'true', 'PrincipalID' => $_SESSION['UUID']]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(!isset($_REQUEST['formInputFeldOfflineIM']) && isset($_REQUEST['saveProfileData'])){
|
||||||
|
$statement = $RUNTIME['PDO']->prepare('UPDATE usersettings SET imviaemail = :IMState WHERE useruuid = :PrincipalID');
|
||||||
|
$statement->execute(['IMState' => 'false', 'PrincipalID' => $_SESSION['UUID']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($_REQUEST['formInputFeldPartnerName']) || @$_REQUEST['formInputFeldPartnerName'] != "")
|
||||||
|
{
|
||||||
|
$NewPartner = trim($_REQUEST['formInputFeldPartnerName']);
|
||||||
|
$CurrentPartner = $RUNTIME['OPENSIM']->getPartner($_SESSION['UUID']);
|
||||||
|
|
||||||
|
if($CurrentPartner != "")$CurrentPartner = $RUNTIME['OPENSIM']->getUserName($CurrentPartner);
|
||||||
|
|
||||||
|
if($NewPartner != "")
|
||||||
|
{
|
||||||
|
if($CurrentPartner != $NewPartner)
|
||||||
|
{
|
||||||
|
$newPartnerUUID = $RUNTIME['OPENSIM']->getUserUUID($NewPartner);
|
||||||
|
|
||||||
|
if($newPartnerUUID != null)
|
||||||
|
{
|
||||||
|
$statement = $RUNTIME['PDO']->prepare('UPDATE userprofile SET profilePartner = :profilePartner WHERE useruuid = :PrincipalID');
|
||||||
|
$statement->execute(['profilePartner' => $newPartnerUUID, 'PrincipalID' => $_SESSION['UUID']]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$statement = $RUNTIME['PDO']->prepare('UPDATE userprofile SET profilePartner = :profilePartner WHERE useruuid = :PrincipalID');
|
||||||
|
$statement->execute(['profilePartner' => '00000000-0000-0000-0000-000000000000', 'PrincipalID' => $_SESSION['UUID']]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$HTML = new HTML();
|
||||||
|
$HTML->setHTMLTitle("Dein Profile");
|
||||||
|
$HTML->importHTML("style/default/dashboard.html");
|
||||||
|
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%USERNAME%%", $_SESSION['DISPLAYNAME']);
|
||||||
|
$HTML->importSeitenInhalt("pages/HTML/profile.html");
|
||||||
|
|
||||||
|
$statementLocalUsers = $RUNTIME['PDO']->prepare("SELECT * FROM UserAccounts ORDER BY PrincipalID ASC");
|
||||||
|
$statementLocalUsers->execute();
|
||||||
|
|
||||||
|
$allUsers = "";
|
||||||
|
while($row = $statementLocalUsers->fetch())
|
||||||
|
{
|
||||||
|
$name = '"'.@$row['FirstName']." ".@$row['LastName'].'"';
|
||||||
|
|
||||||
|
if($allUsers != "")
|
||||||
|
{
|
||||||
|
$allUsers .= ",".$name;
|
||||||
|
}else{
|
||||||
|
$allUsers .= $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$allUsers .= '," "';
|
||||||
|
|
||||||
|
$PartnerUUID = $RUNTIME['OPENSIM']->getPartner($_SESSION['UUID']);
|
||||||
|
$PartnerName = "";
|
||||||
|
|
||||||
|
if($PartnerUUID != null)$PartnerName = $RUNTIME['OPENSIM']->getUserName($PartnerUUID);
|
||||||
|
|
||||||
|
if($RUNTIME['OPENSIM']->allowOfflineIM($_SESSION['UUID']) == "TRUE")$HTML->ReplaceSeitenInhalt("%%offlineIMSTATE%%", ' checked');
|
||||||
|
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%offlineIMSTATE%%", ' ');
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%firstname%%", $_SESSION['FIRSTNAME']);
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%lastname%%", $_SESSION['LASTNAME']);
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%partner%%", $PartnerName);
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%email%%", $RUNTIME['OPENSIM']->getUserMail($_SESSION['UUID']));
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%listAllResidentsAsJSArray%%", $allUsers);
|
||||||
|
|
||||||
|
$HTML->build();
|
||||||
|
echo $HTML->ausgabe();
|
||||||
|
?>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
$HTML = new HTML();
|
||||||
|
$HTML->setHTMLTitle("Deine Regionen");
|
||||||
|
$HTML->importHTML("style/default/dashboard.html");
|
||||||
|
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%USERNAME%%", $_SESSION['DISPLAYNAME']);
|
||||||
|
$HTML->importSeitenInhalt("pages/HTML/deine-regionen.html");
|
||||||
|
|
||||||
|
$table = '<table class="table"><thead><tr><th scope="col">Region Name</th><th scope="col">Eigentümer</th><th scope="col">Position</th><th scope="col">Aktionen</th></thead><tbody>%%ENTRY%%</tbody></table>';
|
||||||
|
|
||||||
|
if(@$_SESSION['LEVEL'] > 100 && @$_REQUEST['SHOWALL'] == "1")
|
||||||
|
{
|
||||||
|
$statement = $RUNTIME['PDO']->prepare("SELECT * FROM regions ORDER BY owner_uuid ASC");
|
||||||
|
$statement->execute(array($_SESSION['UUID']));
|
||||||
|
}else{
|
||||||
|
$statement = $RUNTIME['PDO']->prepare("SELECT * FROM regions WHERE owner_uuid = ? ORDER BY uuid ASC");
|
||||||
|
$statement->execute(array($_SESSION['UUID']));
|
||||||
|
}
|
||||||
|
|
||||||
|
$statement->execute(array($_SESSION['UUID']));
|
||||||
|
|
||||||
|
while($row = $statement->fetch())
|
||||||
|
{
|
||||||
|
$entry = '<tr><td>'.$row['regionName'].'</td><td>'.$RUNTIME['OPENSIM']->getUserName($row['owner_uuid']).'</td><td>'.fillString(($row['locX'] / 256), 4).' / '.fillString(($row['locY'] / 256), 4).'</td><td>TELEPORT | LÖSCHEN</td></tr>';
|
||||||
|
$table = str_replace("%%ENTRY%%", $entry."%%ENTRY%%", $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = str_replace("%%ENTRY%%", "", $table);
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%REGION-LIST%%", $table);
|
||||||
|
|
||||||
|
$HTML->build();
|
||||||
|
echo $HTML->ausgabe();
|
||||||
|
?>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
$HTML = new HTML();
|
||||||
|
$HTML->setHTMLTitle("Online Anzeige");
|
||||||
|
$HTML->importHTML("style/default/dashboard.html");
|
||||||
|
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%USERNAME%%", $_SESSION['DISPLAYNAME']);
|
||||||
|
$HTML->importSeitenInhalt("pages/HTML/online-anzeige.html");
|
||||||
|
|
||||||
|
$table = '<table class="table"><thead><tr><th scope="col">Benutzername</th><th scope="col">Region</th></thead><tbody>%%ENTRY%%</tbody></table>';
|
||||||
|
|
||||||
|
$statement = $RUNTIME['PDO']->prepare("SELECT * FROM Presence ORDER BY RegionID ASC");
|
||||||
|
$statement->execute();
|
||||||
|
|
||||||
|
while($row = $statement->fetch())
|
||||||
|
{
|
||||||
|
if($row['RegionID'] != "00000000-0000-0000-0000-000000000000")
|
||||||
|
{
|
||||||
|
$entry = '<tr><td>'.trim($RUNTIME['OPENSIM']->getUserName($row['UserID'])).'</td><td>'.$RUNTIME['OPENSIM']->getRegionName($row['RegionID']).'</td></tr>';
|
||||||
|
$table = str_replace("%%ENTRY%%", $entry."%%ENTRY%%", $table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = str_replace("%%ENTRY%%", "", $table);
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%ONLINE-LIST%%", $table);
|
||||||
|
|
||||||
|
$HTML->build();
|
||||||
|
echo $HTML->ausgabe();
|
||||||
|
?>
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
if(@$_SESSION['LEVEL'] < 100)
|
||||||
|
{
|
||||||
|
$HTML = new HTML();
|
||||||
|
$HTML->setHTMLTitle("Kein Zugriff");
|
||||||
|
$HTML->importHTML("style/default/dashboard.html");
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%USERNAME%%", $_SESSION['DISPLAYNAME']);
|
||||||
|
|
||||||
|
$HTML->SetSeitenInhalt("Dazu hast du keine Rechte!");
|
||||||
|
$HTML->build();
|
||||||
|
echo $HTML->ausgabe();
|
||||||
|
die();
|
||||||
|
}else{
|
||||||
|
$HTML = new HTML();
|
||||||
|
$HTML->setHTMLTitle("Benutzer");
|
||||||
|
$HTML->importHTML("style/default/dashboard.html");
|
||||||
|
|
||||||
|
$HTML->ReplaceLayoutInhalt("%%USERNAME%%", $_SESSION['DISPLAYNAME']);
|
||||||
|
$HTML->importSeitenInhalt("pages/HTML/deine-regionen.html");
|
||||||
|
|
||||||
|
$table = '<table class="table"><thead><tr><th scope="col">Vorname</th><th scope="col">Nachname</th><th scope="col">Status</th><th scope="col">Aktionen</th></thead><tbody>%%ENTRY%%</tbody></table>';
|
||||||
|
|
||||||
|
$statement = $RUNTIME['PDO']->prepare("SELECT * FROM UserAccounts ORDER BY Created ASC");
|
||||||
|
$statement->execute();
|
||||||
|
|
||||||
|
while($row = $statement->fetch())
|
||||||
|
{
|
||||||
|
$entry = '<tr><td>'.$row['FirstName'].'</td><td>'.$row['LastName'].'</td><td>'.$row['UserLevel'].'</td><td>PASSWORT ÄNDERN | SPERREN | UMBENENNEN</td></tr>';
|
||||||
|
$table = str_replace("%%ENTRY%%", $entry."%%ENTRY%%", $table);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = str_replace("%%ENTRY%%", "", $table);
|
||||||
|
$HTML->ReplaceSeitenInhalt("%%REGION-LIST%%", $table);
|
||||||
|
|
||||||
|
$HTML->build();
|
||||||
|
echo $HTML->ausgabe();
|
||||||
|
}
|
||||||
|
?>
|
After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1,40 @@
|
||||||
|
.autocomplete {
|
||||||
|
/*the container must be positioned relative:*/
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text] {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
input[type=submit] {
|
||||||
|
background-color: DodgerBlue;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.autocomplete-items {
|
||||||
|
position: absolute;
|
||||||
|
border: 1px solid #d4d4d4;
|
||||||
|
border-bottom: none;
|
||||||
|
border-top: none;
|
||||||
|
z-index: 99;
|
||||||
|
/*position the autocomplete items to be the same width as the container:*/
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.autocomplete-items div {
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom: 1px solid #d4d4d4;
|
||||||
|
}
|
||||||
|
.autocomplete-items div:hover {
|
||||||
|
/*when hovering an item:*/
|
||||||
|
background-color: #e9e9e9;
|
||||||
|
}
|
||||||
|
.autocomplete-active {
|
||||||
|
/*when navigating through the items using the arrow keys:*/
|
||||||
|
background-color: DodgerBlue !important;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
|
||||||
|
<title>OpenSim - Kontrollzentrum - %%USERNAME%% - %%EchoTitle%%</title>
|
||||||
|
|
||||||
|
<link href="./style/4Creative.ico" rel="icon">
|
||||||
|
<link href="./style/4Creative.ico" rel="apple-touch-icon">
|
||||||
|
<link href="./style/default/css/autocomplete.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="./style/default/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="./style/default/vendor/datatables/dataTables.bootstrap4.css" rel="stylesheet">
|
||||||
|
<link href="./style/default/css/sb-admin.css" rel="stylesheet"> %%echoHeader%%
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
<nav class="navbar navbar-expand navbar-dark bg-dark static-top">
|
||||||
|
<button class="btn btn-link btn-sm text-white order-1 order-sm-0" id="sidebarToggle" href="#">
|
||||||
|
<i class="fas fa-bars"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="d-none d-md-inline-block form-inline ml-auto mr-0 mr-md-3 my-2 my-md-0"></div>
|
||||||
|
|
||||||
|
<ul class="navbar-nav ml-auto ml-md-0">
|
||||||
|
<li class="nav-item dropdown no-arrow">
|
||||||
|
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">%%USERNAME%% <i class="fas fa-user-circle fa-fw"></i></a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="userDropdown">
|
||||||
|
<a class="dropdown-item" href="?page=profil">Profil</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#logoutModal">Logout</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div id="wrapper">
|
||||||
|
<ul class="sidebar navbar-nav">
|
||||||
|
<li class="nav-item active">
|
||||||
|
<a class="nav-link" href="index.php">
|
||||||
|
<i class="fas fa-fw fa-tachometer-alt"></i>
|
||||||
|
<span>Dashboard</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="index.php?page=downloads">
|
||||||
|
<i class="fas fa-link"></i>
|
||||||
|
<span>Downloads</span></a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="index.php?page=profile">
|
||||||
|
<i class="far fa-address-card"></i>
|
||||||
|
<span>Profil</span></a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="index.php?page=user-online-state">
|
||||||
|
<i class="fas fa-link"></i>
|
||||||
|
<span>Online Anzeige</span></a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="index.php?page=regions">
|
||||||
|
<i class="fas fa-globe-europe"></i>
|
||||||
|
<span>Deine Regionen</span></a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="index.php?page=users">
|
||||||
|
<i class="fas fa-user-plus"></i>
|
||||||
|
<span>Benutzer verwalten</span></a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="index.php?page=groups">
|
||||||
|
<i class="fas fa-users"></i>
|
||||||
|
<span>Deine Gruppen</span></a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
<div id="content-wrapper">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="index.php">Gridverwaltung</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item active">%%EchoTitle%%</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<hr><br>
|
||||||
|
|
||||||
|
%%EchoInhalt%%
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Bist du sicher?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Wähle 'Logout' wenn du dich wirklich abmelden möchtest.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Abbrechen</button>
|
||||||
|
<a class="btn btn-primary" href="index.php?logout=1">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="./style/default/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="./style/default/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
<script src="./style/default/vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||||
|
|
||||||
|
<script src="./style/default/vendor/chart.js/Chart.min.js"></script>
|
||||||
|
<script src="./style/default/vendor/datatables/jquery.dataTables.js"></script>
|
||||||
|
<script src="./style/default/vendor/datatables/dataTables.bootstrap4.js"></script>
|
||||||
|
|
||||||
|
<script src="./style/default/js/sb-admin.min.js"></script>
|
||||||
|
|
||||||
|
<script src="./style/default/js/demo/datatables-demo.js"></script>
|
||||||
|
<script src="./style/default/js/demo/chart-area-demo.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Set new default font family and font color to mimic Bootstrap's default styling
|
||||||
|
Chart.defaults.global.defaultFontFamily = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
|
||||||
|
Chart.defaults.global.defaultFontColor = '#292b2c';
|
||||||
|
|
||||||
|
// Area Chart Example
|
||||||
|
var ctx = document.getElementById("myAreaChart");
|
||||||
|
var myLineChart = new Chart(ctx, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: ["Mar 1", "Mar 2", "Mar 3", "Mar 4", "Mar 5", "Mar 6", "Mar 7", "Mar 8", "Mar 9", "Mar 10", "Mar 11", "Mar 12", "Mar 13"],
|
||||||
|
datasets: [{
|
||||||
|
label: "Sessions",
|
||||||
|
lineTension: 0.3,
|
||||||
|
backgroundColor: "rgba(2,117,216,0.2)",
|
||||||
|
borderColor: "rgba(2,117,216,1)",
|
||||||
|
pointRadius: 5,
|
||||||
|
pointBackgroundColor: "rgba(2,117,216,1)",
|
||||||
|
pointBorderColor: "rgba(255,255,255,0.8)",
|
||||||
|
pointHoverRadius: 5,
|
||||||
|
pointHoverBackgroundColor: "rgba(2,117,216,1)",
|
||||||
|
pointHitRadius: 50,
|
||||||
|
pointBorderWidth: 2,
|
||||||
|
data: [10000, 30162, 26263, 18394, 18287, 28682, 31274, 33259, 25849, 24159, 32651, 31984, 38451],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
time: {
|
||||||
|
unit: 'date'
|
||||||
|
},
|
||||||
|
gridLines: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
maxTicksLimit: 7
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
ticks: {
|
||||||
|
min: 0,
|
||||||
|
max: 40000,
|
||||||
|
maxTicksLimit: 5
|
||||||
|
},
|
||||||
|
gridLines: {
|
||||||
|
color: "rgba(0, 0, 0, .125)",
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,46 @@
|
||||||
|
// Set new default font family and font color to mimic Bootstrap's default styling
|
||||||
|
Chart.defaults.global.defaultFontFamily = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
|
||||||
|
Chart.defaults.global.defaultFontColor = '#292b2c';
|
||||||
|
|
||||||
|
// Bar Chart Example
|
||||||
|
var ctx = document.getElementById("myBarChart");
|
||||||
|
var myLineChart = new Chart(ctx, {
|
||||||
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: ["January", "February", "March", "April", "May", "June"],
|
||||||
|
datasets: [{
|
||||||
|
label: "Revenue",
|
||||||
|
backgroundColor: "rgba(2,117,216,1)",
|
||||||
|
borderColor: "rgba(2,117,216,1)",
|
||||||
|
data: [4215, 5312, 6251, 7841, 9821, 14984],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
time: {
|
||||||
|
unit: 'month'
|
||||||
|
},
|
||||||
|
gridLines: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
maxTicksLimit: 6
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
ticks: {
|
||||||
|
min: 0,
|
||||||
|
max: 15000,
|
||||||
|
maxTicksLimit: 5
|
||||||
|
},
|
||||||
|
gridLines: {
|
||||||
|
display: true
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Set new default font family and font color to mimic Bootstrap's default styling
|
||||||
|
Chart.defaults.global.defaultFontFamily = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
|
||||||
|
Chart.defaults.global.defaultFontColor = '#292b2c';
|
||||||
|
|
||||||
|
// Pie Chart Example
|
||||||
|
var ctx = document.getElementById("myPieChart");
|
||||||
|
var myPieChart = new Chart(ctx, {
|
||||||
|
type: 'pie',
|
||||||
|
data: {
|
||||||
|
labels: ["Blue", "Red", "Yellow", "Green"],
|
||||||
|
datasets: [{
|
||||||
|
data: [12.21, 15.58, 11.25, 8.32],
|
||||||
|
backgroundColor: ['#007bff', '#dc3545', '#ffc107', '#28a745'],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
|
@ -0,0 +1,4 @@
|
||||||
|
// Call the dataTables jQuery plugin
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#dataTable').DataTable();
|
||||||
|
});
|
|
@ -0,0 +1,40 @@
|
||||||
|
(function($) {
|
||||||
|
"use strict"; // Start of use strict
|
||||||
|
|
||||||
|
// Toggle the side navigation
|
||||||
|
$("#sidebarToggle").on('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
$("body").toggleClass("sidebar-toggled");
|
||||||
|
$(".sidebar").toggleClass("toggled");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prevent the content wrapper from scrolling when the fixed side navigation hovered over
|
||||||
|
$('body.fixed-nav .sidebar').on('mousewheel DOMMouseScroll wheel', function(e) {
|
||||||
|
if ($(window).width() > 768) {
|
||||||
|
var e0 = e.originalEvent,
|
||||||
|
delta = e0.wheelDelta || -e0.detail;
|
||||||
|
this.scrollTop += (delta < 0 ? 1 : -1) * 30;
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Scroll to top button appear
|
||||||
|
$(document).on('scroll', function() {
|
||||||
|
var scrollDistance = $(this).scrollTop();
|
||||||
|
if (scrollDistance > 100) {
|
||||||
|
$('.scroll-to-top').fadeIn();
|
||||||
|
} else {
|
||||||
|
$('.scroll-to-top').fadeOut();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Smooth scrolling using jQuery easing
|
||||||
|
$(document).on('click', 'a.scroll-to-top', function(event) {
|
||||||
|
var $anchor = $(this);
|
||||||
|
$('html, body').stop().animate({
|
||||||
|
scrollTop: ($($anchor.attr('href')).offset().top)
|
||||||
|
}, 1000, 'easeInOutExpo');
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
})(jQuery); // End of use strict
|
|
@ -0,0 +1,7 @@
|
||||||
|
/*!
|
||||||
|
* Start Bootstrap - SB Admin v5.1.1 (https://startbootstrap.com/template-overviews/sb-admin)
|
||||||
|
* Copyright 2013-2019 Start Bootstrap
|
||||||
|
* Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap-sb-admin/blob/master/LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
!function(l){"use strict";l("#sidebarToggle").on("click",function(o){o.preventDefault(),l("body").toggleClass("sidebar-toggled"),l(".sidebar").toggleClass("toggled")}),l("body.fixed-nav .sidebar").on("mousewheel DOMMouseScroll wheel",function(o){if(768<l(window).width()){var e=o.originalEvent,t=e.wheelDelta||-e.detail;this.scrollTop+=30*(t<0?1:-1),o.preventDefault()}}),l(document).on("scroll",function(){100<l(this).scrollTop()?l(".scroll-to-top").fadeIn():l(".scroll-to-top").fadeOut()}),l(document).on("click","a.scroll-to-top",function(o){var e=l(this);l("html, body").stop().animate({scrollTop:l(e.attr("href")).offset().top},1e3,"easeInOutExpo"),o.preventDefault()})}(jQuery);
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Styling for custom cards
|
||||||
|
// Custom class for the background icon in card blocks
|
||||||
|
.card-body-icon {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 0;
|
||||||
|
top: -1.25rem;
|
||||||
|
right: -1rem;
|
||||||
|
opacity: 0.4;
|
||||||
|
|
||||||
|
font-size: 5rem;
|
||||||
|
@include rotate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override breakpoints for card columns to work well with sidebar layout
|
||||||
|
.card-columns {
|
||||||
|
@media (min-width: 576px) {
|
||||||
|
column-count: 1;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
column-count: 2;
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
column-count: 2;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
footer.sticky-footer {
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: calc(100% - #{$sidebar-collapsed-width});
|
||||||
|
height: $sticky-footer-height;
|
||||||
|
background-color: $gray-200;
|
||||||
|
.copyright {
|
||||||
|
line-height: 1;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
width: calc(100% - #{$sidebar-base-width});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.sidebar-toggled {
|
||||||
|
footer.sticky-footer {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
footer.sticky-footer {
|
||||||
|
width: calc(100% - #{$sidebar-collapsed-width});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Global styling for this template
|
||||||
|
|
||||||
|
html {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper {
|
||||||
|
display: flex;
|
||||||
|
#content-wrapper {
|
||||||
|
overflow-x: hidden;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 1rem;
|
||||||
|
padding-bottom: $sticky-footer-height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scroll to top button
|
||||||
|
.scroll-to-top {
|
||||||
|
position: fixed;
|
||||||
|
right: 15px;
|
||||||
|
bottom: 15px;
|
||||||
|
display: none;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
text-align: center;
|
||||||
|
color: $white;
|
||||||
|
background: fade-out($gray-800, .5);
|
||||||
|
line-height: 46px;
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background: $gray-800;
|
||||||
|
}
|
||||||
|
i {
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
:root {
|
||||||
|
--input-padding-x: 0.75rem;
|
||||||
|
--input-padding-y: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-login {
|
||||||
|
max-width: 25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-register {
|
||||||
|
max-width: 40rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-group {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-group > input,
|
||||||
|
.form-label-group > label {
|
||||||
|
padding: var(--input-padding-y) var(--input-padding-x);
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-group > label {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 0;
|
||||||
|
/* Override default `<label>` margin */
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #495057;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
transition: all 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-group input::-webkit-input-placeholder {
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-group input:-ms-input-placeholder {
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-group input::-ms-input-placeholder {
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-group input::-moz-placeholder {
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-group input::placeholder {
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-group input:not(:placeholder-shown) {
|
||||||
|
padding-top: calc(var(--input-padding-y) + var(--input-padding-y) * (2 / 3));
|
||||||
|
padding-bottom: calc(var(--input-padding-y) / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-group input:not(:placeholder-shown) ~ label {
|
||||||
|
padding-top: calc(var(--input-padding-y) / 3);
|
||||||
|
padding-bottom: calc(var(--input-padding-y) / 3);
|
||||||
|
font-size: 12px;
|
||||||
|
color: #777;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
@mixin rotate {
|
||||||
|
transform: rotate(15deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin sidebar-icons {
|
||||||
|
.nav-item {
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.nav-link {
|
||||||
|
text-align: center;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
width: $sidebar-collapsed-width;
|
||||||
|
span {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.dropdown-menu {
|
||||||
|
position: absolute !important;
|
||||||
|
transform: none !important;
|
||||||
|
left: calc(#{$sidebar-collapsed-width} + 0.5rem) !important;
|
||||||
|
margin: 0;
|
||||||
|
&.dropup {
|
||||||
|
bottom: 0;
|
||||||
|
top: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.dropdown .dropdown-toggle::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
.navbar-nav {
|
||||||
|
|
||||||
|
.form-inline .input-group {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
&.active {
|
||||||
|
.nav-link {
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.dropdown {
|
||||||
|
.dropdown-toggle {
|
||||||
|
&::after {
|
||||||
|
width: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
float: right;
|
||||||
|
vertical-align: 0;
|
||||||
|
border: 0;
|
||||||
|
font-weight: 900;
|
||||||
|
content: '\f105';
|
||||||
|
font-family: 'Font Awesome 5 Free';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.show {
|
||||||
|
.dropdown-toggle::after {
|
||||||
|
content: '\f107';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.no-arrow {
|
||||||
|
.dropdown-toggle::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.nav-link {
|
||||||
|
&:focus {
|
||||||
|
// remove outline for Safari and Firefox
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.badge {
|
||||||
|
position: absolute;
|
||||||
|
margin-left: 0.75rem;
|
||||||
|
top: 0.3rem;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(min-width: 768px) {
|
||||||
|
|
||||||
|
.form-inline .input-group {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: $sidebar-collapsed-width !important;
|
||||||
|
background-color: $gray-900;
|
||||||
|
min-height: calc(100vh - #{$navbar-base-height});
|
||||||
|
@include sidebar-icons;
|
||||||
|
.nav-item {
|
||||||
|
.nav-link {
|
||||||
|
color: fade-out($white, 0.5);
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
color: fade-out($white, 0.25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.toggled {
|
||||||
|
width: 0 !important;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.sidebar {
|
||||||
|
width: $sidebar-base-width !important;
|
||||||
|
|
||||||
|
.nav-item {
|
||||||
|
.nav-link {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
padding: 1rem;
|
||||||
|
width: $sidebar-base-width;
|
||||||
|
span {
|
||||||
|
font-size: 1rem;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.dropdown-menu {
|
||||||
|
position: static !important;
|
||||||
|
margin: 0 1rem;
|
||||||
|
// Position fix for Firefox
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
&.dropdown .dropdown-toggle::after {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.toggled {
|
||||||
|
overflow: visible;
|
||||||
|
width: $sidebar-collapsed-width !important;
|
||||||
|
@include sidebar-icons;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Additional Text Helper Class
|
||||||
|
.smaller {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper class for the overflow property
|
||||||
|
.o-hidden {
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper classes for z-index
|
||||||
|
.z-0 {
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-1 {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Spacing Variables
|
||||||
|
// Change below variable if the height of the navbar changes
|
||||||
|
$navbar-base-height: 56px;
|
||||||
|
// Change below variable to change the width of the sidenav
|
||||||
|
$sidebar-base-width: 225px;
|
||||||
|
// Change below variable to change the width of the sidenav when collapsed
|
||||||
|
$sidebar-collapsed-width: 90px;
|
||||||
|
// Change below variable to change the height of the sticky footer
|
||||||
|
$sticky-footer-height: 80px;
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Import Custom Variables
|
||||||
|
@import "variables.scss";
|
||||||
|
|
||||||
|
// Import Bootstrap
|
||||||
|
@import "../vendor/bootstrap/scss/bootstrap.scss";
|
||||||
|
|
||||||
|
// Import Custom SCSS
|
||||||
|
@import "mixins.scss";
|
||||||
|
@import "global.scss";
|
||||||
|
@import "utilities.scss";
|
||||||
|
@import "navbar.scss";
|
||||||
|
@import "cards.scss";
|
||||||
|
@import "login.scss";
|
||||||
|
@import "footer.scss";
|
|
@ -0,0 +1,51 @@
|
||||||
|
//
|
||||||
|
// Base styles
|
||||||
|
//
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
position: relative;
|
||||||
|
padding: $alert-padding-y $alert-padding-x;
|
||||||
|
margin-bottom: $alert-margin-bottom;
|
||||||
|
border: $alert-border-width solid transparent;
|
||||||
|
@include border-radius($alert-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Headings for larger alerts
|
||||||
|
.alert-heading {
|
||||||
|
// Specified to prevent conflicts of changing $headings-color
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provide class for links that match alerts
|
||||||
|
.alert-link {
|
||||||
|
font-weight: $alert-link-font-weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Dismissible alerts
|
||||||
|
//
|
||||||
|
// Expand the right padding and account for the close button's positioning.
|
||||||
|
|
||||||
|
.alert-dismissible {
|
||||||
|
padding-right: $close-font-size + $alert-padding-x * 2;
|
||||||
|
|
||||||
|
// Adjust close link position
|
||||||
|
.close {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: $alert-padding-y $alert-padding-x;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Alternate styles
|
||||||
|
//
|
||||||
|
// Generate contextual modifier classes for colorizing the alert.
|
||||||
|
|
||||||
|
@each $color, $value in $theme-colors {
|
||||||
|
.alert-#{$color} {
|
||||||
|
@include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Base class
|
||||||
|
//
|
||||||
|
// Requires one of the contextual, color modifier classes for `color` and
|
||||||
|
// `background-color`.
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: $badge-padding-y $badge-padding-x;
|
||||||
|
@include font-size($badge-font-size);
|
||||||
|
font-weight: $badge-font-weight;
|
||||||
|
line-height: 1;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: baseline;
|
||||||
|
@include border-radius($badge-border-radius);
|
||||||
|
@include transition($badge-transition);
|
||||||
|
|
||||||
|
@at-root a#{&} {
|
||||||
|
@include hover-focus {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty badges collapse automatically
|
||||||
|
&:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quick fix for badges in buttons
|
||||||
|
.btn .badge {
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pill badges
|
||||||
|
//
|
||||||
|
// Make them extra rounded with a modifier to replace v3's badges.
|
||||||
|
|
||||||
|
.badge-pill {
|
||||||
|
padding-right: $badge-pill-padding-x;
|
||||||
|
padding-left: $badge-pill-padding-x;
|
||||||
|
@include border-radius($badge-pill-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Colors
|
||||||
|
//
|
||||||
|
// Contextual variations (linked badges get darker on :hover).
|
||||||
|
|
||||||
|
@each $color, $value in $theme-colors {
|
||||||
|
.badge-#{$color} {
|
||||||
|
@include badge-variant($value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
.breadcrumb {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
|
||||||
|
margin-bottom: $breadcrumb-margin-bottom;
|
||||||
|
list-style: none;
|
||||||
|
background-color: $breadcrumb-bg;
|
||||||
|
@include border-radius($breadcrumb-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb-item {
|
||||||
|
// The separator between breadcrumbs (by default, a forward-slash: "/")
|
||||||
|
+ .breadcrumb-item {
|
||||||
|
padding-left: $breadcrumb-item-padding;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
display: inline-block; // Suppress underlining of the separator in modern browsers
|
||||||
|
padding-right: $breadcrumb-item-padding;
|
||||||
|
color: $breadcrumb-divider-color;
|
||||||
|
content: $breadcrumb-divider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
|
||||||
|
// without `<ul>`s. The `::before` pseudo-element generates an element
|
||||||
|
// *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
|
||||||
|
//
|
||||||
|
// To trick IE into suppressing the underline, we give the pseudo-element an
|
||||||
|
// underline and then immediately remove it.
|
||||||
|
+ .breadcrumb-item:hover::before {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
// stylelint-disable-next-line no-duplicate-selectors
|
||||||
|
+ .breadcrumb-item:hover::before {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: $breadcrumb-active-color;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
// stylelint-disable selector-no-qualifying-type
|
||||||
|
|
||||||
|
// Make the div behave like a button
|
||||||
|
.btn-group,
|
||||||
|
.btn-group-vertical {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
vertical-align: middle; // match .btn alignment given font-size hack above
|
||||||
|
|
||||||
|
> .btn {
|
||||||
|
position: relative;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
|
||||||
|
// Bring the hover, focused, and "active" buttons to the front to overlay
|
||||||
|
// the borders properly
|
||||||
|
@include hover {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
&:focus,
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: Group multiple button groups together for a toolbar
|
||||||
|
.btn-toolbar {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group {
|
||||||
|
// Prevent double borders when buttons are next to each other
|
||||||
|
> .btn:not(:first-child),
|
||||||
|
> .btn-group:not(:first-child) {
|
||||||
|
margin-left: -$btn-border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset rounded corners
|
||||||
|
> .btn:not(:last-child):not(.dropdown-toggle),
|
||||||
|
> .btn-group:not(:last-child) > .btn {
|
||||||
|
@include border-right-radius(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
> .btn:not(:first-child),
|
||||||
|
> .btn-group:not(:first-child) > .btn {
|
||||||
|
@include border-left-radius(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sizing
|
||||||
|
//
|
||||||
|
// Remix the default button sizing classes into new ones for easier manipulation.
|
||||||
|
|
||||||
|
.btn-group-sm > .btn { @extend .btn-sm; }
|
||||||
|
.btn-group-lg > .btn { @extend .btn-lg; }
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Split button dropdowns
|
||||||
|
//
|
||||||
|
|
||||||
|
.dropdown-toggle-split {
|
||||||
|
padding-right: $btn-padding-x * .75;
|
||||||
|
padding-left: $btn-padding-x * .75;
|
||||||
|
|
||||||
|
&::after,
|
||||||
|
.dropup &::after,
|
||||||
|
.dropright &::after {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropleft &::before {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm + .dropdown-toggle-split {
|
||||||
|
padding-right: $btn-padding-x-sm * .75;
|
||||||
|
padding-left: $btn-padding-x-sm * .75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-lg + .dropdown-toggle-split {
|
||||||
|
padding-right: $btn-padding-x-lg * .75;
|
||||||
|
padding-left: $btn-padding-x-lg * .75;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The clickable button for toggling the menu
|
||||||
|
// Set the same inset shadow as the :active state
|
||||||
|
.btn-group.show .dropdown-toggle {
|
||||||
|
@include box-shadow($btn-active-box-shadow);
|
||||||
|
|
||||||
|
// Show no shadow for `.btn-link` since it has no other button styles.
|
||||||
|
&.btn-link {
|
||||||
|
@include box-shadow(none);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Vertical button groups
|
||||||
|
//
|
||||||
|
|
||||||
|
.btn-group-vertical {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
> .btn,
|
||||||
|
> .btn-group {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .btn:not(:first-child),
|
||||||
|
> .btn-group:not(:first-child) {
|
||||||
|
margin-top: -$btn-border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset rounded corners
|
||||||
|
> .btn:not(:last-child):not(.dropdown-toggle),
|
||||||
|
> .btn-group:not(:last-child) > .btn {
|
||||||
|
@include border-bottom-radius(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
> .btn:not(:first-child),
|
||||||
|
> .btn-group:not(:first-child) > .btn {
|
||||||
|
@include border-top-radius(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Checkbox and radio options
|
||||||
|
//
|
||||||
|
// In order to support the browser's form validation feedback, powered by the
|
||||||
|
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
|
||||||
|
// `display: none;` or `visibility: hidden;` as that also hides the popover.
|
||||||
|
// Simply visually hiding the inputs via `opacity` would leave them clickable in
|
||||||
|
// certain cases which is prevented by using `clip` and `pointer-events`.
|
||||||
|
// This way, we ensure a DOM element is visible to position the popover from.
|
||||||
|
//
|
||||||
|
// See https://github.com/twbs/bootstrap/pull/12794 and
|
||||||
|
// https://github.com/twbs/bootstrap/pull/14559 for more information.
|
||||||
|
|
||||||
|
.btn-group-toggle {
|
||||||
|
> .btn,
|
||||||
|
> .btn-group > .btn {
|
||||||
|
margin-bottom: 0; // Override default `<label>` value
|
||||||
|
|
||||||
|
input[type="radio"],
|
||||||
|
input[type="checkbox"] {
|
||||||
|
position: absolute;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
// stylelint-disable selector-no-qualifying-type
|
||||||
|
|
||||||
|
//
|
||||||
|
// Base styles
|
||||||
|
//
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
font-family: $btn-font-family;
|
||||||
|
font-weight: $btn-font-weight;
|
||||||
|
color: $body-color;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
user-select: none;
|
||||||
|
background-color: transparent;
|
||||||
|
border: $btn-border-width solid transparent;
|
||||||
|
@include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);
|
||||||
|
@include transition($btn-transition);
|
||||||
|
|
||||||
|
@include hover {
|
||||||
|
color: $body-color;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&.focus {
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: $btn-focus-box-shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disabled comes first so active can properly restyle
|
||||||
|
&.disabled,
|
||||||
|
&:disabled {
|
||||||
|
opacity: $btn-disabled-opacity;
|
||||||
|
@include box-shadow(none);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:disabled):not(.disabled):active,
|
||||||
|
&:not(:disabled):not(.disabled).active {
|
||||||
|
@include box-shadow($btn-active-box-shadow);
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
@include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Future-proof disabling of clicks on `<a>` elements
|
||||||
|
a.btn.disabled,
|
||||||
|
fieldset:disabled a.btn {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alternate buttons
|
||||||
|
//
|
||||||
|
|
||||||
|
@each $color, $value in $theme-colors {
|
||||||
|
.btn-#{$color} {
|
||||||
|
@include button-variant($value, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $color, $value in $theme-colors {
|
||||||
|
.btn-outline-#{$color} {
|
||||||
|
@include button-outline-variant($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Link buttons
|
||||||
|
//
|
||||||
|
|
||||||
|
// Make a button look and behave like a link
|
||||||
|
.btn-link {
|
||||||
|
font-weight: $font-weight-normal;
|
||||||
|
color: $link-color;
|
||||||
|
text-decoration: $link-decoration;
|
||||||
|
|
||||||
|
@include hover {
|
||||||
|
color: $link-hover-color;
|
||||||
|
text-decoration: $link-hover-decoration;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&.focus {
|
||||||
|
text-decoration: $link-hover-decoration;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled,
|
||||||
|
&.disabled {
|
||||||
|
color: $btn-link-disabled-color;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No need for an active state here
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Button Sizes
|
||||||
|
//
|
||||||
|
|
||||||
|
.btn-lg {
|
||||||
|
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm {
|
||||||
|
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Block button
|
||||||
|
//
|
||||||
|
|
||||||
|
.btn-block {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
// Vertically space out multiple block buttons
|
||||||
|
+ .btn-block {
|
||||||
|
margin-top: $btn-block-spacing-y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specificity overrides
|
||||||
|
input[type="submit"],
|
||||||
|
input[type="reset"],
|
||||||
|
input[type="button"] {
|
||||||
|
&.btn-block {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,289 @@
|
||||||
|
//
|
||||||
|
// Base styles
|
||||||
|
//
|
||||||
|
|
||||||
|
.card {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
|
||||||
|
word-wrap: break-word;
|
||||||
|
background-color: $card-bg;
|
||||||
|
background-clip: border-box;
|
||||||
|
border: $card-border-width solid $card-border-color;
|
||||||
|
@include border-radius($card-border-radius);
|
||||||
|
|
||||||
|
> hr {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .list-group:first-child {
|
||||||
|
.list-group-item:first-child {
|
||||||
|
@include border-top-radius($card-border-radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .list-group:last-child {
|
||||||
|
.list-group-item:last-child {
|
||||||
|
@include border-bottom-radius($card-border-radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body {
|
||||||
|
// Enable `flex-grow: 1` for decks and groups so that card blocks take up
|
||||||
|
// as much space as possible, ensuring footers are aligned to the bottom.
|
||||||
|
flex: 1 1 auto;
|
||||||
|
padding: $card-spacer-x;
|
||||||
|
color: $card-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
margin-bottom: $card-spacer-y;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-subtitle {
|
||||||
|
margin-top: -$card-spacer-y / 2;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-text:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-link {
|
||||||
|
@include hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ .card-link {
|
||||||
|
margin-left: $card-spacer-x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Optional textual caps
|
||||||
|
//
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
padding: $card-spacer-y $card-spacer-x;
|
||||||
|
margin-bottom: 0; // Removes the default margin-bottom of <hN>
|
||||||
|
color: $card-cap-color;
|
||||||
|
background-color: $card-cap-bg;
|
||||||
|
border-bottom: $card-border-width solid $card-border-color;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
@include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ .list-group {
|
||||||
|
.list-group-item:first-child {
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-footer {
|
||||||
|
padding: $card-spacer-y $card-spacer-x;
|
||||||
|
background-color: $card-cap-bg;
|
||||||
|
border-top: $card-border-width solid $card-border-color;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
@include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Header navs
|
||||||
|
//
|
||||||
|
|
||||||
|
.card-header-tabs {
|
||||||
|
margin-right: -$card-spacer-x / 2;
|
||||||
|
margin-bottom: -$card-spacer-y;
|
||||||
|
margin-left: -$card-spacer-x / 2;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header-pills {
|
||||||
|
margin-right: -$card-spacer-x / 2;
|
||||||
|
margin-left: -$card-spacer-x / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Card image
|
||||||
|
.card-img-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: $card-img-overlay-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-img {
|
||||||
|
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
|
||||||
|
@include border-radius($card-inner-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Card image caps
|
||||||
|
.card-img-top {
|
||||||
|
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
|
||||||
|
@include border-top-radius($card-inner-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-img-bottom {
|
||||||
|
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
|
||||||
|
@include border-bottom-radius($card-inner-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Card deck
|
||||||
|
|
||||||
|
.card-deck {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.card {
|
||||||
|
margin-bottom: $card-deck-margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(sm) {
|
||||||
|
flex-flow: row wrap;
|
||||||
|
margin-right: -$card-deck-margin;
|
||||||
|
margin-left: -$card-deck-margin;
|
||||||
|
|
||||||
|
.card {
|
||||||
|
display: flex;
|
||||||
|
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
|
||||||
|
flex: 1 0 0%;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-right: $card-deck-margin;
|
||||||
|
margin-bottom: 0; // Override the default
|
||||||
|
margin-left: $card-deck-margin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Card groups
|
||||||
|
//
|
||||||
|
|
||||||
|
.card-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
// The child selector allows nested `.card` within `.card-group`
|
||||||
|
// to display properly.
|
||||||
|
> .card {
|
||||||
|
margin-bottom: $card-group-margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(sm) {
|
||||||
|
flex-flow: row wrap;
|
||||||
|
// The child selector allows nested `.card` within `.card-group`
|
||||||
|
// to display properly.
|
||||||
|
> .card {
|
||||||
|
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
|
||||||
|
flex: 1 0 0%;
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
+ .card {
|
||||||
|
margin-left: 0;
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle rounded corners
|
||||||
|
@if $enable-rounded {
|
||||||
|
&:not(:last-child) {
|
||||||
|
@include border-right-radius(0);
|
||||||
|
|
||||||
|
.card-img-top,
|
||||||
|
.card-header {
|
||||||
|
// stylelint-disable-next-line property-blacklist
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
.card-img-bottom,
|
||||||
|
.card-footer {
|
||||||
|
// stylelint-disable-next-line property-blacklist
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:first-child) {
|
||||||
|
@include border-left-radius(0);
|
||||||
|
|
||||||
|
.card-img-top,
|
||||||
|
.card-header {
|
||||||
|
// stylelint-disable-next-line property-blacklist
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
}
|
||||||
|
.card-img-bottom,
|
||||||
|
.card-footer {
|
||||||
|
// stylelint-disable-next-line property-blacklist
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Columns
|
||||||
|
//
|
||||||
|
|
||||||
|
.card-columns {
|
||||||
|
.card {
|
||||||
|
margin-bottom: $card-columns-margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(sm) {
|
||||||
|
column-count: $card-columns-count;
|
||||||
|
column-gap: $card-columns-gap;
|
||||||
|
orphans: 1;
|
||||||
|
widows: 1;
|
||||||
|
|
||||||
|
.card {
|
||||||
|
display: inline-block; // Don't let them vertically span multiple columns
|
||||||
|
width: 100%; // Don't let their width change
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Accordion
|
||||||
|
//
|
||||||
|
|
||||||
|
.accordion {
|
||||||
|
> .card {
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&:not(:first-of-type) {
|
||||||
|
.card-header:first-child {
|
||||||
|
@include border-radius(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:last-of-type) {
|
||||||
|
border-bottom: 0;
|
||||||
|
@include border-radius(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-of-type {
|
||||||
|
border-bottom: 0;
|
||||||
|
@include border-bottom-radius(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-of-type {
|
||||||
|
@include border-top-radius(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
margin-bottom: -$card-border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|