homepageOrdercustomhtml, "homepageOrdernotice" => homepageOrdernotice, "homepageOrderplexsearch" => homepageOrderplexsearch, "homepageOrderspeedtest" => homepageOrderspeedtest, "homepageOrdernzbget" => homepageOrdernzbget, "homepageOrdersabnzbd" => homepageOrdersabnzbd, "homepageOrderplexnowplaying" => homepageOrderplexnowplaying, "homepageOrderplexrecent" => homepageOrderplexrecent, "homepageOrderplexplaylist" => homepageOrderplexplaylist, "homepageOrderembynowplaying" => homepageOrderembynowplaying, "homepageOrderembyrecent" => homepageOrderembyrecent, "homepageOrderombi" => homepageOrderombi, "homepageOrdercalendar" => homepageOrdercalendar, "homepageOrdernoticeguest" => homepageOrdernoticeguest, "homepageOrdertransmisson" => homepageOrdertransmisson, ); asort($homepageOrder); return $homepageOrder; } // Debugging output functions function debug_out($variable, $die = false) { $trace = debug_backtrace()[0]; echo "

'.$trace['file'].':'.$trace['line']."\n\n".print_r($variable, true).''; if ($die) { http_response_code(503); die(); } } //Cookie Function function coookie($type, $name, $value = '', $days = -1, $http = true){ if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == "https"){ $Secure = true; $HTTPOnly = true; }elseif (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') { $Secure = true; $HTTPOnly = true; } else { $Secure = false; $HTTPOnly = false; } if(!$http){ $HTTPOnly = false; } $Path = '/'; $Domain = $_SERVER['HTTP_HOST']; $Port = strpos($Domain, ':'); if ($Port !== false) $Domain = substr($Domain, 0, $Port); $Port = strpos($Domain, ':'); $check = substr_count($Domain, '.'); if($check >= 3){ if(is_numeric($Domain[0])){ $Domain = ''; }else{ $Domain = '.'.explode('.',$Domain)[1].'.'.explode('.',$Domain)[2].'.'.explode('.',$Domain)[3]; } }elseif($check == 2){ $Domain = '.'.explode('.',$Domain)[1].'.'.explode('.',$Domain)[2]; }elseif($check == 1){ $Domain = '.' . $Domain; }else{ $Domain = ''; } if($type = 'set'){ $_COOKIE[$name] = $value; header('Set-Cookie: ' . rawurlencode($name) . '=' . rawurlencode($value) . (empty($days) ? '' : '; expires=' . gmdate('D, d-M-Y H:i:s', time() + (86400 * $days)) . ' GMT') . (empty($Path) ? '' : '; path=' . $Path) . (empty($Domain) ? '' : '; domain=' . $Domain) . (!$Secure ? '' : '; secure') . (!$HTTPOnly ? '' : '; HttpOnly'), false); }elseif($type = 'delete'){ unset($_COOKIE[$name]); header('Set-Cookie: ' . rawurlencode($name) . '=' . rawurlencode($value) . (empty($days) ? '' : '; expires=' . gmdate('D, d-M-Y H:i:s', time() - 3600) . ' GMT') . (empty($Path) ? '' : '; path=' . $Path) . (empty($Domain) ? '' : '; domain=' . $Domain) . (!$Secure ? '' : '; secure') . (!$HTTPOnly ? '' : '; HttpOnly'), false); } } // ==== Auth Plugins START ==== if (function_exists('ldap_connect')) : // Pass credentials to LDAP backend function plugin_auth_ldap($username, $password) { $ldapServers = explode(',',AUTHBACKENDHOST); foreach($ldapServers as $key => $value) { // Calculate parts $digest = parse_url(trim($value)); $scheme = strtolower((isset($digest['scheme'])?$digest['scheme']:'ldap')); $host = (isset($digest['host'])?$digest['host']:(isset($digest['path'])?$digest['path']:'')); $port = (isset($digest['port'])?$digest['port']:(strtolower($scheme)=='ldap'?389:636)); // Reassign $ldapServers[$key] = $scheme.'://'.$host.':'.$port; } // returns true or false $ldap = ldap_connect(implode(' ',$ldapServers)); if(empty(AUTHBACKENDDOMAINFORMAT)){ if ($bind = ldap_bind($ldap, AUTHBACKENDDOMAIN.'\\'.$username, $password)) { writeLog("success", "LDAP authentication success"); return true; } else { writeLog("error", "LDAP could not authenticate"); return false; } }else{ ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0); $bind = @ldap_bind($ldap, sprintf(AUTHBACKENDDOMAINFORMAT, $username), $password); if ($bind) { writeLog("success", "LDAP authentication success"); return true; } else { writeLog("error", "LDPA could not authenticate"); return false; } } writeLog("error", "LDAP could not authenticate"); return false; } else : // Ldap Auth Missing Dependancy function plugin_auth_ldap_disabled() { return 'LDAP - Disabled (Dependancy: php-ldap missing!)'; } endif; // Pass credentials to FTP backend function plugin_auth_ftp($username, $password) { // Calculate parts $digest = parse_url(AUTHBACKENDHOST); $scheme = strtolower((isset($digest['scheme'])?$digest['scheme']:(function_exists('ftp_ssl_connect')?'ftps':'ftp'))); $host = (isset($digest['host'])?$digest['host']:(isset($digest['path'])?$digest['path']:'')); $port = (isset($digest['port'])?$digest['port']:21); // Determine Connection Type if ($scheme == 'ftps') { $conn_id = ftp_ssl_connect($host, $port, 20); } elseif ($scheme == 'ftp') { $conn_id = ftp_connect($host, $port, 20); } else { debug_out('Invalid FTP scheme. Use ftp or ftps'); writeLog("error", "invalid FTP scheme"); return false; } // Check if valid FTP connection if ($conn_id) { // Attempt login @$login_result = ftp_login($conn_id, $username, $password); ftp_close($conn_id); // Return Result if ($login_result) { writeLog("success", "$username authenticated"); return true; } else { writeLog("error", "$username could not authenticate"); return false; } } else { return false; } return false; } // Pass credentials to Emby Backend function plugin_auth_emby_local($username, $password) { $embyAddress = qualifyURL(EMBYURL); $headers = array( 'Authorization'=> 'MediaBrowser UserId="e8837bc1-ad67-520e-8cd2-f629e3155721", Client="None", Device="Organizr", DeviceId="xxx", Version="1.0.0.0"', 'Content-Type' => 'application/json', ); $body = array( 'Username' => $username, 'Password' => sha1($password), 'PasswordMd5' => md5($password), ); $response = post_router($embyAddress.'/Users/AuthenticateByName', $body, $headers); if (isset($response['content'])) { $json = json_decode($response['content'], true); if (is_array($json) && isset($json['SessionInfo']) && isset($json['User']) && $json['User']['HasPassword'] == true) { // Login Success - Now Logout Emby Session As We No Longer Need It $headers = array( 'X-Mediabrowser-Token' => $json['AccessToken'], ); $response = post_router($embyAddress.'/Sessions/Logout', array(), $headers); return true; } } return false; } if (function_exists('curl_version')) : // Authenticate Against Emby Local (first) and Emby Connect function plugin_auth_emby_all($username, $password) { $localResult = plugin_auth_emby_local($username, $password); if ($localResult) { return $localResult; } else { return plugin_auth_emby_connect($username, $password); } } // Authenicate against emby connect function plugin_auth_emby_connect($username, $password) { $embyAddress = qualifyURL(EMBYURL); // Get A User $connectId = ''; $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 if ($value['ConnectUserName'] == $username || $value['Name'] == $username) { $connectId = $value['ConnectUserId']; break; } } } if ($connectId) { $connectURL = 'https://connect.emby.media/service/user/authenticate'; $headers = array( 'Accept'=> 'application/json', 'Content-Type' => 'application/x-www-form-urlencoded', ); $body = array( 'nameOrEmail' => $username, 'rawpw' => $password, ); $result = curl_post($connectURL, $body, $headers); if (isset($result['content'])) { $json = json_decode($result['content'], true); if (is_array($json) && isset($json['AccessToken']) && isset($json['User']) && $json['User']['Id'] == $connectId) { return array( 'email' => $json['User']['Email'], 'image' => $json['User']['ImageUrl'], ); } } } } return false; } // Pass credentials to Plex Backend function plugin_auth_plex($username, $password) { // Quick out $isAdmin = false; if ((strtolower(PLEXUSERNAME) == strtolower($username)) && $password == PLEXPASSWORD) { writeLog("success", "Admin: ".$username." authenticated as plex Admin"); $isAdmin = true; } //Get User List $userURL = 'https://plex.tv/pms/friends/all'; $userHeaders = array( 'Authorization' => 'Basic '.base64_encode(PLEXUSERNAME.':'.PLEXPASSWORD), ); libxml_use_internal_errors(true); $userXML = simplexml_load_string(curl_get($userURL, $userHeaders)); if (is_array($userXML) || is_object($userXML)) { $isUser = false; $usernameLower = strtolower($username); foreach($userXML AS $child) { if(isset($child['username']) && strtolower($child['username']) == $usernameLower || isset($child['email']) && strtolower($child['email']) == $usernameLower) { $isUser = true; writeLog("success", $usernameLower." was found in plex friends list"); break; } } if ($isUser || $isAdmin) { //Login User $connectURL = 'https://plex.tv/users/sign_in.json'; $headers = array( 'Accept'=> 'application/json', 'Content-Type' => 'application/x-www-form-urlencoded', 'X-Plex-Product' => 'Organizr', 'X-Plex-Version' => '1.0', 'X-Plex-Client-Identifier' => '01010101-10101010', ); $body = array( 'user[login]' => $username, 'user[password]' => $password, ); $result = curl_post($connectURL, $body, $headers); if (isset($result['content'])) { $json = json_decode($result['content'], true); if ((is_array($json) && isset($json['user']) && isset($json['user']['username'])) && strtolower($json['user']['username']) == $usernameLower || strtolower($json['user']['email']) == $usernameLower) { writeLog("success", $json['user']['username']." was logged into organizr using plex credentials"); return array( 'email' => $json['user']['email'], 'image' => $json['user']['thumb'], 'token' => $json['user']['authToken'], 'type' => $isAdmin ? 'admin' : 'user', ); } }else{ writeLog("error", "error occured while trying to sign $username into plex"); } }else{ writeLog("error", "$username is not an authorized PLEX user or entered invalid password"); } }else{ writeLog("error", "error occured logging into plex might want to check curl.cainfo=/path/to/downloaded/cacert.pem in php.ini"); } return false; } else : // Plex Auth Missing Dependancy function plugin_auth_plex_disabled() { return 'Plex - Disabled (Dependancy: php-curl missing!)'; } // Emby Connect Auth Missing Dependancy function plugin_auth_emby_connect_disabled() { return 'Emby Connect - Disabled (Dependancy: php-curl missing!)'; } // Emby Both Auth Missing Dependancy function plugin_auth_emby_both_disabled() { return 'Emby Both - Disabled (Dependancy: php-curl missing!)'; } endif; // ==== Auth Plugins END ==== // ==== General Class Definitions START ==== $userLanguage = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) : "en"; class setLanguage { private $language = null; private $langCode = null; function __construct($language = false) { // Default if (!$language) { $language = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2) : "en"; } if (!file_exists("lang/{$language}.ini")) { $language = 'en'; } $this->langCode = $language; $this->language = parse_ini_file("lang/{$language}.ini", false, INI_SCANNER_RAW); if (file_exists("lang/{$language}.cust.ini")) { foreach($tmp = parse_ini_file("lang/{$language}.cust.ini", false, INI_SCANNER_RAW) as $k => $v) { $this->language[$k] = $v; } } } public function getLang() { return $this->langCode; } public function translate($originalWord) { $getArg = func_num_args(); if ($getArg > 1) { $allWords = func_get_args(); array_shift($allWords); } else { $allWords = array(); } $translatedWord = isset($this->language[$originalWord]) ? $this->language[$originalWord] : null; if (!$translatedWord) { return ucwords(str_replace("_", " ", strtolower($originalWord))); //echo "WHOA!!!!!!! $originalWord"; } $translatedWord = htmlspecialchars($translatedWord, ENT_QUOTES); return vsprintf($translatedWord, $allWords); } } $language = new setLanguage; // ==== General Class Definitions END ==== // Direct request to curl if it exists, otherwise handle if not HTTPS function post_router($url, $data, $headers = array(), $referer='') { if (function_exists('curl_version')) { return curl_post($url, $data, $headers, $referer); } else { return post_request($url, $data, $headers, $referer); } } if (function_exists('curl_version')) : // Curl Post function curl_post($url, $data, $headers = array(), $referer='') { // Initiate cURL $curlReq = curl_init($url); // As post request curl_setopt($curlReq, CURLOPT_CUSTOMREQUEST, "POST"); 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 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 $curlReq = curl_init($url); // As post request curl_setopt($curlReq, CURLOPT_CUSTOMREQUEST, "GET"); curl_setopt($curlReq, CURLOPT_RETURNTRANSFER, true); curl_setopt($curlReq, CURLOPT_CAINFO, getCert()); curl_setopt($curlReq, CURLOPT_CONNECTTIMEOUT, 5); if(localURL($url)){ curl_setopt($curlReq, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($curlReq, CURLOPT_SSL_VERIFYPEER, 0); } // 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); // Close curl_close($curlReq); // Return return $result; } //Curl Delete Function function curl_delete($url, $headers = array()) { // Initiate cURL $curlReq = curl_init($url); // As post request curl_setopt($curlReq, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_setopt($curlReq, CURLOPT_RETURNTRANSFER, true); curl_setopt($curlReq, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($curlReq, CURLOPT_CAINFO, getCert()); if(localURL($url)){ curl_setopt($curlReq, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($curlReq, CURLOPT_SSL_VERIFYPEER, 0); } // 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); } endif; //Case-Insensitive Function function in_arrayi($needle, $haystack) { return in_array(strtolower($needle), array_map('strtolower', $haystack)); } // HTTP post request (Removes need for curl, probably useless) function post_request($url, $data, $headers = array(), $referer='') { // Adapted from http://stackoverflow.com/a/28387011/6810513 // Convert the data array into URL Parameters like a=b&foo=bar etc. if (isset($headers['Content-Type'])) { switch ($headers['Content-Type']) { case 'application/json': $data = json_encode($data); break; case 'application/x-www-form-urlencoded': $data = http_build_query($data); break; } } else { $headers['Content-Type'] = 'application/x-www-form-urlencoded'; $data = http_build_query($data); } // parse the given URL $urlDigest = parse_url($url); // extract host and path: $host = $urlDigest['host']; $path = $urlDigest['path']; if ($urlDigest['scheme'] != 'http') { die('Error: Only HTTP request are supported, please use cURL to add HTTPS support! ('.$urlDigest['scheme'].'://'.$host.')'); } // open a socket connection on port 80 - timeout: 30 sec $fp = fsockopen($host, (isset($urlDigest['port'])?':'.$urlDigest['port']:80), $errno, $errstr, 30); if ($fp){ // send the request headers: fputs($fp, "POST $path HTTP/1.1\r\n"); fputs($fp, "Host: $host\r\n"); if ($referer != '') fputs($fp, "Referer: $referer\r\n"); fputs($fp, "Content-length: ". strlen($data) ."\r\n"); foreach($headers as $k => $v) { fputs($fp, $k.": ".$v."\r\n"); } fputs($fp, "Connection: close\r\n\r\n"); fputs($fp, $data); $result = ''; while(!feof($fp)) { // receive the results of the request $result .= fgets($fp, 128); } } else { return array( 'status' => 'err', 'error' => "$errstr ($errno)" ); } // close the socket connection: fclose($fp); // split the result header from the content $result = explode("\r\n\r\n", $result, 2); $header = isset($result[0]) ? $result[0] : ''; $content = isset($result[1]) ? $result[1] : ''; // return as structured array: return array( 'status' => 'ok', 'header' => $header, 'content' => $content, ); } // Format item from Emby for Carousel function resolveEmbyItem($address, $token, $item, $nowPlaying = false, $showNames = false, $role = false, $moreInfo = false) { // Static Height $height = 444; // Get Item Details $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{ $URL = EMBYURL."/web/itemdetails.html?id=".$itemDetails['Id']; }*/ $URL = EMBYURL."/web/itemdetails.html?id=".$itemDetails['Id']; switch ($itemDetails['Type']) { case 'Episode': case 'Series': $title = (isset($itemDetails['SeriesName'])?$itemDetails['SeriesName']:""); $imageId = (isset($itemDetails['SeriesId'])?$itemDetails['SeriesId']:$itemDetails['Id']); $width = 300; $style = ''; $image = 'slick-image-tall'; if(!$nowPlaying){ $imageType = (isset($itemDetails['ImageTags']['Primary']) ? "Primary" : false); $key = $itemDetails['Id'] . "-list"; $itemType = 'season'; }else{ $height = 281; $width = 500; $imageId = isset($itemDetails['ParentThumbItemId']) ? $itemDetails['ParentThumbItemId'] : (isset($itemDetails['ParentBackdropItemId']) ? $itemDetails['ParentBackdropItemId'] : false); $imageType = isset($itemDetails['ParentThumbItemId']) ? "Thumb" : (isset($itemDetails['ParentBackdropItemId']) ? "Backdrop" : false); $key = (isset($itemDetails['ParentThumbItemId']) ? $itemDetails['ParentThumbItemId']."-np" : "none-np"); $elapsed = $moreInfo['PlayState']['PositionTicks']; $duration = $moreInfo['NowPlayingItem']['RunTimeTicks']; $watched = (!empty($elapsed) ? floor(($elapsed / $duration) * 100) : 0); //$transcoded = floor($item->TranscodeSession['progress']- $watched); $stream = $moreInfo['PlayState']['PlayMethod']; $user = $role == "admin" ? $moreInfo['UserName'] : ""; $id = $moreInfo['DeviceId']; $streamInfo = buildStream(array( 'platform' => (string) $moreInfo['Client'], 'device' => (string) $moreInfo['DeviceName'], 'stream' => streamType($stream), 'video' => streamType($stream)." ".embyArray($moreInfo['NowPlayingItem']['MediaStreams'], "video"), 'audio' => streamType($stream)." ".embyArray($moreInfo['NowPlayingItem']['MediaStreams'], "audio"), )); $state = (($moreInfo['PlayState']['IsPaused'] == "1") ? "pause" : "play"); $topTitle = '
No Media Found