Parcourir la source

Merge pull request #686 from causefx/cero-dev

Cero dev
causefx il y a 8 ans
Parent
commit
440efe086e
19 fichiers modifiés avec 718 ajouts et 540 suppressions
  1. 12 11
      chat/refreshmessages.php
  2. 2 141
      chatjs.php
  3. 6 0
      check.php
  4. 1 0
      config/configDefaults.php
  5. 7 1
      css/style.css
  6. 44 29
      error.php
  7. 183 96
      functions.php
  8. 146 24
      homepage.php
  9. 12 8
      index.php
  10. 2 0
      js/lazyload.min.js
  11. 12 0
      lang/de.ini
  12. 9 1
      lang/en.ini
  13. 33 21
      lang/es.ini
  14. 13 1
      lang/fr.ini
  15. 12 0
      lang/it.ini
  16. 12 0
      lang/nl.ini
  17. 12 0
      lang/pl.ini
  18. 156 186
      settings.php
  19. 44 21
      user.php

+ 12 - 11
chat/refreshmessages.php

@@ -17,7 +17,7 @@ if( $result = $db->query("SELECT * FROM
                          (SELECT id, timestamp, user, avatar, message
                           FROM chatpack_log ORDER BY id DESC LIMIT 125)
                           ORDER BY id ASC") )
-{   
+{
     $newmessages = array();
 
     while( $row = $result->fetchArray() )
@@ -27,16 +27,17 @@ if( $result = $db->query("SELECT * FROM
         $user = $row["user"];
         $avatar = $row["avatar"];
         $message = $row["message"];
-        
+
         $timenow = time();
         $messagetime = date("h:iA", intval($timestamp));
         $messagedate = date("m-d", intval($timestamp));
+        $messagenewtime = date("Y-m-d H:i:s", intval($timestamp));
         $message = utf8_encode($message);
-        
+
         $msgstr = "";  // message components
 
         if( strlen($user) > 0 && strlen($message) > 0 )
-        {  
+        {
             // catch emoticon
 
             $emoticon = false;
@@ -63,12 +64,12 @@ if( $result = $db->query("SELECT * FROM
                 $ending = substr($imagename, $endingpos+1);
                 $originalimg = $originalname . "." . $ending;
             }
-            
+
             if( !$emoticon && !$image )
             {
                 $message = decryptmessage($message);
             }
-            
+
             // catch URLs
 
             /*$message = str_replace("https://", "http://", $message);
@@ -91,7 +92,7 @@ if( $result = $db->query("SELECT * FROM
                                     "<span style=\"color: #d89334;\"><strong>$1</strong></span>", $message);
 
             // user online avatar
-            
+
             //$avatar = "<img class=\"avatarimg\" id=\"$timestamp\" src=\"" . $avatar . "\">";
 
             // unique message key
@@ -101,9 +102,9 @@ if( $result = $db->query("SELECT * FROM
 
             // show user avatar and message
             if($user == $currentuser){
-                $msgstr = $msgstr . "<p class=\"avatarandtext\" id=\"$messagekey\"><li><img src=\"$avatar\" id=\"$timestamp\" class=\"img-circle user-avatar $user\" alt=\"$user\"><div class=\"chat-panel blue-bg messagelike\" id=\"$id\"><div class=\"chat-heading clearfix\"><h4 class=\"pull-left zero-m\">$user</h4><p class=\"pull-right\"><i class=\"fa fa-clock-o\"></i>$messagedate $messagetime </p></div><div class=\"chat-body\">$message</div><span class=\"readed\"><i class=\"fa fa-heart red\" id=\"like$id\"></i></span></div></li></p>";//class="chat-inverted"
+                $msgstr = $msgstr . "<p class=\"avatarandtext\" id=\"$messagekey\"><li><img src=\"$avatar\" id=\"$timestamp\" class=\"img-circle user-avatar $user\" alt=\"$user\"><div class=\"chat-panel blue-bg messagelike\" id=\"$id\"><div class=\"chat-heading clearfix\"><h4 class=\"pull-left zero-m\">$user</h4><p class=\"pull-right\"><i class=\"fa fa-clock-o\"></i><timestamp time=\"$messagenewtime\" class=\"chat-timestamp\">$messagenewtime</timestamp></p></div><div class=\"chat-body\">$message</div></div></li></p>";//class="chat-inverted"
             }else{
-                $msgstr = $msgstr . "<p class=\"avatarandtext\" id=\"$messagekey\"><li class=\"chat-inverted\"><img src=\"$avatar\" id=\"$timestamp\" class=\"img-circle user-avatar $user\" alt=\"$user\"><div class=\"chat-panel red-bg messagelike\" id=\"$id\"><div class=\"chat-heading clearfix\"><h4 class=\"pull-left zero-m\">$user</h4><p class=\"pull-right\"><i class=\"fa fa-clock-o\"></i>$messagedate $messagetime </p></div><div class=\"chat-body\">$message</div><span class=\"readed\"><i class=\"fa fa-heart red liked\" id=\"like$id\"></i></span></div></li></p>";//class="chat-inverted"
+                $msgstr = $msgstr . "<p class=\"avatarandtext\" id=\"$messagekey\"><li class=\"chat-inverted\"><img src=\"$avatar\" id=\"$timestamp\" class=\"img-circle user-avatar $user\" alt=\"$user\"><div class=\"chat-panel red-bg messagelike\" id=\"$id\"><div class=\"chat-heading clearfix\"><h4 class=\"pull-left zero-m\">$user</h4><p class=\"pull-right\"><i class=\"fa fa-clock-o\"></i><timestamp time=\"$messagenewtime\" class=\"chat-timestamp\">$messagenewtime</timestamp></p></div><div class=\"chat-body\">$message</div></div></li></p>";//class="chat-inverted"
             }
 
             array_push($newmessages, $msgstr);
@@ -126,7 +127,7 @@ function decryptmessage($msg)
     $initvector = "aC92eG1PdGhuMXN6";
     $decryptedmessage = openssl_decrypt($msg, "AES-256-CBC", $key, 0, $initvector);
     $decryptedmessage = utf8_encode($decryptedmessage);
-    
+
     return $decryptedmessage;
 }
 
@@ -151,4 +152,4 @@ else
     }
 }
 
-?>
+?>

+ 2 - 141
chatjs.php

@@ -319,13 +319,13 @@ $(document).ready(function()
 
 
     // allowed characters in username
-
+	/*
     $("#username").keyup(function()
     {
         var text = $(this).val();
         $(this).val(text.replace(/[^a-zA-Z0-9 ]/g, ""));
     });
-
+	*/
     // enter username
 
     var user = "";
@@ -398,94 +398,6 @@ $(document).ready(function()
         }
     });
 
-    // log emoticon
-
-    $(".emoticonimg").click(function()
-    {
-        var emoticonselected = $(this);
-        emoticonselected.hide();
-        var emoticonid = $(this).attr("id");
-        var data = "messagedata=" + "specialchar" + emoticonid + "###" + user + "###" + avatar;
-
-        $.ajax
-        ({
-            type: "POST",
-            url: "chat/logmessage.php",
-            data: data,
-            cache: false,
-            success: function(result)
-            {
-                emoticonselected.show();
-            }
-        });
-    });
-
-    // show upload form
-
-    $("#showuploadform").click(function()
-    {
-        $("#showuploadform").hide();
-        $("#showemoticons").show();
-        $("#uploadform").show();
-        $("#emoticons").hide();
-        $("#loadingwrapper").hide();
-
-        var r = Math.floor((Math.random() * 14) + 1);
-        var randomemoticon = "chat/img/emoticon" + r + ".png";
-        $("#showemoticonsimg").attr("src", randomemoticon);
-
-        refresh();  // also use as manual content refresh
-    });
-
-    // upload image
-
-    $("#form").submit(function(event)
-    {
-        event.preventDefault();
-
-        $("#uploadform").hide();
-        $("#showemoticons").hide();
-        $("#loadingwrapper").show();
-
-        var filedata = $("#uploadimage").prop("files")[0];
-        var formdata = new FormData();
-        formdata.append("image", filedata);
-        var datavars = user + "###" + avatar;
-        formdata.append("datavars", datavars);
-
-        $.ajax
-        ({
-            type: "POST",
-            url: "chat/uploadimage.php",
-            cache: false,
-            contentType: false,
-            processData: false,
-            data: formdata,
-            success: function(result)
-            {
-                $("#uploadimage").val("");
-                $("#showuploadform").show();
-                $("#showemoticons").hide();
-                $("#uploadform").hide();
-                $("#loadingwrapper").hide();
-                $("#content").show();
-                $("#emoticons").show();
-            }
-        });
-    });
-
-    // show emoticons
-
-    $("#showemoticons").click(function()
-    {
-        $("#showuploadform").show();
-        $("#showemoticons").hide();
-        $("#uploadform").hide();
-        $("#loadingwrapper").hide();
-        $("#content").show();
-        $("#emoticons").show();
-    });
-
     // refresh content
 
     var content = $("#messages");
@@ -644,48 +556,12 @@ $(document).ready(function()
                                         }
                                     }
 
-                                    // refresh eventlisteners of messages to set likes
-
-                                    $(".messagelike").unbind().click(function()
-                                    {
-                                        if( this.innerHTML.indexOf("target=") == -1 &&
-                                            this.innerHTML.indexOf("_blank") == -1 )
-                                        {
-                                            likemessage(this.id);
-                                        }
-                                    });
                                 });
                             }
                         }
                     }
 
-                    // get and show likes
-
-                    $.ajax
-                    ({
-                        url: "chat/getlikes.php",
-                        cache: false,
-                        success: function(result)
-                        {
-                            var likesandunlikes = result.split("#");
-                            var likedmessages = likesandunlikes[0];
-                            var unlikedmessages = likesandunlikes[1];
-                            var likes = JSON.parse(likedmessages);
-                            var unlikes = JSON.parse(unlikedmessages);
-
-                            for( var i=0; i<likes.length; i++ )
-                            {
-                                var likeid = "#like" + likes[i];
-                                $(likeid).show();
-                            }
 
-                            for( var i=0; i<unlikes.length; i++ )
-                            {
-                                var unlikeid = "#like" + unlikes[i];
-                                $(unlikeid).hide();
-                            }
-                        }
-                    });
 
                     // hide intro
 
@@ -798,21 +674,6 @@ $(document).ready(function()
         }
     }
 
-    // like message
-
-    function likemessage(messageid)
-    {
-        var data = "messageid=" + messageid;
-
-        $.ajax
-        ({
-            type: "POST",
-            url: "chat/setlike.php",
-            data: data,
-            cache: false
-        });
-    }
-
     // update which users are typing
 
     function istyping(u, t)

+ 6 - 0
check.php

@@ -168,6 +168,12 @@ function getFilePermission($file) {
                 checkFunction("hash");
                 checkFunction("fopen");
                 checkFunction("fsockopen");
+				checkFunction("ob_start");
+				checkFunction("ob_get_contents");
+				checkFunction("ob_end_flush");
+				checkFunction("fwrite");
+				checkFunction("fclose");
+				checkFunction("readfile");
                 ?>
                 </div>
                 <div class="row">

+ 1 - 0
config/configDefaults.php

@@ -132,4 +132,5 @@ return array(
 	"homepageOrderembyrecent" => '11',
 	"homepageOrderombi" => '12',
 	"homepageOrdercalendar" => '13',
+	'requestedUserOnly' => 'true',
 );

+ 7 - 1
css/style.css

@@ -1019,6 +1019,10 @@ body {
   margin: 0 !important;
 }
 
+.zero-p {
+  padding: 0 !important;
+}
+
 .green {
   color: #42b382;
 }
@@ -1062,7 +1066,9 @@ body {
 .grayish-blue {
   color: #37474f;
 }
-
+.white {
+	color: #fff;
+}
 .white-bg {
   background: #fff !important;
 }

+ 44 - 29
error.php

@@ -1,32 +1,46 @@
 <?php
 // Include functions if not already included
 require_once('functions.php');
-
 // Upgrade environment
 upgradeCheck();
-
 // Lazyload settings
 $databaseConfig = configLazy('config/config.php');
-
 // Load USER
 require_once("user.php");
 $USER = new User("registration_callback");
-
+if(isset($_GET['error']) && $_GET['error'] !== '404'){
+    $status = (isset($_GET['error'])?$_GET['error']:404);
+    setcookie('lec', $status, time() + (5), "/", DOMAIN);
+    http_response_code($status);
+    //get file name
+    if(!empty($_SERVER['PHP_SELF'])){
+        $file = $_SERVER['PHP_SELF'];
+    }elseif(!empty($_SERVER['SCRIPT_NAME'])){
+        $file = $_SERVER['SCRIPT_NAME'];
+    }else{
+        $file = checkRootPath(dirname($_SERVER['SCRIPT_NAME'])).'error.php';
+    }
+    header('Location:'.$file);
+    exit();
+}
+if(!isset($_COOKIE['lec'])) {
+    $status = '404';
+} else {
+    $status = $_COOKIE['lec'];
+}
 // Create Database Connection
 $file_db = new PDO('sqlite:'.DATABASE_LOCATION.'users.db');
 $file_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
-
 // Some PHP config stuff
 ini_set("display_errors", 1);
 ini_set("error_reporting", E_ALL | E_STRICT);
-
+//Color stuff
 foreach(loadAppearance() as $key => $value) {
 	$$key = $value;
 }
-
+//error stuff
 $requested = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
-$status = (isset($_GET['error'])?$_GET['error']:404);
-$codes = array(  
+$codes = array(
        400 => array('Bad Request', 'The server cannot or will not process the request due to an apparent client error.', 'sowwy'),
        401 => array('Unauthorized', 'You do not have access to this page.', 'sowwy'),
        403 => array('Forbidden', 'The server has refused to fulfill your request.', 'sowwy'),
@@ -37,13 +51,12 @@ $codes = array(
        502 => array('Bad Gateway', 'The server received an invalid response from the upstream server while trying to fulfill the request.', 'confused'),
        503 => array('Service Unavailable', 'The server is currently unavailable (because it is overloaded or down for maintenance).', 'confused'),
        504 => array('Gateway Timeout', 'The upstream server failed to send a request in the time allowed by the server.', 'confused'),
-       999 => array('Not Logged In', 'You need to be logged in to access this page.', 'confused'),
+       999 => array('Not Logged In', 'You need to be logged in to access this page.', 'confused', '401'),
 );
-
 $errorTitle = ($codes[$status][0]) ? $codes[$status][0] : "Error";
 $message = ($codes[$status][1]) ? $codes[$status][1] : "An Error Occured";
 $errorImage = ($codes[$status][2]) ? $codes[$status][2] : "confused";
-
+$status = ($codes[$status][3]) ? $codes[$status][3] : $status;
 ?>
 
 <!DOCTYPE html>
@@ -54,12 +67,11 @@ $errorImage = ($codes[$status][2]) ? $codes[$status][2] : "confused";
         <meta name="viewport" content="width=device-width, initial-scale=1.0">
         <meta http-equiv="X-UA-Compatible" content="IE=edge">
         <meta name="msapplication-tap-highlight" content="no" />
-
         <title><?=$errorTitle;?></title>
-
-        <link rel="stylesheet" href="<?php echo checkRootPath(dirname($_SERVER['SCRIPT_NAME'])); ?>bower_components/bootstrap/dist/css/bootstrap.min.css">
-        <link rel="stylesheet" href="<?php echo checkRootPath(dirname($_SERVER['SCRIPT_NAME'])); ?>bower_components/Waves/dist/waves.min.css"> 
-        <link rel="stylesheet" href="<?php echo checkRootPath(dirname($_SERVER['SCRIPT_NAME'])); ?>css/style.css">
+        <link rel="stylesheet" href="<?php echo checkRootPath(dirname($_SERVER['SCRIPT_NAME'])); ?>bower_components/font-awesome/css/font-awesome.min.css?v=<?php echo INSTALLEDVERSION; ?>">
+        <link rel="stylesheet" href="<?php echo checkRootPath(dirname($_SERVER['SCRIPT_NAME'])); ?>bower_components/bootstrap/dist/css/bootstrap.min.css?v=<?php echo INSTALLEDVERSION; ?>">
+        <link rel="stylesheet" href="<?php echo checkRootPath(dirname($_SERVER['SCRIPT_NAME'])); ?>bower_components/Waves/dist/waves.min.css">
+        <link rel="stylesheet" href="<?php echo checkRootPath(dirname($_SERVER['SCRIPT_NAME'])); ?>css/style.css?v=<?php echo INSTALLEDVERSION; ?>">
 		<style><?php customCSS(); ?></style>
     </head>
     <body id="body-error" class="gray-bg" style="padding: 0;">
@@ -68,18 +80,21 @@ $errorImage = ($codes[$status][2]) ? $codes[$status][2] : "confused";
                 <div class="table-wrapper" style="background:<?=$sidebar;?>;">
                     <div class="table-row">
                         <div class="table-cell text-center">
-                            <div class="login i-block">
-                                <div class="content-box">
-                                    <div class="biggest-box" style="background:<?=$topbar;?>;">
-                                        <h1 class="zero-m text-uppercase" style="color:<?=$topbartext;?>; font-size: 40px;"><?=$errorTitle;?></h1>
-                                    </div>
-                                    <div class="big-box text-left">
-                                        <center><img src="<?php echo checkRootPath(dirname($_SERVER['SCRIPT_NAME'])); ?>images/<?=$errorImage;?>.png" style="height: 200px;"></center>
-                                        <h4 style="color: <?=$topbar;?>;" class="text-center"><?php echo $message;?></h4>
-                                        <button style="background:<?=$topbar;?>;" onclick="parent.location='../'" type="button" class="btn log-in btn-block btn-primary text-uppercase waves waves-effect waves-float"><text style="color:<?=$topbartext;?>;"><?php echo $language->translate("GO_BACK");?></text></button>
-                                    </div>
-                                </div>
-                            </div>
+                        	<div class="pagenotfound i-block">
+                        		<div class="content-box">
+                        			<div class="top" style="background:<?=$topbar;?>;">
+                        				<h1 class="zero-m" style="color:<?=$topbartext;?>;"><?=$status;?></h1>
+                        				<a href="#" onclick="parent.location='../'" class="fa-stack fa-2x icon-back">
+                        					<i class="fa fa-circle fa-stack-2x" style="color:<?=$topbartext;?>;"></i>
+                        					<i class="fa fa-long-arrow-left fa-stack-1x fa-inverse" style="color:<?=$topbar;?>;"></i>
+                        				</a>
+                        			</div>
+                        			<div class="big-box">
+                        				<h4 style="color: <?=$topbar;?>;"><?=$errorTitle;?></h4>
+                        				<p style="color: <?=$topbar;?>;"><?php echo $message;?></p>
+                        			</div>
+                        		</div>
+                        	</div>
                         </div>
                     </div>
                 </div>

+ 183 - 96
functions.php

@@ -2,7 +2,7 @@
 
 // ===================================
 // Define Version
- define('INSTALLEDVERSION', '1.50');
+ define('INSTALLEDVERSION', '1.5001');
 // ===================================
 use Kryptonit3\Sonarr\Sonarr;
 use Kryptonit3\SickRage\SickRage;
@@ -169,7 +169,7 @@ if (function_exists('curl_version')) :
 
 		// Get A User
 		$connectId = '';
-		$userIds = json_decode(file_get_contents($embyAddress.'/Users?api_key='.EMBYTOKEN),true);
+		$userIds = json_decode(@file_get_contents($embyAddress.'/Users?api_key='.EMBYTOKEN),true);
 		if (is_array($userIds)) {
 			foreach ($userIds as $key => $value) { // Scan for this user
 				if (isset($value['ConnectUserName']) && isset($value['ConnectUserId'])) { // Qualifty as connect account
@@ -394,6 +394,47 @@ if (function_exists('curl_version')) :
 		return array('content'=>$result, 'http_code'=>$httpcode);
 	}
 
+	// Curl Put
+	function curl_put($url, $data, $headers = array(), $referer='') {
+		// Initiate cURL
+		$curlReq = curl_init($url);
+		// As post request
+		curl_setopt($curlReq, CURLOPT_CUSTOMREQUEST, "PUT");
+		curl_setopt($curlReq, CURLOPT_RETURNTRANSFER, true);
+		curl_setopt($curlReq, CURLOPT_CAINFO, getCert());
+		if(localURL($url)){
+			curl_setopt($curlReq, CURLOPT_SSL_VERIFYHOST, 0);
+			curl_setopt($curlReq, CURLOPT_SSL_VERIFYPEER, 0);
+		}
+		// Format Data
+		switch (isset($headers['Content-Type'])?$headers['Content-Type']:'') {
+			case 'application/json':
+				curl_setopt($curlReq, CURLOPT_POSTFIELDS, json_encode($data));
+				break;
+			case 'application/x-www-form-urlencoded':
+				curl_setopt($curlReq, CURLOPT_POSTFIELDS, http_build_query($data));
+				break;
+			default:
+				$headers['Content-Type'] = 'application/x-www-form-urlencoded';
+				curl_setopt($curlReq, CURLOPT_POSTFIELDS, http_build_query($data));
+		}
+		// Format Headers
+		$cHeaders = array();
+		foreach ($headers as $k => $v) {
+			$cHeaders[] = $k.': '.$v;
+		}
+		if (count($cHeaders)) {
+			curl_setopt($curlReq, CURLOPT_HTTPHEADER, $cHeaders);
+		}
+		// Execute
+		$result = curl_exec($curlReq);
+		$httpcode = curl_getinfo($curlReq);
+		// Close
+		curl_close($curlReq);
+		// Return
+		return array('content'=>$result, 'http_code'=>$httpcode);
+	}
+
 	//Curl Get Function
 	function curl_get($url, $headers = array()) {
 		// Initiate cURL
@@ -544,7 +585,7 @@ function resolveEmbyItem($address, $token, $item, $nowPlaying = false, $showName
 	$height = 444;
 
 	// Get Item Details
-	$itemDetails = json_decode(file_get_contents($address.'/Items?Ids='.$item['Id'].'&api_key='.$token),true)['Items'][0];
+	$itemDetails = json_decode(@file_get_contents($address.'/Items?Ids='.$item['Id'].'&api_key='.$token),true)['Items'][0];
 	/*if (substr_count(EMBYURL, ':') == 2) {
 		$URL = "http://app.emby.media/itemdetails.html?id=".$itemDetails['Id'];
 	}else{
@@ -957,9 +998,9 @@ function outputRecentAdded($header, $items, $script = false, $array, $type) {
 function outputNowPlaying($header, $size, $type, $items, $script = false) {
 	// If None Populate Empty Item
 	if (!count($items)) {
-		return '<div id='.$type.'></div>'.($script?'<script>'.$script.'</script>':'');
+		return '<div id="'.$type.'"></div>'.($script?'<script>'.$script.'</script>':'');
 	}else{
-	   return '<div id='.$type.'><h5 class="zero-m big-box"><strong>'.$header.'</strong></h5>'.implode('',$items).'</div>'.($script?'<script>'.$script.'</script>':'');
+	   return '<div id="'.$type.'"><h5 class="zero-m big-box"><strong>'.$header.'</strong></h5>'.implode('',$items).'</div>'.($script?'<script>'.$script.'</script>':'');
  }
 
 }
@@ -978,16 +1019,7 @@ function getEmbyStreams($size, $showNames, $role) {
 		}
 	}
 
-	return outputNowPlaying(translate('PLAYING_NOW_ON_EMBY')." ( ".count($playingItems)." Streams )", $size, 'streams-emby', $playingItems, "
-		setInterval(function() {
-			$('<div></div>').load('ajax.php?a=emby-streams',function() {
-				var element = $(this).find('[id]');
-				var loadedID = 	element.attr('id');
-				$('#'+loadedID).replaceWith(element);
-				console.log('Loaded updated: '+loadedID);
-			});
-		}, ".NOWPLAYINGREFRESH.");
-	");
+	return outputNowPlaying(translate('PLAYING_NOW_ON_EMBY')." ( ".count($playingItems)." Streams )", $size, 'streams-emby', $playingItems, ajaxLoop('emby-streams',NOWPLAYINGREFRESH));
 }
 
 // Get Now Playing Streams From Plex
@@ -1011,16 +1043,7 @@ function getPlexStreams($size, $showNames, $role){
 				$items[] = resolvePlexItem($gotServer, PLEXTOKEN, $child, true, $showNames, $role);
 			}
 
-			return outputNowPlaying(translate('PLAYING_NOW_ON_PLEX')." ( ".count($items)." Streams )", $size, 'streams-plex', $items, "
-				setInterval(function() {
-					$('<div></div>').load('ajax.php?a=plex-streams',function() {
-						var element = $(this).find('[id]');
-						var loadedID = 	element.attr('id');
-						$('#'+loadedID).replaceWith(element);
-						console.log('Loaded updated: '+loadedID);
-					});
-				}, ".NOWPLAYINGREFRESH.");
-			");
+			return outputNowPlaying(translate('PLAYING_NOW_ON_PLEX')." ( ".count($items)." Streams )", $size, 'streams-plex', $items, ajaxLoop('plex-streams',NOWPLAYINGREFRESH));
 		}else{
 			writeLog("error", "PLEX STREAM ERROR: could not connect - check token - if HTTPS, is cert valid");
 		}
@@ -1056,7 +1079,7 @@ function getEmbyRecent($array) {
     }
 
     // Get the latest Items
-    $latest = json_decode(file_get_contents($address.'/Users/'.$userId.'/Items/Latest?EnableImages=false&Limit='.EMBYRECENTITEMS.'&api_key='.EMBYTOKEN.($showPlayed?'':'&IsPlayed=false')),true);
+    $latest = json_decode(@file_get_contents($address.'/Users/'.$userId.'/Items/Latest?EnableImages=false&Limit='.EMBYRECENTITEMS.'&api_key='.EMBYTOKEN.($showPlayed?'':'&IsPlayed=false')),true);
 
     // For Each Item In Category
     $items = array();
@@ -1075,18 +1098,7 @@ function getEmbyRecent($array) {
     unset($array["MusicAlbum"]);
     unset($array["Series"]);
 
-    return outputRecentAdded($header, $items, "
-	setInterval(function() {
-		$('<div></div>').load('ajax.php?a=emby-recent',function() {
-			var element = $(this).find('#recentMediaEmby');
-			var loadedID = 	element.attr('id');
-			$('#recentMediaEmby').replaceWith(element);
-			console.log('Loaded recent: '+loadedID);
-			loadSlick();
-		});
-
-	}, ".RECENTREFRESH.");
-	", $array, 'Emby');
+    return outputRecentAdded($header, $items, ajaxLoop('emby-recent',RECENTREFRESH,'loadSlick();'), $array, 'Emby');
 }
 
 // Get Recent Content From Plex
@@ -1114,18 +1126,7 @@ function getPlexRecent($array){
 				}
 			}
 
-			return outputRecentAdded($header, $items, "
-			setInterval(function() {
-				$('<div></div>').load('ajax.php?a=plex-recent',function() {
-					var element = $(this).find('#recentMediaPlex');
-					var loadedID = 	element.attr('id');
-					$('#recentMediaPlex').replaceWith(element);
-					console.log('Loaded recent: '+loadedID);
-					loadSlick();
-				});
-
-			}, ".RECENTREFRESH.");
-			", $array, 'Plex');
+			return outputRecentAdded($header, $items, ajaxLoop('plex-recent',RECENTREFRESH,'loadSlick();'), $array, 'Plex');
 		}else{
 			writeLog("error", "PLEX RECENT-ITEMS ERROR: could not connect - check token - if HTTPS, is cert valid");
 		}
@@ -1165,7 +1166,8 @@ function getEmbyImage() {
 	    }
         ob_start(); // Start the output buffer
         header('Content-type: image/jpeg');
-        @readfile($image_src);
+        //@readfile($image_src);
+		echo @curl_get($image_src);
         // Cache the output to a file
         $fp = fopen($cachefile, 'wb');
         fwrite($fp, ob_get_contents());
@@ -1206,7 +1208,8 @@ function getPlexImage() {
         }
 		ob_start(); // Start the output buffer
         header('Content-type: image/jpeg');
-		@readfile($image_src);
+		//@readfile($image_src);
+		echo @curl_get($image_src);
         // Cache the output to a file
         $fp = fopen($cachefile, 'wb');
         fwrite($fp, ob_get_contents());
@@ -4677,7 +4680,31 @@ function errormessage($msg) {
 	echo $msg;
 	echo "</div>";
 }
-
+function ajaxLoop($ajaxFunction, $refresh, $extraFunction = ''){
+	return "
+	setInterval(function() {
+		$.ajax({
+			url: 'ajax.php?a=".$ajaxFunction."',
+			timeout: 10000,
+			type: 'GET',
+			success: function(response) {
+				var getDiv = response;
+				var loadedID = 	$(getDiv).attr('id');
+				if (typeof loadedID !== 'undefined') {
+					$('#'+loadedID).replaceWith($(getDiv).prop('outerHTML'));
+					".$extraFunction."
+					console.log('".$ajaxFunction." has been updated');
+				}else{
+					console.log('".$ajaxFunction." data was not sufficent or is offline');
+				}
+			},
+			error: function(jqXHR, textStatus, errorThrown) {
+				console.error('".$ajaxFunction." could not be updated');
+			}
+		});
+	}, ".$refresh.");
+	";
+}
 function getOrgUsers(){
 	$file_db = DATABASE_LOCATION."users.db";
 	if(file_exists($file_db)){
@@ -4767,8 +4794,14 @@ function ombiAction($id, $action, $type){
 		case 'approve':
 			$api = curl_post(OMBIURL."/api/v1/Request/".$type."/approve", $body, $headers);
 			break;
+		case 'available':
+				$api = curl_post(OMBIURL."/api/v1/Request/".$type."/available", $body, $headers);
+				break;
+		case 'unavailable':
+				$api = curl_post(OMBIURL."/api/v1/Request/".$type."/unavailable", $body, $headers);
+				break;
 		case 'deny':
-			$api = curl_post(OMBIURL."/api/v1/Request/".$type."/deny", $body, $headers);
+			$api = curl_put(OMBIURL."/api/v1/Request/".$type."/deny", $body, $headers);
 			break;
 		case 'delete':
 			$api = curl_delete(OMBIURL."/api/v1/Request/".$type."/".$id, $headers);
@@ -4783,11 +4816,11 @@ function ombiAction($id, $action, $type){
 			return false;
 			break;
 		case 200:
-			writeLog("success", "OMBI: action completed successfully");
+			writeLog("success", "OMBI: action completed successfully for [type: $type - action: $action - id: $id]");
 			return true;
 			break;
 		default:
-			writeLog("error", "OMBI: unknown error with request [type: $type | action: $action | id: $id]");
+			writeLog("error", "OMBI: unknown error with request [type: $type - action: $action - id: $id]");
 			return false;
 	}
     //return (!empty($result) ? $result : null );
@@ -4813,33 +4846,47 @@ function getOmbiRequests($type = "both"){
 			break;
 	}
 	if(isset($movie)){
+		//$movie = array_reverse($movie);
 		foreach ($movie as $key => $value) {
-			$requests['movie'][] = array(
+			$poster = explode('/',$value['posterPath']);
+			$requests[] = array(
 				'id' => $value['theMovieDbId'],
 				'title' => $value['title'],
-				'poster' => (strpos($value['posterPath'], "http") !== false) ? $value['posterPath'] : 'https://image.tmdb.org/t/p/w300/'.$value['posterPath'],
+				'poster' => (strpos($value['posterPath'], "/") !== false) ? 'https://image.tmdb.org/t/p/w300/'.end($poster) : 'https://image.tmdb.org/t/p/w300/'.$value['posterPath'],
 				'approved' => $value['approved'],
 				'available' => $value['available'],
 				'denied' => $value['denied'],
 				'deniedReason' => $value['deniedReason'],
 				'user' => $value['requestedUser']['userName'],
 				'request_id' => $value['id'],
+				'request_date' => $value['requestedDate'],
+				'release_date' => $value['releaseDate'],
+				'type' => 'movie',
+				'icon' => 'mdi mdi-filmstrip',
+				'color' => 'palette-Deep-Purple-900 bg white',
 			);
 		}
 	}
 	if(isset($tv) && (is_array($tv) || is_object($tv))){
 		foreach ($tv as $key => $value) {
-			$requests['tv'][] = array(
-				'id' => $value['tvDbId'],
-				'title' => $value['title'],
-				'poster' => $value['posterPath'],
-				'approved' => $value['childRequests'][0]['approved'],
-				'available' => $key['childRequests'][0]['available'],
-				'denied' => $key['childRequests'][0]['denied'],
-				'deniedReason' => $key['childRequests'][0]['deniedReason'],
-				'user' => $value['childRequests'][0]['requestedUser']['userName'],
-				'request_id' => $value['id'],
-			);
+			if(is_array($value['childRequests'][0])){
+				$requests[] = array(
+					'id' => $value['tvDbId'],
+					'title' => $value['title'],
+					'poster' => $value['posterPath'],
+					'approved' => $value['childRequests'][0]['approved'],
+					'available' => $value['childRequests'][0]['available'],
+					'denied' => $value['childRequests'][0]['denied'],
+					'deniedReason' => $value['childRequests'][0]['deniedReason'],
+					'user' => $value['childRequests'][0]['requestedUser']['userName'],
+					'request_id' => $value['id'],
+					'request_date' => $value['childRequests'][0]['requestedDate'],
+					'release_date' => $value['releaseDate'],
+					'type' => 'tv',
+					'icon' => 'mdi mdi-television',
+					'color' => 'grayish-blue-bg',
+				);
+			}
 		}
 	}
     return (empty($requests)) ? '' : $requests;
@@ -4897,7 +4944,7 @@ function buildOmbiItem($type, $group, $user, $request){
 		$actions = '';
 		if($request['denied']){
 			$status = 1;
-			//$actions .= '<li request-type="'.$type.'" request-id="'.$request['request_id'].'" request-name="approve"><a class="requestAction" href="javascript:void(0)">Approve</a></li>';
+			$actions .= '<li request-type="'.$type.'" request-id="'.$request['request_id'].'" request-name="approve"><a class="requestAction" href="javascript:void(0)">Approve</a></li>';
 		}else{
 			if($request['approved']){
 				$status = 2;
@@ -4907,18 +4954,33 @@ function buildOmbiItem($type, $group, $user, $request){
 				$actions .= '<li request-type="'.$type.'" request-id="'.$request['request_id'].'" request-name="deny"><a class="requestAction" href="javascript:void(0)">Deny</a></li>';
 			}
 		}
+		if($request['available']){
+			$actions .= '<li request-type="'.$type.'" request-id="'.$request['request_id'].'" request-name="unavailable"><a class="requestAction" href="javascript:void(0)">Mark as Unavailable</a></li>';
+		}else{
+			$actions .= '<li request-type="'.$type.'" request-id="'.$request['request_id'].'" request-name="available"><a class="requestAction" href="javascript:void(0)">Mark as Available</a></li>';
+		}
 		$actions .= '<li request-type="'.$type.'" request-id="'.$request['request_id'].'" request-name="delete"><a class="requestAction" href="javascript:void(0)">Delete</a></li>';
 		if(isset($group) && $group == 'admin'){
+			$actionMenu = '
+			<div class="requestOptions">
+				<div class="btn-group transparent" role="group">
+					<button type="button" class="btn waves btn-success  btn-sm dropdown-toggle waves-effect waves-float transparent" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="mdi mdi-dots-vertical mdi-24px"></i></button>
+					<ul class="dropdown-menu"><h6 class="text-center requestHeader gray-bg">'.$request['user'].'</h6>'.$actions.'</ul>
+				</div>
+			</div>
+			';
+		}else{
+			$actionMenu = '';
+		}
+		if((isset($group)) && $group == 'admin' || REQUESTEDUSERONLY == 'false'){
 			return '
 			<div class="item-'.$type.'-'.convertOmbiString('approved', $request['approved'])['string'].'">
-				<div class="requestOptions">
-					<div class="btn-group transparent" role="group">
-						<button type="button" class="btn waves btn-success  btn-sm dropdown-toggle waves-effect waves-float transparent" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="mdi mdi-dots-vertical mdi-24px"></i></button>
-						<ul class="dropdown-menu"><h6 class="text-center">'.$request['user'].'</h6>'.$actions.'</ul>
-					</div>
-				</div>
+				'.$actionMenu.'
 				<a class="openTab" extraTitle="'.$request['title'].'" extraType="'.$type.'" openTab="true"><img alt="" class="slick-image-tall" data-lazy="'.$request['poster'].'"></a>
 				<div class="requestBottom text-center">
+					<div data-toggle="tooltip" data-placement="top" data-original-title="'.$request['type'].'" class="zero-m requestGroup '.$request['color'].'">
+						<i class="'.$request['icon'].'"></i>
+					</div>
 					<div data-toggle="tooltip" data-placement="top" data-original-title="'.convertOmbiString('status', $status)['string'].'" class="zero-m requestGroup '.convertOmbiString('status', $status)['color'].'">
 						<i class="'.convertOmbiString('status', $status)['icon'].'"></i>
 					</div>
@@ -4928,12 +4990,16 @@ function buildOmbiItem($type, $group, $user, $request){
 				</div>
 				<small class="elip slick-bottom-title">'.$request['title'].'</small>
 			</div>';
-		}elseif(isset($group) && $group == 'user'){
+		}else{
 			if(strtolower($request['user']) == strtolower($user)){
 				return '
 				<div class="item-'.$type.'-'.convertOmbiString('approved', $request['approved'])['string'].'">
+					'.$actionMenu.'
 					<a class="openTab" extraTitle="'.$request['title'].'" extraType="'.$type.'" openTab="true"><img alt="" class="slick-image-tall" data-lazy="'.$request['poster'].'"></a>
 					<div class="requestBottom text-center">
+						<div data-toggle="tooltip" data-placement="top" data-original-title="'.$request['type'].'" class="zero-m requestGroup '.$request['color'].'">
+							<i class="'.$request['icon'].'"></i>
+						</div>
 						<div data-toggle="tooltip" data-placement="top" data-original-title="'.convertOmbiString('status', $status)['string'].'" class="zero-m requestGroup '.convertOmbiString('status', $status)['color'].'">
 							<i class="'.convertOmbiString('status', $status)['icon'].'"></i>
 						</div>
@@ -4949,31 +5015,33 @@ function buildOmbiItem($type, $group, $user, $request){
 }
 function buildOmbiList($group, $user){
 	$requests = array();
-	$openTab = 'true';
 	$movieList = getOmbiRequests('movie');
 	$tvList = getOmbiRequests('tv');
-	if (is_array($movieList) || is_object($movieList)){
-		foreach ($movieList['movie'] as $request) {
-			$requests[] = buildOmbiItem('movie', $group, $user, $request);
+	if(is_array($movieList) && is_array($tvList)){
+		$result = array_merge($movieList , $tvList );
+	}else{
+		if(is_array($movieList)){
+			$result = $movieList;
+		}elseif(is_array($movieList)){
+			$result = $tvList;
+		}else{
+			$result = false;
 		}
 	}
-	if (is_array($tvList) || is_object($tvList)){
-		foreach ($tvList['tv'] as $request) {
-			$requests[] = buildOmbiItem('season', $group, $user, $request);
+	if (is_array($result) || is_object($result)){
+		usort($result, function ($item1, $item2) {
+			if ($item1['request_date'] == $item2['request_date']) return 0;
+			return $item1['request_date'] > $item2['request_date'] ? -1 : 1;
+		});
+		foreach ($result as $request) {
+			if($request['type'] == 'movie'){
+		        $requests[] = buildOmbiItem('movie', $group, $user, $request);
+		    }elseif($request['type'] == 'tv'){
+		        $requests[] = buildOmbiItem('season', $group, $user, $request);
+		    }
 		}
 	}
-	return outputOmbiRequests("Requested Content", $requests, "
-	setInterval(function() {
-		$('<div></div>').load('ajax.php?a=ombi-requests',function() {
-			var element = $(this).find('#recentRequests');
-			var loadedID = 	element.attr('id');
-			$('#recentRequests').replaceWith(element);
-			console.log('Loaded updated: '+loadedID);
-			loadSlick();
-		});
-
-	}, ".RECENTREFRESH.");
-	", false);
+	return outputOmbiRequests("Requested Content", $requests, ajaxLoop('ombi-requests',REQUESTREFRESH,'loadSlick();'), false);
 }
 
 function outputOmbiRequests($header = "Requested Content", $items, $script = false, $array) {
@@ -5001,6 +5069,25 @@ function outputOmbiRequests($header = "Requested Content", $items, $script = fal
     }
 }
 
+function loadIcons(){
+	$dirname = "images/";
+	$images = scandir($dirname);
+	$ignore = Array(".", "..", "favicon", "settings", "cache", "platforms", "._.DS_Store", ".DS_Store", "confused.png", "sowwy.png", "sort-btns", "loading.png", "titlelogo.png", "default.svg", "login.png", "no-np.png", "no-list.png", "no-np.psd", "no-list.psd", "themes", "nadaplaying.jpg", "organizr-logo-h-d.png", "organizr-logo-h.png");
+	$allIcons = '';
+	foreach($images as $curimg){
+		if(!in_array($curimg, $ignore)) {
+			$allIcons .= '
+			<div class="col-xs-2" style="width: 75px; height: 75px; padding-right: 0px;">
+				<a data-toggle="tooltip" data-placement="bottom" title="'.$dirname.$curimg.'" class="thumbnail" style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);">
+					<img style="width: 50px; height: 50px;" data-src="'.$dirname.$curimg.'" alt="thumbnail" class="allIcons lazyload shadow">
+				</a>
+			</div>
+			';
+		}
+	}
+	return $allIcons;
+}
+
 function buildHomepageSettings(){
 	$homepageOrder = homepageOrder();
 	$homepageList = '<h4>Drag Homepage Items to Order Them</h4><div id="homepage-items" class="external-events">';

+ 146 - 24
homepage.php

@@ -75,6 +75,15 @@ foreach(loadAppearance() as $key => $value) {
         <![endif]-->
         <style>
 			<?php if($USER->role !== "admin"){ echo '.refreshImage { display: none; }';}?>
+            .requestOptions ul.dropdown-menu {
+                max-width: 160px;
+            }
+			.requestHeader {
+				padding: 5px;
+				margin-top: -10px;
+				border-radius: 5px 5px 0 0;
+                margin-bottom: 0;
+			}
 			.requestOptions {
 				position: absolute;
 			    top: 5px;
@@ -468,10 +477,10 @@ foreach(loadAppearance() as $key => $value) {
 	                console.log('creating slick for '+name);
 	                $(this).slick({
 
-	                    slidesToShow: 13,
-	                    slidesToScroll: 13,
+	                    slidesToShow: 27,
+	                    slidesToScroll: 27,
 	                    infinite: true,
-						speed: 900,
+						//speed: 900,
 	                    lazyLoad: 'ondemand',
 	                    prevArrow: '<a class="zero-m pull-left prev-mail btn btn-default waves waves-button btn-sm waves-effect waves-float"><i class="fa fa-angle-left"></i></a>',
 	                    nextArrow: '<a class="pull-left next-mail btn btn-default waves waves-button btn-sm waves-effect waves-float"><i class="fa fa-angle-right"></i></a>',
@@ -479,73 +488,178 @@ foreach(loadAppearance() as $key => $value) {
 	                    arrows: true,
 	                    responsive: [
 							{
-			                    breakpoint: 1750,
+								breakpoint: 3744,
+								settings: {
+									slidesToShow: 26,
+									slidesToScroll: 26,
+								}
+							},
+							{
+								breakpoint: 3600,
+								settings: {
+									slidesToShow: 25,
+									slidesToScroll: 25,
+								}
+							},
+							{
+								breakpoint: 3456,
+								settings: {
+									slidesToShow: 24,
+									slidesToScroll: 24,
+								}
+							},
+							{
+								breakpoint: 3312,
+								settings: {
+									slidesToShow: 23,
+									slidesToScroll: 23,
+								}
+							},
+							{
+								breakpoint: 3168,
+								settings: {
+									slidesToShow: 22,
+									slidesToScroll: 22,
+								}
+							},
+							{
+								breakpoint: 3024,
+								settings: {
+									slidesToShow: 21,
+									slidesToScroll: 21,
+								}
+							},
+							{
+								breakpoint: 2880,
+								settings: {
+									slidesToShow: 20,
+									slidesToScroll: 20,
+								}
+							},
+							{
+								breakpoint: 2736,
+								settings: {
+									slidesToShow: 19,
+									slidesToScroll: 19,
+								}
+							},
+							{
+								breakpoint: 2592,
+								settings: {
+									slidesToShow: 18,
+									slidesToScroll: 18,
+								}
+							},
+							{
+								breakpoint: 2448,
+								settings: {
+									slidesToShow: 17,
+									slidesToScroll: 17,
+								}
+							},
+							{
+			                    breakpoint: 2304,
+			                    settings: {
+			                        slidesToShow: 16,
+			                        slidesToScroll: 16,
+			                    }
+		                    },
+							{
+								breakpoint: 2160,
+								settings: {
+									slidesToShow: 15,
+									slidesToScroll: 15,
+								}
+							},
+							{
+			                    breakpoint: 2016,
+			                    settings: {
+			                        slidesToShow: 14,
+			                        slidesToScroll: 14,
+			                    }
+		                    },
+							{
+			                    breakpoint: 1872,
+			                    settings: {
+			                        slidesToShow: 13,
+			                        slidesToScroll: 13,
+			                    }
+		                    },
+							{
+			                    breakpoint: 1728,
+			                    settings: {
+			                        slidesToShow: 12,
+			                        slidesToScroll: 12,
+			                    }
+		                    },
+							{
+			                    breakpoint: 1584,
 			                    settings: {
 			                        slidesToShow: 11,
 			                        slidesToScroll: 11,
 			                    }
 		                    },
 		                    {
-			                    breakpoint: 1600,
+			                    breakpoint: 1440,
 			                    settings: {
 			                        slidesToShow: 10,
 			                        slidesToScroll: 10,
 			                    }
 		                    },
 		                    {
-			                    breakpoint: 1450,
+			                    breakpoint: 1296,
 			                    settings: {
 			                        slidesToShow: 9,
 			                        slidesToScroll: 9,
 			                    }
 		                    },
 		                    {
-			                    breakpoint: 1300,
+			                    breakpoint: 1152,
 			                    settings: {
 			                        slidesToShow: 8,
 			                        slidesToScroll: 8,
 			                    }
 		                    },
 		                    {
-			                    breakpoint: 1150,
+			                    breakpoint: 1008,
 			                    settings: {
 			                        slidesToShow: 7,
 			                        slidesToScroll: 7,
 			                    }
 		                    },
 		                    {
-			                    breakpoint: 1000,
+			                    breakpoint: 864,
 			                    settings: {
 			                        slidesToShow: 6,
 			                        slidesToScroll: 6,
 			                    }
 		                    },
 		                    {
-			                    breakpoint: 850,
+			                    breakpoint: 720,
 			                    settings: {
 			                        slidesToShow: 5,
 			                        slidesToScroll: 5,
 			                    }
 		                    },
 		                    {
-			                    breakpoint: 700,
+			                    breakpoint: 576,
 			                    settings: {
 			                        slidesToShow: 4,
 			                        slidesToScroll: 4,
 			                    }
 		                    },
 		                    {
-			                    breakpoint: 675,
+			                    breakpoint: 432,
 			                    settings: {
-			                        slidesToShow: 4,
-			                        slidesToScroll: 4,
+			                        slidesToShow: 3,
+			                        slidesToScroll: 3,
 			                    }
 		                    },
 		                    {
-			                    breakpoint: 480,
+			                    breakpoint: 288,
 			                    settings: {
-			                        slidesToShow: 3,
-			                        slidesToScroll: 3,
+			                        slidesToShow: 2,
+			                        slidesToScroll: 2,
 			                    }
 		                    }
 		                ]
@@ -579,13 +693,21 @@ foreach(loadAppearance() as $key => $value) {
 					action_type: action,
 					type: type,
                 }).done(function(data){
-					$('<div></div>').load('ajax.php?a=ombi-requests',function() {
-						var element = $(this).find('[id]');
-						var loadedID = 	element.attr('id');
-						$('#'+loadedID).replaceWith(element);
-						console.log('OMBI ACTION Submited and reloaded: '+loadedID);
-						loadSlick();
-					});
+                    $.ajax({
+        				url: 'ajax.php?a=ombi-requests',
+        				timeout: 10000,
+        				type: 'GET',
+        				success: function(response) {
+        					var getDiv = response;
+        					var loadedID = 	$(getDiv).attr('id');
+        					$('#'+loadedID).replaceWith($(getDiv).prop('outerHTML'));
+        					console.log('OMBI ACTION Submited and reloaded: '+loadedID);
+                            loadSlick();
+        				},
+        				error: function(jqXHR, textStatus, errorThrown) {
+        					console.error(loadedID+' could not be updated');
+        				}
+        			});
 				});
 			});
             $('.repeat-btn').click(function(){

+ 12 - 8
index.php

@@ -538,7 +538,7 @@ $group = (isset($group) ? $group : "guest");
 									<li window="<?=$row['window'];?>" class="tab-item <?=$defaultz;?>" id="<?=$row['url'];?>x" data-title="<?=$row['name'];?>" name="<?php echo strtolower($row['name']);?>">
 										<a class="tab-link">
 											<?php if($row['iconurl']) { ?>
-												<i style="font-size: 19px; padding: 0 10px; font-size: 19px;">
+												<i style="font-size: 19px; padding: 0 10px; font-size: 19px" data-toggle="tooltip" data-placement="bottom" data-original-title="<?=$row['name'];?>">
 													<span id="<?=$row['url'];?>s" class="badge badge-success" style="position: absolute;z-index: 100;right: 0px;"></span>
 													<img src="<?=$row['iconurl'];?>" style="height: 30px; width: 30px; margin-top: -2px;">
 													<?php if($row['ping'] == "true" && $row['ping_url']){ $allPings["image".$name] = $row['ping_url']; ?>
@@ -546,7 +546,7 @@ $group = (isset($group) ? $group : "guest");
 													<?php }?>
 												</i>
 											<?php }else { ?>
-												<i class="fa <?=$row['icon'];?> fa-lg">
+												<i class="fa <?=$row['icon'];?> fa-lg" data-toggle="tooltip" data-placement="bottom" data-original-title="<?=$row['name'];?>">
 													<span id="<?=$row['url'];?>s" class="badge badge-success" style="position: absolute;z-index: 100;right: 0px;"></span>
 													<?php if($row['ping'] == "true" && $row['ping_url']){ $allPings["icon".$name] = $row['ping_url']; ?>
 														<ping class="ping-<?=$name;?> startPingTimer"></ping>
@@ -797,8 +797,8 @@ $group = (isset($group) ? $group : "guest");
 										<h1 class="zero-m text-uppercase" style="color:<?=$topbartext;?>;"><?php echo $language->translate("HOLD_UP");?></h1>
 									</div>
 									<div class="big-box text-left">
-										<center><img src="images/sowwy.png" style="height: 200px;"></center>
-										<h2 class="text-center"><?php echo $language->translate("LOOKS_LIKE_YOU_DONT_HAVE_ACCESS");?></h2>
+										<!--<center><img src="images/sowwy.png" style="height: 200px;"></center>
+										<h2 class="text-center"><?php echo $language->translate("LOOKS_LIKE_YOU_DONT_HAVE_ACCESS");?></h2>-->
 										<?php if(!$USER->authenticated) : ?>
 										<button style="background:<?=$topbar;?>;" type="submit" class="btn log-in btn-block btn-primary text-uppercase waves waves-effect waves-float"><text style="color:<?=$topbartext;?>;"><?php echo $language->translate("LOGIN");?></text></button>
 										<?php endif; ?>
@@ -897,6 +897,7 @@ $group = (isset($group) ? $group : "guest");
 										<input type="hidden" name="op" value="register"/>
 										<input type="hidden" name="sha1" value=""/>
 										<input type="hidden" name="settings" value="false"/>
+										<input type="hidden" name="validate" id="validate" value=""/>
 
 										<div class="form-group">
 
@@ -949,7 +950,7 @@ $group = (isset($group) ? $group : "guest");
 									<form name="log out" id="logout" action="" method="POST">
 										<input type="hidden" name="op" value="logout">
 										<input type="hidden" name="username"value="<?php echo $_SESSION["username"]; ?>" >
-										<center><img src="images/sowwy.png" style="height: 200px;"></center>
+										<!--<center><img src="images/sowwy.png" style="height: 200px;"></center>-->
 										<h3 style="color:<?=$topbar;?>;" class="zero-m text-uppercase"><?php echo $language->translate("DO_YOU_WANT_TO_LOGOUT");?></h3>
 										<a style="color:<?=$topbar;?>;" id="logoutSubmit" class="i-block" data-dismiss="modal"><?php echo $language->translate("YES_WORD");?></a>
 										<a style="color:<?=$topbar;?>;" class="i-block" data-dismiss="modal"><?php echo $language->translate("NO_WORD");?></a>
@@ -1057,7 +1058,7 @@ $group = (isset($group) ? $group : "guest");
 						<div class="row">
 							<?php if($tabSetup == "No") : $tabCount = 1; foreach($splash as $row) :
 								$name = str_replace(array(':', '\\', '/', '*'), 'x', $row['ping_url']);?>
-							<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2" id="splash-<?php echo strtolower($row['name']);?>">
+							<div class="col-xs-6 col-md-2 col-lg-2 splashContainer" id="splash-<?php echo strtolower($row['name']);?>">
 								<li style="list-style-type: none; cursor: pointer;" window="<?=$row['window'];?>" class="splash-item content-box small-box ultra-widget gray-bg" name="<?php echo strtolower($row['name']);?>">
 									<div class="w-content">
 										<div class="w-icon">
@@ -1083,13 +1084,13 @@ $group = (isset($group) ? $group : "guest");
 							</div>
 							<?php $tabCount++; endforeach; endif;?>
 							<?php if( $USER->authenticated && $USER->role == "admin" ){ ?>
-								<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">
+								<div class="col-xs-6 col-md-2 col-lg-2 splashContainer">
 									<li style="list-style-type: none; cursor: pointer;" class="splash-item content-box small-box ultra-widget gray-bg" data-title="" name="settings">
 										<div class="w-content">
 											<div class="w-icon">
 												<center>
 													<i style="">
-														<img src="images/settings.png" style="height: 100px; margin-top: -10px;" class="">
+														<img src="images/<?=$settingsIcon;?>" style="height: 100px; margin-top: -10px;" class="">
 													</i>
 												</center>
 											</div>
@@ -1559,8 +1560,10 @@ $group = (isset($group) ? $group : "guest");
 		update();
 		setInterval(update, 60000);
 		console.log(date);
+		<?php if($userDevice !== "phone"){?>
 		//Tooltips
 		$('[data-toggle="tooltip"]').tooltip();
+		<?php } ?>
 		$(".box").niceScroll({
             railpadding: {top:0,right:0,left:0,bottom:0},
             scrollspeed: 30,
@@ -1829,6 +1832,7 @@ $group = (isset($group) ? $group : "guest");
 							$("#userPassForm").toggle();
 							$("#registration").toggle();
 							$("#welcomeGoBack3").toggle();
+							$("#validate").val($('input[name=registerPasswordValue]').val());
 
 						}
 

+ 2 - 0
js/lazyload.min.js

@@ -0,0 +1,2 @@
+/*! Lazy Load 2.0.0-beta.2 - MIT license - Copyright 2007-2017 Mika Tuupola */
+!function(t,e){"object"==typeof exports?module.exports=e(t):"function"==typeof define&&define.amd?define([],e(t)):t.LazyLoad=e(t)}("undefined"!=typeof global?global:this.window||this.global,function(t){"use strict";function e(t,e){this.settings=r(s,e||{}),this.images=t||document.querySelectorAll(this.settings.selector),this.observer=null,this.init()}const s={src:"data-src",srcset:"data-srcset",selector:".lazyload"},r=function(){let t={},e=!1,s=0,o=arguments.length;"[object Boolean]"===Object.prototype.toString.call(arguments[0])&&(e=arguments[0],s++);for(;s<o;s++)!function(s){for(let o in s)Object.prototype.hasOwnProperty.call(s,o)&&(e&&"[object Object]"===Object.prototype.toString.call(s[o])?t[o]=r(!0,t[o],s[o]):t[o]=s[o])}(arguments[s]);return t};if(e.prototype={init:function(){if(!t.IntersectionObserver)return void this.loadImages();let e=this,s={root:null,rootMargin:"0px",threshold:[0]};this.observer=new IntersectionObserver(function(t){t.forEach(function(t){if(t.intersectionRatio>0){e.observer.unobserve(t.target);let s=t.target.getAttribute(e.settings.src),r=t.target.getAttribute(e.settings.srcset);"img"===t.target.tagName.toLowerCase()?(s&&(t.target.src=s),r&&(t.target.srcset=r)):t.target.style.backgroundImage="url("+s+")"}})},s),this.images.forEach(function(t){e.observer.observe(t)})},loadAndDestroy:function(){this.settings&&(this.loadImages(),this.destroy())},loadImages:function(){if(!this.settings)return;let t=this;this.images.forEach(function(e){let s=e.getAttribute(t.settings.src),r=e.getAttribute(t.settings.srcset);"img"===e.tagName.toLowerCase()?(s&&(e.src=s),r&&(e.srcset=r)):e.style.backgroundImage="url("+s+")"})},destroy:function(){this.settings&&(this.observer.disconnect(),this.settings=null)}},t.lazyload=function(t,s){return new e(t,s)},t.jQuery){const s=t.jQuery;s.fn.lazyload=function(t){return t=t||{},t.attribute=t.attribute||"data-src",new e(s.makeArray(this),t),this}}return e});

+ 12 - 0
lang/de.ini

@@ -333,3 +333,15 @@ COUCH_URL = "Couchpotato URL"
 COUCH_KEY = "Couchpotato API/Schlüssel"
 DELETE_CHAT_DATABASE = "Chat Datenbank löschen"
 INSTALLED_THEME = "Installiertes Thema"
+PLEX_TAB_URL = "Plex Tab URL - i.e. https://domain.com/plex or https://plex.domain.com"
+RECENT_REFRESH = "Recent Items Refresh Rate"
+NOW_PLAYING_REFRESH = "Now Playing Refresh Rate"
+REQUEST_REFRESH = "Requests Refresh Rate"
+COLOR_TEMPLATE = "Color Templates"
+REQUESTED_ONLY = "Show only requests for that user - if Off it will show all requests"
+SIZE = "Size"
+OR_ICON_NAME = "or Icon Name"
+OMBI_URL = "Ombi V3 URL"
+OMBI_KEY = "Ombi V3 API Key"
+ENABLE_WEATHER = "Enable Weather Widget"
+WEATHER_AUTH = "Minimum authentication level to access Weather Widget"

+ 9 - 1
lang/en.ini

@@ -206,7 +206,7 @@ SABNZBD_KEY = "SABnzbd API Key"
 HEADPHONES_URL = "Headphones URL"
 HEADPHONES_PORT = "Headphones Port"
 HEADPHONES_KEY = "Headphones API Key"
-COOKIE_DOMAIN = "Domain Name for Cookie"
+COOKIE_DOMAIN = "Domain Name for Cookie & Auth Request i.e. domain.com"
 DAYS = "Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday"
 CALENDAR_START_DAY = "First Day"
 CALENDAR_START_DATE = "# of Days Before"
@@ -337,3 +337,11 @@ PLEX_TAB_URL = "Plex Tab URL - i.e. https://domain.com/plex or https://plex.doma
 RECENT_REFRESH = "Recent Items Refresh Rate"
 NOW_PLAYING_REFRESH = "Now Playing Refresh Rate"
 REQUEST_REFRESH = "Requests Refresh Rate"
+COLOR_TEMPLATE = "Color Templates"
+REQUESTED_ONLY = "Show only requests for that user - if Off it will show all requests"
+SIZE = "Size"
+OR_ICON_NAME = "or Icon Name"
+OMBI_URL = "Ombi V3 URL"
+OMBI_KEY = "Ombi V3 API Key"
+ENABLE_WEATHER = "Enable Weather Widget"
+WEATHER_AUTH = "Minimum authentication level to access Weather Widget"

+ 33 - 21
lang/es.ini

@@ -12,14 +12,14 @@ EMAIL_ADDRESS = "Correo electrónico"
 EMAIL = "Correo electrónico"
 PASSWORD = "Contraseña"
 PASSWORD_AGAIN = "Contraseña otra vez"
-ADMIN = "Administrador" 
-USER = "Usuario" 
-HOLD_UP = "¡Espera!" 
-LOOKS_LIKE_YOU_DONT_HAVE_ACCESS = "Parece que no tienes acceso." 
-USERNAME = "Nombre de usuario" 
-REMEMBER_ME = "Recuérdame" 
-FORGOT_PASSWORD = "¿Has olvidado tu contraseña?" 
-RESET_PASSWORD = "Restablecimiento de contraseña" 
+ADMIN = "Administrador"
+USER = "Usuario"
+HOLD_UP = "¡Espera!"
+LOOKS_LIKE_YOU_DONT_HAVE_ACCESS = "Parece que no tienes acceso."
+USERNAME = "Nombre de usuario"
+REMEMBER_ME = "Recuérdame"
+FORGOT_PASSWORD = "¿Has olvidado tu contraseña?"
+RESET_PASSWORD = "Restablecimiento de contraseña"
 DATABASE_PATH = "Camino de la base de datos"
 SPECIFY_LOCATION = "¿Dónde quieres guardar los archivos de la base de datos?"
 CURRENT_DIRECTORY = "Directorio actual"
@@ -86,20 +86,20 @@ INSTALLED_VERSION = "Versión instalada""
 CURRENT_VERSION = "Versión actual""
 DELETE_DATABASE = "Eliminar base de datos "
 DELETE_WARNING = "Haga esto solo si una actualización lo requiere. Esto eliminará su base de datos. No se pueda volver atrás y necesitará configurarlo todo, incluyendo las cuentas de usuario"
-SUBMIT_ISSUE = "Enviar un problema o una solicitud" 
-VIEW_ON_GITHUB = "Ver en GitHub" 
+SUBMIT_ISSUE = "Enviar un problema o una solicitud"
+VIEW_ON_GITHUB = "Ver en GitHub"
 CHAT_WITH_US = "Chatea con nosotros" T
-ABS_SAVED = "Pestañas guardadas" 
-APPLY_CHANGES = "Aplicar los cambios" 
-APPLY_RELOAD = "Aplicar cambios para actualizar la página" 
-OK = "OK" 
-COLORS_SAVED = "Colores guardados" 
-NEW_VERSION = "Nueva versión disponible" 
-CLICK_INFO = "Haga clic en la pestaña información" 
-WHATS_NEW = "Qué hay de nuevo en" 
-CHANGES = "Cambios" 
-AUTO_UPGRADE = "Actualización automática" 
-SOFTWARE_IS = "Software es" 
+ABS_SAVED = "Pestañas guardadas"
+APPLY_CHANGES = "Aplicar los cambios"
+APPLY_RELOAD = "Aplicar cambios para actualizar la página"
+OK = "OK"
+COLORS_SAVED = "Colores guardados"
+NEW_VERSION = "Nueva versión disponible"
+CLICK_INFO = "Haga clic en la pestaña información"
+WHATS_NEW = "Qué hay de nuevo en"
+CHANGES = "Cambios"
+AUTO_UPGRADE = "Actualización automática"
+SOFTWARE_IS = "Software es"
 UP_TO_DATE = "¡Actualizado!"
 PREVIOUS = "Previous"
 NEXT = "Next"
@@ -333,3 +333,15 @@ COUCH_URL = "Couchpotato URL"
 COUCH_KEY = "Couchpotato API/Key"
 DELETE_CHAT_DATABASE = "Delete Chat Database"
 INSTALLED_THEME = "Installed Theme"
+PLEX_TAB_URL = "Plex Tab URL - i.e. https://domain.com/plex or https://plex.domain.com"
+RECENT_REFRESH = "Recent Items Refresh Rate"
+NOW_PLAYING_REFRESH = "Now Playing Refresh Rate"
+REQUEST_REFRESH = "Requests Refresh Rate"
+COLOR_TEMPLATE = "Color Templates"
+REQUESTED_ONLY = "Show only requests for that user - if Off it will show all requests"
+SIZE = "Size"
+OR_ICON_NAME = "or Icon Name"
+OMBI_URL = "Ombi V3 URL"
+OMBI_KEY = "Ombi V3 API Key"
+ENABLE_WEATHER = "Enable Weather Widget"
+WEATHER_AUTH = "Minimum authentication level to access Weather Widget"

+ 13 - 1
lang/fr.ini

@@ -124,7 +124,7 @@ SIDE_BY_SIDE = "Vue côte à côte"
 SIDE_BY_SIDE_ABOUT = "Pour ceux qui sont multi-tâches, nous avons configuré un moyen facile pour vous de travailler sur deux choses à la fois. Pour commencer, voici les bases:"
 SIDE_BY_SIDE_INSTRUCTIONS1 = "Cliquez avec le bouton droit de la souris sur n’importe quel onglet pour mettre côte à côte."
 SIDE_BY_SIDE_INSTRUCTIONS2 = "Si vous aimeriez rafraîchir le côté droit, cliquez avec le bouton droit de la souris sur cet icône"
-SIDE_BY_SIDE_INSTRUCTIONS3 = "Quand vous avez terminé du côte à côte, utilisez le [esc] + [esc] raccourci clavier listé ci-dessous" 
+SIDE_BY_SIDE_INSTRUCTIONS3 = "Quand vous avez terminé du côte à côte, utilisez le [esc] + [esc] raccourci clavier listé ci-dessous"
 KEYBOARD_SHORTCUTS = "Raccourcis clavier"
 KEYBOARD_SHORTCUTS_ABOUT = "Organizer dispose de certains raccourcis clavier intégrés pour une utilisation encore plus facile.  Ceci est utilisables si Organizr est fixé et non en iFrame."
 KEYBOARD_INSTRUCTIONS1 = "Allé au menu Paramètres"
@@ -333,3 +333,15 @@ COUCH_URL = "Couchpotato URL"
 COUCH_KEY = "Couchpotato API/Key"
 DELETE_CHAT_DATABASE = "Delete Chat Database"
 INSTALLED_THEME = "Installed Theme"
+PLEX_TAB_URL = "Plex Tab URL - i.e. https://domain.com/plex or https://plex.domain.com"
+RECENT_REFRESH = "Recent Items Refresh Rate"
+NOW_PLAYING_REFRESH = "Now Playing Refresh Rate"
+REQUEST_REFRESH = "Requests Refresh Rate"
+COLOR_TEMPLATE = "Color Templates"
+REQUESTED_ONLY = "Show only requests for that user - if Off it will show all requests"
+SIZE = "Size"
+OR_ICON_NAME = "or Icon Name"
+OMBI_URL = "Ombi V3 URL"
+OMBI_KEY = "Ombi V3 API Key"
+ENABLE_WEATHER = "Enable Weather Widget"
+WEATHER_AUTH = "Minimum authentication level to access Weather Widget"

+ 12 - 0
lang/it.ini

@@ -333,3 +333,15 @@ COUCH_URL = "Couchpotato URL"
 COUCH_KEY = "Couchpotato API/Key"
 DELETE_CHAT_DATABASE = "Delete Chat Database"
 INSTALLED_THEME = "Installed Theme"
+PLEX_TAB_URL = "Plex Tab URL - i.e. https://domain.com/plex or https://plex.domain.com"
+RECENT_REFRESH = "Recent Items Refresh Rate"
+NOW_PLAYING_REFRESH = "Now Playing Refresh Rate"
+REQUEST_REFRESH = "Requests Refresh Rate"
+COLOR_TEMPLATE = "Color Templates"
+REQUESTED_ONLY = "Show only requests for that user - if Off it will show all requests"
+SIZE = "Size"
+OR_ICON_NAME = "or Icon Name"
+OMBI_URL = "Ombi V3 URL"
+OMBI_KEY = "Ombi V3 API Key"
+ENABLE_WEATHER = "Enable Weather Widget"
+WEATHER_AUTH = "Minimum authentication level to access Weather Widget"

+ 12 - 0
lang/nl.ini

@@ -333,3 +333,15 @@ COUCH_URL = "Couchpotato URL"
 COUCH_KEY = "Couchpotato API/Key"
 DELETE_CHAT_DATABASE = "Delete Chat Database"
 INSTALLED_THEME = "Installed Theme"
+PLEX_TAB_URL = "Plex Tab URL - i.e. https://domain.com/plex or https://plex.domain.com"
+RECENT_REFRESH = "Recent Items Refresh Rate"
+NOW_PLAYING_REFRESH = "Now Playing Refresh Rate"
+REQUEST_REFRESH = "Requests Refresh Rate"
+COLOR_TEMPLATE = "Color Templates"
+REQUESTED_ONLY = "Show only requests for that user - if Off it will show all requests"
+SIZE = "Size"
+OR_ICON_NAME = "or Icon Name"
+OMBI_URL = "Ombi V3 URL"
+OMBI_KEY = "Ombi V3 API Key"
+ENABLE_WEATHER = "Enable Weather Widget"
+WEATHER_AUTH = "Minimum authentication level to access Weather Widget"

+ 12 - 0
lang/pl.ini

@@ -333,3 +333,15 @@ COUCH_URL = "Couchpotato URL"
 COUCH_KEY = "Couchpotato API/Key"
 DELETE_CHAT_DATABASE = "Delete Chat Database"
 INSTALLED_THEME = "Installed Theme"
+PLEX_TAB_URL = "Plex Tab URL - i.e. https://domain.com/plex or https://plex.domain.com"
+RECENT_REFRESH = "Recent Items Refresh Rate"
+NOW_PLAYING_REFRESH = "Now Playing Refresh Rate"
+REQUEST_REFRESH = "Requests Refresh Rate"
+COLOR_TEMPLATE = "Color Templates"
+REQUESTED_ONLY = "Show only requests for that user - if Off it will show all requests"
+SIZE = "Size"
+OR_ICON_NAME = "or Icon Name"
+OMBI_URL = "Ombi V3 URL"
+OMBI_KEY = "Ombi V3 API Key"
+ENABLE_WEATHER = "Enable Weather Widget"
+WEATHER_AUTH = "Minimum authentication level to access Weather Widget"

+ 156 - 186
settings.php

@@ -57,44 +57,37 @@ $themeVersion = (!empty(INSTALLEDTHEME) ? explode("-", INSTALLEDTHEME)[1] : null
         <meta name="viewport" content="width=device-width, initial-scale=1.0">
         <meta http-equiv="X-UA-Compatible" content="IE=edge">
         <meta name="msapplication-tap-highlight" content="no" />
-
         <title>Settings</title>
-
         <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css?v=<?php echo INSTALLEDVERSION; ?>">
         <link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.min.css">
         <link rel="stylesheet" href="bower_components/mdi/css/materialdesignicons.min.css">
         <link rel="stylesheet" href="bower_components/metisMenu/dist/metisMenu.min.css">
         <link rel="stylesheet" href="bower_components/Waves/dist/waves.min.css">
         <link rel="stylesheet" href="bower_components/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.css">
-
         <link rel="stylesheet" href="js/selects/cs-select.css">
         <link rel="stylesheet" href="js/selects/cs-skin-elastic.css">
-        <link href="bower_components/iconpick/dist/css/fontawesome-iconpicker.min.css" rel="stylesheet">
+        <link rel="stylesheet" href="bower_components/iconpick/dist/css/fontawesome-iconpicker.min.css">
         <link rel="stylesheet" href="bower_components/google-material-color/dist/palette.css">
         <link rel="stylesheet" href="bower_components/sweetalert/dist/sweetalert.css">
         <link rel="stylesheet" href="bower_components/smoke/dist/css/smoke.min.css">
-
-        <script src="js/menu/modernizr.custom.js"></script>
-        <script type="text/javascript" src="js/sha1.js"></script>
-        <script type="text/javascript" src="js/user.js"></script>
         <link rel="stylesheet" href="bower_components/animate.css/animate.min.css">
         <link rel="stylesheet" href="bower_components/DataTables/media/css/jquery.dataTables.css">
         <link rel="stylesheet" href="bower_components/datatables-tabletools/css/dataTables.tableTools.css">
         <link rel="stylesheet" href="bower_components/numbered/jquery.numberedtextarea.css">
-
         <link rel="stylesheet" href="css/style.css?v=<?php echo INSTALLEDVERSION; ?>">
-        <link rel="stylesheet" href="css/settings.css?v=<?php echo INSTALLEDVERSION; ?>">
         <link rel="stylesheet" href="bower_components/summernote/dist/summernote.css">
-        <link href="css/jquery.filer.css" rel="stylesheet">
-	    <link href="css/jquery.filer-dragdropbox-theme.css" rel="stylesheet">
+        <link rel="stylesheet" href="css/jquery.filer.css">
+	    <link rel="stylesheet" href="css/jquery.filer-dragdropbox-theme.css">
         <link rel="stylesheet" href="bower_components/morris.js/morris.css">
-
+		<link rel="stylesheet" href="css/settings.css?v=<?php echo INSTALLEDVERSION; ?>">
         <!--[if lt IE 9]>
         <script src="bower_components/html5shiv/dist/html5shiv.min.js"></script>
         <script src="bower_components/respondJs/dest/respond.min.js"></script>
         <![endif]-->
-
         <!--Scripts-->
+		<script src="js/menu/modernizr.custom.js"></script>
+        <script src="js/sha1.js"></script>
+        <script src="js/user.js"></script>
         <script src="bower_components/jquery/dist/jquery.min.js"></script>
         <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
         <script src="bower_components/metisMenu/dist/metisMenu.min.js"></script>
@@ -104,26 +97,19 @@ $themeVersion = (!empty(INSTALLEDTHEME) ? explode("-", INSTALLEDTHEME)[1] : null
         <script src="bower_components/slimScroll/jquery.slimscroll.min.js"></script>
         <script src="bower_components/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.js"></script>
         <script src="bower_components/cta/dist/cta.min.js"></script>
-
         <!--Menu-->
         <script src="js/menu/classie.js"></script>
         <script src="bower_components/iconpick/dist/js/fontawesome-iconpicker.js"></script>
-
-
         <!--Selects-->
         <script src="js/selects/selectFx.js"></script>
         <script src="js/jscolor.js"></script>
         <script src="bower_components/sweetalert/dist/sweetalert.min.js"></script>
-
         <script src="bower_components/smoke/dist/js/smoke.min.js"></script>
         <script src="bower_components/numbered/jquery.numberedtextarea.js"></script>
-
         <!--Other-->
         <script src="js/ajax.js?v=<?php echo INSTALLEDVERSION; ?>"></script>
         <script src="bower_components/raphael/raphael-min.js"></script>
         <script src="bower_components/morris.js/morris.min.js"></script>
-
-
         <!--Notification-->
         <script src="js/notifications/notificationFx.js"></script>
 
@@ -137,8 +123,8 @@ $themeVersion = (!empty(INSTALLEDTHEME) ? explode("-", INSTALLEDTHEME)[1] : null
         <script src="bower_components/datatables-tabletools/js/dataTables.tableTools.js"></script>
          <!--Summernote-->
         <script src="bower_components/summernote/dist/summernote.min.js"></script>
-
 		<!--Other-->
+		<script src="js/lazyload.min.js"></script>
 		<script>
 			function addTab() {
 				var idNumber = Math.round(Math.random() * 999999999) + 1000000000;
@@ -166,7 +152,6 @@ $themeVersion = (!empty(INSTALLEDTHEME) ? explode("-", INSTALLEDTHEME)[1] : null
 			function submitTabs(form) {
 				var formData = {};
 				var ids = [];
-
 				$.each($(form).serializeArray(), function(i,v) {
 					var regmatch = /(\w+)\[((?:new-)?\d+)\]/i.exec(v.name);
 					if (regmatch) {
@@ -183,17 +168,19 @@ $themeVersion = (!empty(INSTALLEDTHEME) ? explode("-", INSTALLEDTHEME)[1] : null
 				});
 				console.log(formData);
 				ajax_request('POST', 'submit-tabs', formData);
-
 				return false;
 			}
 		</script>
-
         <style>
             body{
                 background: #273238;
             }
-			.sort-placeholder {
-
+			.tabs-with-bg .dropdown-menu a:hover {
+				color: black !important;
+			}
+			.shadow {
+				-webkit-filter: drop-shadow(0px 0px 0px black);
+				filter: drop-shadow(0px 0px 0px black);
 			}
 			.faded {
 				opacity: .5;
@@ -256,7 +243,6 @@ $themeVersion = (!empty(INSTALLEDTHEME) ? explode("-", INSTALLEDTHEME)[1] : null
                     position: fixed;
                     height:100% !important;
                     margin-top:0;
-
                 }.email-content .email-header, .email-new .email-header{
                     padding: 10px 30px;
                     z-index: 1000;
@@ -356,13 +342,11 @@ $themeVersion = (!empty(INSTALLEDTHEME) ? explode("-", INSTALLEDTHEME)[1] : null
                 border-bottom: 0;
                 border-radius: 5px;
                 top: 3px;
-}<?php customCSS(); ?>
+			}<?php customCSS(); ?>
         </style>
     </head>
-
     <body id="body-settings" class="scroller-body group-<?php echo $group;?>" style="padding: 0; overflow: hidden">
         <div id="main-wrapper" class="main-wrapper">
-
             <!--Content-->
             <div id="content"  style="margin:0 10px; overflow:hidden">
 				<!-- Update -->
@@ -389,7 +373,7 @@ $themeVersion = (!empty(INSTALLEDTHEME) ? explode("-", INSTALLEDTHEME)[1] : null
 				</div>
 				<!-- Check Frame Modal -->
                 <div class="modal fade checkFrame" tabindex="-1" role="dialog">
-                    <div class="modal-dialog modal-lg" role="document">
+                	<div class="modal-dialog modal-lg" role="document">
                         <div class="modal-content">
                             <div class="modal-header">
                                 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
@@ -423,114 +407,108 @@ $themeVersion = (!empty(INSTALLEDTHEME) ? explode("-", INSTALLEDTHEME)[1] : null
 					}else{
 						echo '<div class="col-sm-2">';
 						echo '<button id="apply" style="width: 100%; display: none;" class="btn waves btn-success btn-sm text-uppercase waves-effect waves-float animated tada" type="submit">'.$language->translate("APPLY_CHANGES").'</button>';
-					}?>
-
-
-<?php
-$buildMenu = array(
-	array(
-		'id' => 'open-tabs',
-		'box' => 'tab-box',
-		'name' => 'Edit Tabs',
-		'icon_1' => 'view-list',
-		'icon_2' => 'th-list',
-		'color' => 'red-orange',
-		'color2' => 'palette-Red-A700 bg',
-		'padding' => '2',
-	),
-	array(
-		'id' => 'open-colors',
-		'box' => 'color-box',
-		'name' => 'Edit Colors',
-		'icon_1' => 'format-paint',
-		'icon_2' => 'paint-brush',
-		'color' => 'red',
-		'color2' => 'palette-Indigo-A700 bg',
-		'padding' => '2',
-	),
-	array(
-		'id' => 'open-users',
-		'box' => 'users-box',
-		'name' => 'Manage Users',
-		'icon_1' => 'account-multiple',
-		'icon_2' => 'user',
-		'color' => 'green',
-		'color2' => 'palette-Blue-Grey-700 bg',
-		'padding' => '2',
-    ),
-    array(
-		'id' => 'open-email',
-		'box' => 'email-box',
-		'name' => 'Email Users',
-		'icon_1' => 'email',
-		'icon_2' => 'envelope',
-		'color' => 'yellow',
-		'color2' => 'palette-Pink-A700 bg',
-		'padding' => '2',
-	),
-	array(
-		'id' => 'open-logs',
-		'box' => 'logs-box',
-		'name' => 'View Logs',
-		'icon_1' => 'file-document-box',
-		'icon_2' => 'list-alt',
-		'color' => 'blue',
-		'color2' => 'palette-Teal-A700 bg',
-		'padding' => '2',
-	),
-	array(
-		'id' => 'open-homepage',
-		'box' => 'homepage-box',
-		'name' => 'Edit Homepage',
-		'icon_1' => 'television-guide',
-		'icon_2' => 'home',
-		'color' => 'yellow',
-		'color2' => 'palette-Deep-Orange-A400 bg',
-		'padding' => '2',
-    ),
-	array(
-		'id' => 'open-invites',
-		'box' => 'invites-box',
-		'name' => 'Plex Invites',
-		'icon_1' => 'account-multiple-plus',
-		'icon_2' => 'user-plus',
-		'color' => 'light-blue',
-		'color2' => 'palette-Amber-A700 bg',
-		'padding' => '2',
-	),
-	array(
-		'id' => 'open-advanced',
-		'box' => 'advanced-box',
-		'name' => 'Advanced',
-		'icon_1' => 'settings',
-		'icon_2' => 'cog',
-		'color' => 'gray',
-		'color2' => 'palette-Grey-600 bg',
-		'padding' => '2',
-	),array(
-		'id' => 'open-info',
-		'box' => 'info-box',
-		'name' => 'About',
-		'icon_1' => 'information',
-		'icon_2' => 'info-circle',
-		'color' => 'orange',
-		'color2' => 'palette-Light-Blue-A700 bg',
-		'padding' => '2',
-	),array(
-		'id' => 'open-donate',
-		'box' => 'donate-box',
-		'name' => 'Donate',
-		'icon_1' => 'cash-usd',
-		'icon_2' => 'money',
-		'color' => 'red',
-		'color2' => 'palette-Green-A700 bg',
-		'padding' => '2',
-	),
-);
-if($userDevice !== "phone"){ echo "<br><br><br>".buildMenu($buildMenu); }else{ echo buildMenuPhone($buildMenu); }
-?>
-
-
+					}
+					$buildMenu = array(
+						array(
+							'id' => 'open-tabs',
+							'box' => 'tab-box',
+							'name' => 'Edit Tabs',
+							'icon_1' => 'view-list',
+							'icon_2' => 'th-list',
+							'color' => 'red-orange',
+							'color2' => 'palette-Red-A700 bg',
+							'padding' => '2',
+						),
+						array(
+							'id' => 'open-colors',
+							'box' => 'color-box',
+							'name' => 'Edit Colors',
+							'icon_1' => 'format-paint',
+							'icon_2' => 'paint-brush',
+							'color' => 'red',
+							'color2' => 'palette-Indigo-A700 bg',
+							'padding' => '2',
+						),
+						array(
+							'id' => 'open-users',
+							'box' => 'users-box',
+							'name' => 'Manage Users',
+							'icon_1' => 'account-multiple',
+							'icon_2' => 'user',
+							'color' => 'green',
+							'color2' => 'palette-Blue-Grey-700 bg',
+							'padding' => '2',
+					    ),
+					    array(
+							'id' => 'open-email',
+							'box' => 'email-box',
+							'name' => 'Email Users',
+							'icon_1' => 'email',
+							'icon_2' => 'envelope',
+							'color' => 'yellow',
+							'color2' => 'palette-Pink-A700 bg',
+							'padding' => '2',
+						),
+						array(
+							'id' => 'open-logs',
+							'box' => 'logs-box',
+							'name' => 'View Logs',
+							'icon_1' => 'file-document-box',
+							'icon_2' => 'list-alt',
+							'color' => 'blue',
+							'color2' => 'palette-Teal-A700 bg',
+							'padding' => '2',
+						),
+						array(
+							'id' => 'open-homepage',
+							'box' => 'homepage-box',
+							'name' => 'Edit Homepage',
+							'icon_1' => 'television-guide',
+							'icon_2' => 'home',
+							'color' => 'yellow',
+							'color2' => 'palette-Deep-Orange-A400 bg',
+							'padding' => '2',
+					    ),
+						array(
+							'id' => 'open-invites',
+							'box' => 'invites-box',
+							'name' => 'Plex Invites',
+							'icon_1' => 'account-multiple-plus',
+							'icon_2' => 'user-plus',
+							'color' => 'light-blue',
+							'color2' => 'palette-Amber-A700 bg',
+							'padding' => '2',
+						),
+						array(
+							'id' => 'open-advanced',
+							'box' => 'advanced-box',
+							'name' => 'Advanced',
+							'icon_1' => 'settings',
+							'icon_2' => 'cog',
+							'color' => 'gray',
+							'color2' => 'palette-Grey-600 bg',
+							'padding' => '2',
+						),array(
+							'id' => 'open-info',
+							'box' => 'info-box',
+							'name' => 'About',
+							'icon_1' => 'information',
+							'icon_2' => 'info-circle',
+							'color' => 'orange',
+							'color2' => 'palette-Light-Blue-A700 bg',
+							'padding' => '2',
+						),array(
+							'id' => 'open-donate',
+							'box' => 'donate-box',
+							'name' => 'Donate',
+							'icon_1' => 'cash-usd',
+							'icon_2' => 'money',
+							'color' => 'red',
+							'color2' => 'palette-Green-A700 bg',
+							'padding' => '2',
+						),
+					);
+					if($userDevice !== "phone"){ echo "<br><br><br>".buildMenu($buildMenu); }else{ echo buildMenuPhone($buildMenu); }?>
                     </div>
 					<?php if($userDevice !== "phone"){?>
                     <div class="col-lg-10" style="position: absolute;top: 50%;left: 10%;width: 80%;">
@@ -543,8 +521,8 @@ if($userDevice !== "phone"){ echo "<br><br><br>".buildMenu($buildMenu); }else{ e
                         <div class="email-header gray-bg">
                             <button type="button" class="btn btn-danger btn-sm waves close-button"><i class="fa fa-close"></i></button>
                             <button type="button" class="btn waves btn-labeled btn-success btn btn-sm text-uppercase waves-effect waves-float save-btn-form submitTabBtn">
-												<span class="btn-label"><i class="fa fa-floppy-o"></i></span><?php echo translate('SAVE_TABS'); ?>
-											</button>
+								<span class="btn-label"><i class="fa fa-floppy-o"></i></span><?php echo translate('SAVE_TABS'); ?>
+							</button>
                             <h1>Edit Tabs</h1>
                         </div>
                         <div class="email-inner small-box">
@@ -573,37 +551,23 @@ if($userDevice !== "phone"){ echo "<br><br><br>".buildMenu($buildMenu); }else{ e
 											<h4><strong><?php echo $language->translate("ALL_ICONS");?></strong> [<?php echo $language->translate("CLICK_ICON");?>]</h4>
 											<div class="row">
 												<textarea id="copyTarget" class="hideCopy" style="left: -9999px; top: 0; position: absolute;"></textarea>
-<?php
-$dirname = "images/";
-$images = scandir($dirname);
-$ignore = Array(".", "..", "favicon", "settings", "cache", "platforms", "._.DS_Store", ".DS_Store", "confused.png", "sowwy.png", "sort-btns", "loading.png", "titlelogo.png", "default.svg", "login.png", "no-np.png", "no-list.png", "no-np.psd", "no-list.psd", "themes", "nadaplaying.jpg", "organizr-logo-h-d.png", "organizr-logo-h.png");
-foreach($images as $curimg){
-	if(!in_array($curimg, $ignore)) { ?>
-												<div class="col-xs-2" style="width: 75px; height: 75px; padding-right: 0px;">
-													<a data-toggle="tooltip" data-placement="bottom" title="<?=$dirname.$curimg;?>" class="thumbnail" style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);">
-														<img style="width: 50px; height: 50px;" src="<?=$dirname.$curimg;?>" alt="thumbnail" class="allIcons">
-													</a>
-												</div>
-<?php
-	}
-}
-?>
+												<?php echo loadIcons();?>
 											</div>
 										</div>
 										<div class="panel">
                                             <div class="panel-body todo">
                                                 <ul class="list-group ui-sortable">
-<?php
-foreach($file_db->query('SELECT * FROM tabs ORDER BY `order` asc') as $key => $row) {
-	if (!isset($row['id'])) { $row['id'] = $key + 1; }
-	echo printTabRow($row);
-}
-?>
+													<?php
+													foreach($file_db->query('SELECT * FROM tabs ORDER BY `order` asc') as $key => $row) {
+														if (!isset($row['id'])) { $row['id'] = $key + 1; }
+														echo printTabRow($row);
+													}
+													?>
                                                 </ul>
                                             </div>
 										</div>
 									</form>
-<?php echo printTabRow(false); ?>
+									<?php echo printTabRow(false); ?>
                                 </div>
                             </div>
                         </div>
@@ -626,38 +590,37 @@ echo buildSettings(
 					array(
 						array(
 							'type' => 'button',
-							'labelTranslate' => 'CHOOSE_THEME',
+							'labelTranslate' => 'COLOR_TEMPLATE',
 							'icon' => 'css3',
 							'id' => 'themeSelector',
 							'buttonType' => 'dark',
 							'buttonDrop' => '
-		<ul class="dropdown-menu gray-bg">
-			<li class="chooseTheme" id="plexTheme" style="border: 1px #FFFFFF; border-style: groove; background: #000000; border-radius: 5px; margin: 5px;"><a style="color: #E49F0C !important;" href="#">Plex<span><img class="themeImage" src="images/themes/plex.png"></span></a></li>
-			<li class="chooseTheme" id="newPlexTheme" style="border: 1px #E5A00D; border-style: groove; background: #282A2D; border-radius: 5px; margin: 5px;"><a style="color: #E5A00D !important;" href="#">New Plex<span><img class="themeImage" src="images/themes/newplex.png"></span></a></li>
-			<li class="chooseTheme" id="embyTheme" style="border: 1px #FFFFFF; border-style: groove; background: #212121; border-radius: 5px; margin: 5px;"><a style="color: #52B54B !important;" href="#">Emby<span><img class="themeImage" src="images/themes/emby.png"></span></a></li>
-			<li class="chooseTheme" id="bookTheme" style="border: 1px #FFFFFF; border-style: groove; background: #3B5998; border-radius: 5px; margin: 5px;"><a style="color: #FFFFFF !important;" href="#">Facebook<span><img class="themeImage" src="images/themes/facebook.png"></span></a></li>
-			<li class="chooseTheme" id="spaTheme" style="border: 1px #66BBAE; border-style: groove; background: #66BBAE; border-radius: 5px; margin: 5px;"><a style="color: #5B391E !important;" href="#">Spa<span><img class="themeImage" src="images/themes/spa.png"></span></a></li>
-			<li class="chooseTheme" id="darklyTheme" style="border: 1px #464545; border-style: groove; background: #375A7F; border-radius: 5px; margin: 5px;"><a style="color: #FFFFFF !important;" href="#">Darkly<span><img class="themeImage" src="images/themes/darkly.png"></span></a></li>
-			<li class="chooseTheme" id="slateTheme" style="border: 1px #58C0DE; border-style: groove; background: #272B30; border-radius: 5px; margin: 5px;"><a style="color: #C8C8C8 !important;" href="#">Slate<span><img class="themeImage" src="images/themes/slate.png"></span></a></li>
-			<li class="chooseTheme" id="monokaiTheme" style="border: 1px #AD80FD; border-style: groove; background: #333333; border-radius: 5px; margin: 5px;"><a style="color: #66D9EF !important;" href="#">Monokai<span><img class="themeImage" src="images/themes/monokai.png"></span></a></li>
-			<li class="chooseTheme" id="thejokerTheme" style="border: 1px #CCC6CC; border-style: groove; background: #000000; border-radius: 5px; margin: 5px;"><a style="color: #CCCCCC !important;" href="#">The Joker<span><img class="themeImage" src="images/themes/joker.png"></span></a></li>
-			<li class="chooseTheme" id="redTheme" style="border: 1px #eb6363; border-style: groove; background: #eb6363; border-radius: 5px; margin: 5px;"><a style="color: #FFFFFF !important;" href="#">Original Red<span><img class="themeImage" src="images/themes/original.png"></span></a></li>
-		</ul>
+							<ul class="dropdown-menu gray-bg">
+								<li class="chooseTheme" id="plexTheme" style="border: 1px #FFFFFF; border-style: groove; background: #000000; border-radius: 5px; margin: 5px;"><a style="color: #E49F0C !important;" href="#">Plex<span><img class="themeImage" src="images/themes/plex.png"></span></a></li>
+								<li class="chooseTheme" id="newPlexTheme" style="border: 1px #E5A00D; border-style: groove; background: #282A2D; border-radius: 5px; margin: 5px;"><a style="color: #E5A00D !important;" href="#">New Plex<span><img class="themeImage" src="images/themes/newplex.png"></span></a></li>
+								<li class="chooseTheme" id="embyTheme" style="border: 1px #FFFFFF; border-style: groove; background: #212121; border-radius: 5px; margin: 5px;"><a style="color: #52B54B !important;" href="#">Emby<span><img class="themeImage" src="images/themes/emby.png"></span></a></li>
+								<li class="chooseTheme" id="bookTheme" style="border: 1px #FFFFFF; border-style: groove; background: #3B5998; border-radius: 5px; margin: 5px;"><a style="color: #FFFFFF !important;" href="#">Facebook<span><img class="themeImage" src="images/themes/facebook.png"></span></a></li>
+								<li class="chooseTheme" id="spaTheme" style="border: 1px #66BBAE; border-style: groove; background: #66BBAE; border-radius: 5px; margin: 5px;"><a style="color: #5B391E !important;" href="#">Spa<span><img class="themeImage" src="images/themes/spa.png"></span></a></li>
+								<li class="chooseTheme" id="darklyTheme" style="border: 1px #464545; border-style: groove; background: #375A7F; border-radius: 5px; margin: 5px;"><a style="color: #FFFFFF !important;" href="#">Darkly<span><img class="themeImage" src="images/themes/darkly.png"></span></a></li>
+								<li class="chooseTheme" id="slateTheme" style="border: 1px #58C0DE; border-style: groove; background: #272B30; border-radius: 5px; margin: 5px;"><a style="color: #C8C8C8 !important;" href="#">Slate<span><img class="themeImage" src="images/themes/slate.png"></span></a></li>
+								<li class="chooseTheme" id="monokaiTheme" style="border: 1px #AD80FD; border-style: groove; background: #333333; border-radius: 5px; margin: 5px;"><a style="color: #66D9EF !important;" href="#">Monokai<span><img class="themeImage" src="images/themes/monokai.png"></span></a></li>
+								<li class="chooseTheme" id="thejokerTheme" style="border: 1px #CCC6CC; border-style: groove; background: #000000; border-radius: 5px; margin: 5px;"><a style="color: #CCCCCC !important;" href="#">The Joker<span><img class="themeImage" src="images/themes/joker.png"></span></a></li>
+								<li class="chooseTheme" id="redTheme" style="border: 1px #eb6363; border-style: groove; background: #eb6363; border-radius: 5px; margin: 5px;"><a style="color: #FFFFFF !important;" href="#">Original Red<span><img class="themeImage" src="images/themes/original.png"></span></a></li>
+							</ul>
 							',
                         ),
                         array(
 							'type' => 'button',
-							'label' => 'LAYER#CAKE',
+							'labelTranslate' => 'CHOOSE_THEME',
 							'icon' => 'birthday-cake',
 							'id' => 'layerCake',
 							'buttonType' => 'dark',
 							'buttonDrop' => '
-        <ul class="dropdown-menu gray-bg">
-        <p class="text-center">Powered by Leram</p>
-			<li id="layerCakeDefault" data-toggle="tooltip" data-placement="top" title="" data-original-title="A 7 color theme based on Organizr" style="border: 1px #FFFFFF; border-style: groove; background: #000000; border-radius: 5px; margin: 5px;"><a style="color: #E49F0C !important;" onclick="layerCake(\'Basic\',\'layerCake\');$(\'#customCSS_id\').attr(\'data-changed\', \'true\');" href="#">Basic</a></li>
-			<li id="layerCakeCustom" data-toggle="tooltip" data-placement="top" title="" data-original-title="A 32 color theme based on Organizr" style="border: 1px #E5A00D; border-style: groove; background: #282A2D; border-radius: 5px; margin: 5px;"><a style="color: #E5A00D !important;" onclick="layerCake(\'Advanced\',\'layerCake\');$(\'#customCSS_id\').attr(\'data-changed\', \'true\');" href="#">Advanced</a></li>
-			<li id="open-themes" box="themes-box" onclick"" data-toggle="tooltip" data-placement="top" title="" data-original-title="Custom Themes Created by The Community" style="border: 1px #E5A00D; border-style: groove; background: #282A2D; border-radius: 5px; margin: 5px;"><a style="color: #E5A00D !important;" onclick="" href="#">Themes</a></li>
-		</ul>
+							<ul class="dropdown-menu">
+								<li id="open-themes" box="themes-box" onclick"" data-toggle="tooltip" data-placement="top" title="" data-original-title="Custom Themes Created by The Community"><a onclick="" href="#">Themes</a></li>
+								<li id="layerCakeDefault" data-toggle="tooltip" data-placement="top" title="" data-original-title="A 7 color theme based on Organizr"><a onclick="layerCake(\'Basic\',\'layerCake\');$(\'#customCSS_id\').attr(\'data-changed\', \'true\');" href="#">LAYER#CAKE Basic</a></li>
+								<li id="layerCakeCustom" data-toggle="tooltip" data-placement="top" title="" data-original-title="A 32 color theme based on Organizr"><a onclick="layerCake(\'Advanced\',\'layerCake\');$(\'#customCSS_id\').attr(\'data-changed\', \'true\');" href="#">LAYER#CAKE Advanced</a></li>
+							</ul>
 							',
 						),
 					),
@@ -1586,9 +1549,15 @@ echo buildSettings(
 						'value' => REQUESTREFRESH,
 						'options' => $refreshSeconds,
 					),
+                    array(
+						'type' => 'checkbox',
+						'labelTranslate' => 'REQUESTED_ONLY',
+						'name' => 'requestedUserOnly',
+						'value' => REQUESTEDUSERONLY,
+					),
 					array(
 						'type' => 'custom',
-						'html' => '<h2>Requires Ombi V3.0.2151 & Above</h2>',
+						'html' => '<h2>Requires Ombi V3.0.2165 & Above</h2>',
 					),
 				),
 			),
@@ -2184,7 +2153,7 @@ echo buildSettings(
                     <div class="email-body">
                         <div class="email-header gray-bg">
                             <button type="button" class="btn btn-danger btn-sm waves close-button"><i class="fa fa-close"></i></button>
-                            <h1>layer.Cake Themes</h1>
+                            <h1>Themes</h1>
                         </div>
                         <div class="email-inner small-box">
                             <div class="email-inner-section">
@@ -3102,6 +3071,7 @@ echo buildSettings(
         <?php endif; ?>
 
 		<script>
+		lazyload();
 			<?php echo speedTestDisplay(speedTestData(),"graph");?>
 			$(".settingsMenu").click(function() {
 				$(".settingsMenu").removeClass("settingsMenuActive");

+ 44 - 21
user.php

@@ -281,6 +281,14 @@
 			$email = $_POST["email"];
 			$sha1 = $_POST["sha1"];
 			$settings = $_POST["settings"];
+			$validate = (isset($_POST["validate"])) ? $_POST["validate"] : null;
+			if(REGISTERPASSWORD != ""){
+				if($validate == REGISTERPASSWORD){
+					$validate = true;
+				}
+			}else{
+				$validate = null;
+			}
 			// step 1: someone could have bypassed the javascript validation, so validate again.
 			if(!$this->validate_user_name($username)) {
 				$this->info("<strong>registration error:</strong> user name did not pass validation");
@@ -292,25 +300,7 @@
 				$this->info("<strong>registration error:</strong> password did not pass validation");
 				return false; }
 			// step 2: if validation passed, register user
-			$registered = $this->register_user($username, $email, $sha1, $registration_callback, $settings);
-			if($registered && User::use_mail)
-			{
-				// send email notification
-				$subject = "Welcome to ".DOMAIN;
-				$language = new setLanguage;
-				$domain = getServerPath();
-				$body = orgEmail(
-					$header = $language->translate('EMAIL_NEWUSER_HEADER'),
-					$title = $language->translate('EMAIL_NEWUSER_TITLE'),
-					$user = $username,
-					$mainMessage =$language->translate('EMAIL_NEWUSER_MESSAGE'),
-					$button = $language->translate('EMAIL_NEWUSER_BUTTON'),
-					$buttonURL = $domain,
-					$subTitle = $language->translate('EMAIL_NEWUSER_SUBTITLE'),
-					$subMessage = $language->translate('EMAIL_NEWUSER_SUBMESSAGE')
-					);
-                $this->startEmail($email, $username, $subject, $body);
-			}
+			$registered = $this->register_user($username, $email, $sha1, $registration_callback, $settings, $validate);
 			return $registered;
 		}
 		/**
@@ -543,7 +533,7 @@
 		 * is profile information that can be set, but in no way
 		 * needs to be, in the user's profile section
 		 */
-		function register_user($username, $email, $sha1, &$registration_callback = false, $settings) {
+		function register_user($username, $email, $sha1, &$registration_callback = false, $settings, $validate) {
 			$username = strtolower($username);
 			$dbpassword = $this->token_hash_password($username, $sha1, "");
 			if($dbpassword==$sha1) die("password hashing is not implemented.");
@@ -552,6 +542,30 @@
             foreach($this->database->query($queryAdmin) as $data) {
                 $newRole = "user";
             }
+			if($newRole == "user" && $validate == null){
+				writeLog("error", "$username on IP ".$_SERVER['REMOTE_ADDR']." is trying to hack your Organizr");
+				$this->error = "Hack attempt has been made. What are you doing? Logging your IP now...?";
+				$this->error("Hack attempt has been made. What are you doing? Logging your IP now...");
+				return false;
+			}
+			if($username && User::use_mail)
+			{
+				// send email notification
+				$subject = "Welcome to ".DOMAIN;
+				$language = new setLanguage;
+				$domain = getServerPath();
+				$body = orgEmail(
+					$header = $language->translate('EMAIL_NEWUSER_HEADER'),
+					$title = $language->translate('EMAIL_NEWUSER_TITLE'),
+					$user = $username,
+					$mainMessage =$language->translate('EMAIL_NEWUSER_MESSAGE'),
+					$button = $language->translate('EMAIL_NEWUSER_BUTTON'),
+					$buttonURL = $domain,
+					$subTitle = $language->translate('EMAIL_NEWUSER_SUBTITLE'),
+					$subMessage = $language->translate('EMAIL_NEWUSER_SUBMESSAGE')
+					);
+                $this->startEmail($email, $username, $subject, $body);
+			}
 			// Does user already exist? (see notes on safe reporting)
 			if(User::unsafe_reporting) {
 				$query = "SELECT username FROM users WHERE username LIKE '$username' COLLATE NOCASE";
@@ -695,7 +709,7 @@
 				} else if (AUTHBACKENDCREATE !== 'false' && $surface) {
 					// Create User
 					$falseByRef = false;
-					$this->register_user($username, (is_array($authSuccess) && isset($authSuccess['email']) ? $authSuccess['email'] : ''), $sha1, $falseByRef, !$remember);
+					$this->register_user($username, (is_array($authSuccess) && isset($authSuccess['email']) ? $authSuccess['email'] : ''), $sha1, $falseByRef, !$remember, true);
 				} else {
 					// authentication failed
 					//$this->info("Successful Backend Auth, No User in DB, Create Set to False");
@@ -729,6 +743,15 @@
 		 */
 		function update_user($username, $email, $sha1, $role)
 		{
+			// logged in, but do the tokens match?
+			$token = $this->get_user_token($username);
+			writeLog("success", "$username has requested info update using token: $token");
+			if($token != $_SESSION["token"]) {
+				$this->error("token mismatch for $username");
+				return false;
+			}else{
+				writeLog("success", "$username token has been validated");
+			}
 			if($email !="") {
 				$update = "UPDATE users SET email = '$email' WHERE username = '$username' COLLATE NOCASE";
 				$this->database->exec($update); }