'.$trace['file'].':'.$trace['line']."\n\n".print_r($variable, true).'';
if ($die) { http_response_code(503); die(); }
}
// ==== 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 ($bind = ldap_bind($ldap, AUTHBACKENDDOMAIN.'\\'.$username, $password)) {
writeLog("success", "LDAP authentication success");
return true;
} else {
writeLog("error", "LDPA could not authenticate");
return false;
}
writeLog("error", "LDPA 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
if ((strtolower(PLEXUSERNAME) == strtolower($username)) && $password == PLEXPASSWORD) {
writeLog("success", $username." authenticated by plex");
return true;
}
//Get User List
$userURL = 'https://plex.tv/pms/friends/all';
$userHeaders = array(
'Authorization' => 'Basic '.base64_encode(PLEXUSERNAME.':'.PLEXPASSWORD),
);
$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) {
$isUser = true;
writeLog("success", $usernameLower." was found in plex friends list");
break;
}
}
if ($isUser) {
//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) {
writeLog("success", $json['user']['username']." was logged into organizr using plex credentials");
return array(
'email' => $json['user']['email'],
'image' => $json['user']['thumb']
);
}
}
}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 ====
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)));
}
$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());
// 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);
// 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());
// 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 = "http://app.emby.media/itemdetails.html?id=".$itemDetails['Id'];
switch ($itemDetails['Type']) {
case 'Episode':
$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";
}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 = '
'.$title.' - '.$itemDetails['Name'].'
';
$bottomTitle = 'S'.$itemDetails['ParentIndexNumber'].' · E'.$itemDetails['IndexNumber'].'';
if($showNames == "true"){ $bottomTitle .= ''.$user.''; }
}
break;
case 'MusicAlbum':
case 'Audio':
$title = $itemDetails['Name'];
$imageId = $itemDetails['Id'];
$width = 444;
$style = '';
$image = 'slick-image-short';
if(!$nowPlaying){
$imageType = (isset($itemDetails['ImageTags']['Primary']) ? "Primary" : false);
$key = $itemDetails['Id'] . "-list";
}else{
$height = 281;
$width = 500;
$imageId = (isset($itemDetails['ParentBackdropItemId']) ? $itemDetails['ParentBackdropItemId'] : false);
$imageType = (isset($itemDetails['ParentBackdropItemId']) ? "Backdrop" : false);
$key = (isset($itemDetails['ParentBackdropItemId']) ? $itemDetails['ParentBackdropItemId'] : "no-np") . "-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),
'audio' => " ".streamType($stream)." ".embyArray($moreInfo['NowPlayingItem']['MediaStreams'], "audio"),
));
$state = (($moreInfo['PlayState']['IsPaused'] == "1") ? "pause" : "play");
$topTitle = ''.$itemDetails['AlbumArtist'].' - '.$itemDetails['Album'].'
';
$bottomTitle = ''.$title.'';
if($showNames == "true"){ $bottomTitle .= ''.$user.''; }
}
break;
case 'TvChannel':
$title = $itemDetails['CurrentProgram']['Name'];
$imageId = $itemDetails['Id'];
$width = 300;
$style = '';
$image = 'slick-image-tall';
if(!$nowPlaying){
$imageType = "Primary";
$key = $itemDetails['Id'] . "-list";
}else{
$height = 281;
$width = 500;
$imageType = "Thumb";
$key = $itemDetails['Id'] . "-np";
$useImage = "images/livetv.png";
$watched = "0";
$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 = ''.$title.'
';
$bottomTitle = ''.$itemDetails['Name'].' - '.$itemDetails['ChannelNumber'].'';
if($showNames == "true"){ $bottomTitle .= ''.$user.''; }
}
break;
default:
$title = $itemDetails['Name'];
$imageId = $itemDetails['Id'];
$width = 300;
$style = '';
$image = 'slick-image-tall';
if(!$nowPlaying){
$imageType = (isset($itemDetails['ImageTags']['Primary']) ? "Primary" : false);
$key = $itemDetails['Id'] . "-list";
}else{
$height = 281;
$width = 500;
$imageType = isset($itemDetails['ImageTags']['Thumb']) ? "Thumb" : (isset($itemDetails['BackdropImageTags']) ? "Backdrop" : false);
$key = $itemDetails['Id'] . "-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 = ''.$title.'
';
$bottomTitle = ''.$moreInfo['NowPlayingItem']['ProductionYear'].'';
if($showNames == "true"){ $bottomTitle .= ''.$user.''; }
}
}
// If No Overview
if (!isset($itemDetails['Overview'])) {
$itemDetails['Overview'] = '';
}
if (file_exists('images/cache/'.$key.'.jpg')){ $image_url = 'images/cache/'.$key.'.jpg'; }
if (file_exists('images/cache/'.$key.'.jpg') && (time() - 604800) > filemtime('images/cache/'.$key.'.jpg') || !file_exists('images/cache/'.$key.'.jpg')) {
$image_url = 'ajax.php?a=emby-image&type='.$imageType.'&img='.$imageId.'&height='.$height.'&width='.$width.'&key='.$key.'';
}
if($nowPlaying){
if(!$imageType){ $image_url = "images/no-np.png"; $key = "no-np"; }
if(!$imageId){ $image_url = "images/no-np.png"; $key = "no-np"; }
}else{
if(!$imageType){ $image_url = "images/no-list.png"; $key = "no-list"; }
if(!$imageId){ $image_url = "images/no-list.png"; $key = "no-list"; }
}
if(isset($useImage)){ $image_url = $useImage; }
// Assemble Item And Cache Into Array
if($nowPlaying){
//prettyPrint($itemDetails);
return '';
}else{
return '
'.$title.' ';
}
}
// Format item from Plex for Carousel
function resolvePlexItem($server, $token, $item, $nowPlaying = false, $showNames = false, $role = false) {
// Static Height
$height = 444;
switch ($item['type']) {
case 'season':
$title = $item['parentTitle'];
$summary = $item['parentSummary'];
$width = 300;
$image = 'slick-image-tall';
$style = '';
if(!$nowPlaying){
$thumb = $item['thumb'];
$key = $item['ratingKey'] . "-list";
}else {
$height = 281;
$width = 500;
$thumb = $item['art'];
$key = $item['ratingKey'] . "-np";
$elapsed = $item['viewOffset'];
$duration = $item['duration'];
$watched = (!empty($elapsed) ? floor(($elapsed / $duration) * 100) : 0);
$transcoded = floor($item->TranscodeSession['progress']- $watched);
$stream = $item->Media->Part->Stream['decision'];
$user = $role == "admin" ? $item->User['title'] : "";
$id = str_replace('"', '', $item->Player['machineIdentifier']);
$streamInfo = buildStream(array(
'platform' => (string) $item->Player['platform'],
'device' => (string) $item->Player['device'],
'stream' => " ".streamType($item->Media->Part['decision']),
'video' => streamType($item->Media->Part->Stream[0]['decision'])." (".$item->Media->Part->Stream[0]['codec'].") (".$item->Media->Part->Stream[0]['width']."x".$item->Media->Part->Stream[0]['height'].")",
'audio' => " ".streamType($item->Media->Part->Stream[1]['decision'])." (".$item->Media->Part->Stream[1]['codec'].") (".$item->Media->Part->Stream[1]['channels']."ch)",
));
$state = (($item->Player['state'] == "paused") ? "pause" : "play");
}
break;
case 'episode':
$title = $item['grandparentTitle'];
$summary = $item['title'];
$width = 300;
$image = 'slick-image-tall';
$style = '';
if(!$nowPlaying){
$thumb = $item['parentThumb'];
$key = $item['ratingKey'] . "-list";
}else {
$height = 281;
$width = 500;
$thumb = $item['art'];
$key = $item['ratingKey'] . "-np";
$elapsed = $item['viewOffset'];
$duration = $item['duration'];
$watched = (!empty($elapsed) ? floor(($elapsed / $duration) * 100) : 0);
$transcoded = floor($item->TranscodeSession['progress']- $watched);
$stream = $item->Media->Part->Stream['decision'];
$user = $role == "admin" ? $item->User['title'] : "";
$id = str_replace('"', '', $item->Player['machineIdentifier']);
$streamInfo = buildStream(array(
'platform' => (string) $item->Player['platform'],
'device' => (string) $item->Player['device'],
'stream' => " ".streamType($item->Media->Part['decision']),
'video' => streamType($item->Media->Part->Stream[0]['decision'])." (".$item->Media->Part->Stream[0]['codec'].") (".$item->Media->Part->Stream[0]['width']."x".$item->Media->Part->Stream[0]['height'].")",
'audio' => " ".streamType($item->Media->Part->Stream[1]['decision'])." (".$item->Media->Part->Stream[1]['codec'].") (".$item->Media->Part->Stream[1]['channels']."ch)",
));
$state = (($item->Player['state'] == "paused") ? "pause" : "play");
$topTitle = ''.$title.' - '.$item['title'].'
';
$bottomTitle = 'S'.$item['parentIndex'].' · E'.$item['index'].'';
if($showNames == "true"){ $bottomTitle .= ''.$user.''; }
}
break;
case 'clip':
$title = $item['title'];
$summary = $item['summary'];
$width = 300;
$image = 'slick-image-tall';
$style = '';
if(!$nowPlaying){
$thumb = $item['thumb'];
$key = $item['ratingKey'] . "-list";
}else {
$height = 281;
$width = 500;
$thumb = $item['art'];
$key = isset($item['ratingKey']) ? $item['ratingKey'] . "-np" : (isset($item['live']) ? "livetv.png" : ":)");
$useImage = (isset($item['live']) ? "images/livetv.png" : null);
$extraInfo = isset($item['extraType']) ? "Trailer" : (isset($item['live']) ? "Live TV" : ":)");
$elapsed = $item['viewOffset'];
$duration = $item['duration'];
$watched = (!empty($elapsed) ? floor(($elapsed / $duration) * 100) : 0);
$transcoded = floor($item->TranscodeSession['progress']- $watched);
$stream = $item->Media->Part->Stream['decision'];
$user = $role == "admin" ? $item->User['title'] : "";
$id = str_replace('"', '', $item->Player['machineIdentifier']);
$streamInfo = buildStream(array(
'platform' => (string) $item->Player['platform'],
'device' => (string) $item->Player['device'],
'stream' => " ".streamType($item->Media->Part['decision']),
'video' => streamType($item->Media->Part->Stream[0]['decision'])." (".$item->Media->Part->Stream[0]['codec'].") (".$item->Media->Part->Stream[0]['width']."x".$item->Media->Part->Stream[0]['height'].")",
'audio' => " ".streamType($item->Media->Part->Stream[1]['decision'])." (".$item->Media->Part->Stream[1]['codec'].") (".$item->Media->Part->Stream[1]['channels']."ch)",
));
$state = (($item->Player['state'] == "paused") ? "pause" : "play");
$topTitle = ''.$title.'
';
$bottomTitle = ''.$extraInfo.'';
if($showNames == "true"){ $bottomTitle .= ''.$user.''; }
}
break;
case 'album':
case 'track':
$title = $item['parentTitle'];
$summary = $item['title'];
$image = 'slick-image-short';
$style = 'left: 160px !important;';
$item['ratingKey'] = $item['parentRatingKey'];
if(!$nowPlaying){
$width = 444;
$thumb = $item['thumb'];
$key = $item['ratingKey'] . "-list";
}else {
$height = 281;
$width = 500;
$thumb = $item['art'];
$key = $item['ratingKey'] . "-np";
$elapsed = $item['viewOffset'];
$duration = $item['duration'];
$watched = (!empty($elapsed) ? floor(($elapsed / $duration) * 100) : 0);
$transcoded = floor($item->TranscodeSession['progress']- $watched);
$stream = $item->Media->Part->Stream['decision'];
$user = $role == "admin" ? $item->User['title'] : "";
$id = str_replace('"', '', $item->Player['machineIdentifier']);
$streamInfo = buildStream(array(
'platform' => (string) $item->Player['platform'],
'device' => (string) $item->Player['device'],
'stream' => " ".streamType($item->Media->Part['decision']),
'audio' => " ".streamType($item->Media->Part->Stream[0]['decision'])." (".$item->Media->Part->Stream[0]['codec'].") (".$item->Media->Part->Stream[0]['channels']."ch)",
));
$state = (($item->Player['state'] == "paused") ? "pause" : "play");
$topTitle = ''.$item['grandparentTitle'].' - '.$item['title'].'
';
$bottomTitle = ''.$title.'';
if($showNames == "true"){ $bottomTitle .= ''.$user.''; }
}
break;
default:
$title = $item['title'];
$summary = $item['summary'];
$image = 'slick-image-tall';
$style = '';
if(!$nowPlaying){
$width = 300;
$thumb = $item['thumb'];
$key = $item['ratingKey'] . "-list";
}else {
$height = 281;
$width = 500;
$thumb = $item['art'];
$key = $item['ratingKey'] . "-np";
$elapsed = $item['viewOffset'];
$duration = $item['duration'];
$watched = (!empty($elapsed) ? floor(($elapsed / $duration) * 100) : 0);
$transcoded = floor($item->TranscodeSession['progress']- $watched);
$stream = $item->Media->Part->Stream['decision'];
$user = $role == "admin" ? $item->User['title'] : "";
$id = str_replace('"', '', $item->Player['machineIdentifier']);
$streamInfo = buildStream(array(
'platform' => (string) $item->Player['platform'],
'device' => (string) $item->Player['device'],
'stream' => " ".streamType($item->Media->Part['decision']),
'video' => streamType($item->Media->Part->Stream[0]['decision'])." (".$item->Media->Part->Stream[0]['codec'].") (".$item->Media->Part->Stream[0]['width']."x".$item->Media->Part->Stream[0]['height'].")",
'audio' => " ".streamType($item->Media->Part->Stream[1]['decision'])." (".$item->Media->Part->Stream[1]['codec'].") (".$item->Media->Part->Stream[1]['channels']."ch)",
));
$state = (($item->Player['state'] == "paused") ? "pause" : "play");
$topTitle = ''.$title.'
';
$bottomTitle = ''.$item['year'].'';
if($showNames == "true"){ $bottomTitle .= ''.$user.''; }
}
}
if (substr_count(PLEXURL, ':') == 2) {
$address = "https://app.plex.tv/web/app#!/server/$server/details?key=/library/metadata/".$item['ratingKey'];
}else{
$address = PLEXURL."/web/index.html#!/server/$server/details?key=/library/metadata/".$item['ratingKey'];
}
// If No Overview
if (!isset($itemDetails['Overview'])) { $itemDetails['Overview'] = ''; }
if (file_exists('images/cache/'.$key.'.jpg')){ $image_url = 'images/cache/'.$key.'.jpg'; }
if (file_exists('images/cache/'.$key.'.jpg') && (time() - 604800) > filemtime('images/cache/'.$key.'.jpg') || !file_exists('images/cache/'.$key.'.jpg')) {
$image_url = 'ajax.php?a=plex-image&img='.$thumb.'&height='.$height.'&width='.$width.'&key='.$key.'';
}
if(!$thumb){ $image_url = "images/no-np.png"; $key = "no-np"; }
if(isset($useImage)){ $image_url = $useImage; }
$openTab = (PLEXTABNAME) ? "true" : "false";
// Assemble Item And Cache Into Array
if($nowPlaying){
return '';
}else{
return '
'.$title.' ';
}
}
//Recent Added
function outputRecentAdded($header, $items, $script = false, $array) {
$hideMenu = '';
// If None Populate Empty Item
if (!count($items)) {
return '';
}else{
return ''.($script?'':'');
}
}
// Create Carousel
function outputNowPlaying($header, $size, $type, $items, $script = false) {
// If None Populate Empty Item
if (!count($items)) {
return ''.($script?'':'');
}else{
return ''.$header.'
'.implode('',$items).''.($script?'':'');
}
}
// Get Now Playing Streams From Emby
function getEmbyStreams($size, $showNames, $role) {
$address = qualifyURL(EMBYURL);
$api = json_decode(@file_get_contents($address.'/Sessions?api_key='.EMBYTOKEN),true);
if (!is_array($api)) { return 'Could not load!'; }
$playingItems = array();
foreach($api as $key => $value) {
if (isset($value['NowPlayingItem'])) {
$playingItems[] = resolveEmbyItem($address, EMBYTOKEN, $value['NowPlayingItem'], true, $showNames, $role, $value);
}
}
return outputNowPlaying(translate('PLAYING_NOW_ON_EMBY'), $size, 'streams-emby', $playingItems, "
setInterval(function() {
$('').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);
});
}, 15000);
");
}
// Get Now Playing Streams From Plex
function getPlexStreams($size, $showNames, $role){
$address = qualifyURL(PLEXURL);
// Perform API requests
$api = @curl_get($address."/status/sessions?X-Plex-Token=".PLEXTOKEN);
$api = simplexml_load_string($api);
if (is_array($api) || is_object($api)){
if (!$api->head->title){
$getServer = simplexml_load_string(@curl_get($address."/?X-Plex-Token=".PLEXTOKEN));
if (!$getServer) { return 'Could not load!'; }
// Identify the local machine
$gotServer = $getServer['machineIdentifier'];
$items = array();
foreach($api AS $child) {
$items[] = resolvePlexItem($gotServer, PLEXTOKEN, $child, true, $showNames, $role);
}
return outputNowPlaying(translate('PLAYING_NOW_ON_PLEX'), $size, 'streams-plex', $items, "
setInterval(function() {
$('').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);
});
}, 15000);
");
}else{
writeLog("error", "PLEX STREAM ERROR: could not connect - check token - if HTTPS, is cert valid");
}
}else{
writeLog("error", "PLEX STREAM ERROR: could not connect - check URL - if HTTPS, is cert valid");
}
}
// Get Recent Content From Emby
function getEmbyRecent($array) {
$address = qualifyURL(EMBYURL);
$header = translate('RECENT_CONTENT');
// Currently Logged In User
$username = false;
if (isset($GLOBALS['USER'])) {
$username = strtolower($GLOBALS['USER']->username);
}
// Get A User
$userIds = json_decode(@file_get_contents($address.'/Users?api_key='.EMBYTOKEN),true);
if (!is_array($userIds)) { return 'Could not load!'; }
$showPlayed = true;
foreach ($userIds as $value) { // Scan for admin user
if (isset($value['Policy']) && isset($value['Policy']['IsAdministrator']) && $value['Policy']['IsAdministrator']) {
$userId = $value['Id'];
}
if ($username && strtolower($value['Name']) == $username) {
$userId = $value['Id'];
$showPlayed = false;
break;
}
}
// 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);
// For Each Item In Category
$items = array();
foreach ($latest as $k => $v) {
$type = (string) $v['Type'];
if(@$array[$type] == "true"){
$items[] = resolveEmbyItem($address, EMBYTOKEN, $v, false, false, false);
}
}
$array["movie"] = $array["Movie"];
$array["season"] = $array["Episode"];
$array["album"] = $array["MusicAlbum"];
unset($array["Movie"]);
unset($array["Episode"]);
unset($array["MusicAlbum"]);
unset($array["Series"]);
return outputRecentAdded($header, $items, "", $array);
}
// Get Recent Content From Plex
function getPlexRecent($array){
$address = qualifyURL(PLEXURL);
$header = translate('RECENT_CONTENT');
// Perform Requests
$api = @curl_get($address."/library/recentlyAdded?limit=".PLEXRECENTITEMS."&X-Plex-Token=".PLEXTOKEN);
$api = simplexml_load_string($api);
if (is_array($api) || is_object($api)){
if (!$api->head->title){
$getServer = simplexml_load_string(@curl_get($address."/?X-Plex-Token=".PLEXTOKEN));
if (!$getServer) { return 'Could not load!'; }
// Identify the local machine
$gotServer = $getServer['machineIdentifier'];
$items = array();
foreach($api AS $child) {
$type = (string) $child['type'];
if($array[$type] == "true"){
$items[] = resolvePlexItem($gotServer, PLEXTOKEN, $child, false, false, false);
}
}
return outputRecentAdded($header, $items, "", $array);
}else{
writeLog("error", "PLEX STREAM ERROR: could not connect - check token - if HTTPS, is cert valid");
}
}else{
writeLog("error", "PLEX STREAM ERROR: could not connect - check URL - if HTTPS, is cert valid");
}
}
// Get Image From Emby
function getEmbyImage() {
$embyAddress = qualifyURL(EMBYURL);
if (!file_exists('images/cache')) {
mkdir('images/cache', 0777, true);
}
$itemId = $_GET['img'];
$key = $_GET['key'];
$itemType = $_GET['type'];
$imgParams = array();
if (isset($_GET['height'])) { $imgParams['height'] = 'maxHeight='.$_GET['height']; }
if (isset($_GET['width'])) { $imgParams['width'] = 'maxWidth='.$_GET['width']; }
if(isset($itemId)) {
$image_src = $embyAddress . '/Items/'.$itemId.'/Images/'.$itemType.'?'.implode('&', $imgParams);
$cachefile = 'images/cache/'.$key.'.jpg';
$cachetime = 604800;
// Serve from the cache if it is younger than $cachetime
if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) {
header("Content-type: image/jpeg");
@readfile($cachefile);
exit;
}
ob_start(); // Start the output buffer
header('Content-type: image/jpeg');
@readfile($image_src);
// Cache the output to a file
$fp = fopen($cachefile, 'wb');
fwrite($fp, ob_get_contents());
fclose($fp);
ob_end_flush(); // Send the output to the browser
die();
} else {
debug_out('Invalid Request',1);
}
}
// Get Image From Plex
function getPlexImage() {
$plexAddress = qualifyURL(PLEXURL);
if (!file_exists('images/cache')) {
mkdir('images/cache', 0777, true);
}
$image_url = $_GET['img'];
$key = $_GET['key'];
$image_height = $_GET['height'];
$image_width = $_GET['width'];
if(isset($image_url) && isset($image_height) && isset($image_width)) {
$image_src = $plexAddress . '/photo/:/transcode?height='.$image_height.'&width='.$image_width.'&upscale=1&url=' . $image_url . '&X-Plex-Token=' . PLEXTOKEN;
$cachefile = 'images/cache/'.$key.'.jpg';
$cachetime = 604800;
// Serve from the cache if it is younger than $cachetime
if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) {
header("Content-type: image/jpeg");
@readfile($cachefile);
exit;
}
ob_start(); // Start the output buffer
header('Content-type: image/jpeg');
@readfile($image_src);
// Cache the output to a file
$fp = fopen($cachefile, 'wb');
fwrite($fp, ob_get_contents());
fclose($fp);
ob_end_flush(); // Send the output to the browser
die();
} else {
echo "Invalid Plex Request";
}
}
// Simplier access to class
function translate($string) {
if (isset($GLOBALS['language'])) {
return $GLOBALS['language']->translate($string);
} else {
return '!Translations Not Loaded!';
}
}
// Generate Random string
function randString($length = 10, $chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ') {
$tmp = '';
for ($i = 0; $i < $length; $i++) {
$tmp .= substr(str_shuffle($chars), 0, 1);
}
return $tmp;
}
// Create config file in the return syntax
function createConfig($array, $path = 'config/config.php', $nest = 0) {
// Define Initial Value
$output = array();
// Sort Items
ksort($array);
// Update the current config version
if (!$nest) {
// Inject Current Version
$output[] = "\t'CONFIG_VERSION' => '".(isset($array['apply_CONFIG_VERSION'])?$array['apply_CONFIG_VERSION']:INSTALLEDVERSION)."'";
}
unset($array['CONFIG_VERSION']);
unset($array['apply_CONFIG_VERSION']);
// Process Settings
foreach ($array as $k => $v) {
$allowCommit = true;
switch (gettype($v)) {
case 'boolean':
$item = ($v?'true':'false');
break;
case 'integer':
case 'double':
case 'integer':
case 'NULL':
$item = $v;
break;
case 'string':
$item = "'".str_replace(array('\\',"'"),array('\\\\',"\'"),$v)."'";
break;
case 'array':
$item = createConfig($v, false, $nest+1);
break;
default:
$allowCommit = false;
}
if($allowCommit) {
$output[] = str_repeat("\t",$nest+1)."'$k' => $item";
}
}
// Build output
$output = (!$nest?" $v) {
$current[$k] = $v;
}
// Return Create
return createConfig($current);
}
// Inject Defaults As Needed
function fillDefaultConfig($array, $path = 'config/configDefaults.php') {
if (is_string($path)) {
$loadedDefaults = loadConfig($path);
} else {
$loadedDefaults = $path;
}
return (is_array($loadedDefaults) ? fillDefaultConfig_recurse($array, $loadedDefaults) : false);
}
// support function for fillDefaultConfig()
function fillDefaultConfig_recurse($current, $defaults) {
foreach($defaults as $k => $v) {
if (!isset($current[$k])) {
$current[$k] = $v;
} else if (is_array($current[$k]) && is_array($v)) {
$current[$k] = fillDefaultConfig_recurse($current[$k], $v);
}
}
return $current;
};
// Define Scalar Variables (nest non-secular with underscores)
function defineConfig($array, $anyCase = true, $nest_prefix = false) {
foreach($array as $k => $v) {
if (is_scalar($v) && !defined($nest_prefix.$k)) {
define($nest_prefix.$k, $v, $anyCase);
} else if (is_array($v)) {
defineConfig($v, $anyCase, $nest_prefix.$k.'_');
}
}
}
// This function exists only because I am lazy
function configLazy($path = 'config/config.php') {
// Load config or default
if (file_exists($path)) {
$config = fillDefaultConfig(loadConfig($path));
} else {
$config = loadConfig('config/configDefaults.php');
}
if (is_array($config)) {
defineConfig($config);
}
return $config;
}
// Qualify URL
function qualifyURL($url) {
//local address?
if(substr($url, 0,1) == "/"){
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
$protocol = "https://";
} else {
$protocol = "http://";
}
$url = $protocol.getServer().$url;
}
// Get Digest
$digest = parse_url($url);
// http/https
if (!isset($digest['scheme'])) {
if (isset($digest['port']) && in_array($digest['port'], array(80,8080,8096,32400,7878,8989,8182,8081,6789))) {
$scheme = 'http';
} else {
$scheme = 'https';
}
} else {
$scheme = $digest['scheme'];
}
// Host
$host = (isset($digest['host'])?$digest['host']:'');
// Port
$port = (isset($digest['port'])?':'.$digest['port']:'');
// Path
$path = (isset($digest['path'])?$digest['path']:'');
// Output
return $scheme.'://'.$host.$port.$path;
}
// Function to be called at top of each to allow upgrading environment as the spec changes
function upgradeCheck() {
// Upgrade to 1.31
if (file_exists('homepageSettings.ini.php')) {
$databaseConfig = parse_ini_file('databaseLocation.ini.php', true);
$homepageConfig = parse_ini_file('homepageSettings.ini.php', true);
$databaseConfig = array_merge($databaseConfig, $homepageConfig);
$databaseData = '; ' . "\r\n";
foreach($databaseConfig as $k => $v) {
if(substr($v, -1) == "/") : $v = rtrim($v, "/"); endif;
$databaseData .= $k . " = \"" . $v . "\"\r\n";
}
write_ini_file($databaseData, 'databaseLocation.ini.php');
unlink('homepageSettings.ini.php');
unset($databaseData);
unset($homepageConfig);
}
// Upgrade to 1.32
if (file_exists('databaseLocation.ini.php')) {
// Load Existing
$config = parse_ini_file('databaseLocation.ini.php', true);
// Refactor
$config['database_Location'] = preg_replace('/\/\/$/','/',$config['databaseLocation'].'/');
$config['user_home'] = $config['database_Location'].'users/';
unset($config['databaseLocation']);
// Turn Off Emby And Plex Recent
$config["embyURL"] = $config["embyURL"].(!empty($config["embyPort"])?':'.$config["embyPort"]:'');
unset($config["embyPort"]);
$config["plexURL"] = $config["plexURL"].(!empty($config["plexPort"])?':'.$config["plexPort"]:'');
unset($config["plexPort"]);
$config["nzbgetURL"] = $config["nzbgetURL"].(!empty($config["nzbgetPort"])?':'.$config["nzbgetPort"]:'');
unset($config["nzbgetPort"]);
$config["sabnzbdURL"] = $config["sabnzbdURL"].(!empty($config["sabnzbdPort"])?':'.$config["sabnzbdPort"]:'');
unset($config["sabnzbdPort"]);
$config["headphonesURL"] = $config["headphonesURL"].(!empty($config["headphonesPort"])?':'.$config["headphonesPort"]:'');
unset($config["headphonesPort"]);
// Write config file
$config['CONFIG_VERSION'] = '1.32';
copy('config/config.php', 'config/config['.date('Y-m-d_H-i-s').'][pre1.32].bak.php');
$createConfigSuccess = createConfig($config);
// Create new config
if ($createConfigSuccess) {
if (file_exists('config/config.php')) {
// Remove Old ini file
unlink('databaseLocation.ini.php');
} else {
debug_out('Something is not right here!');
}
} else {
debug_out('Couldn\'t create updated configuration.' ,1);
}
}
// Upgrade to 1.33
$config = loadConfig();
if (isset($config['database_Location']) && (!isset($config['CONFIG_VERSION']) || $config['CONFIG_VERSION'] < '1.33')) {
// Fix User Directory
$config['database_Location'] = preg_replace('/\/\/$/','/',$config['database_Location'].'/');
$config['user_home'] = $config['database_Location'].'users/';
unset($config['USER_HOME']);
// Backend auth merge
if (isset($config['authBackendPort']) && !isset(parse_url($config['authBackendHost'])['port'])) {
$config['authBackendHost'] .= ':'.$config['authBackendPort'];
}
unset($config['authBackendPort']);
// If auth is being used move it to embyURL as that is now used in auth functions
if ((isset($config['authType']) && $config['authType'] == 'true') && (isset($config['authBackendHost']) && $config['authBackendHost'] == 'true') && (isset($config['authBackend']) && in_array($config['authBackend'], array('emby_all','emby_local','emby_connect')))) {
$config['embyURL'] = $config['authBackendHost'];
}
// Upgrade database to latest version
updateSQLiteDB($config['database_Location'],'1.32');
// Update Version and Commit
$config['apply_CONFIG_VERSION'] = '1.33';
copy('config/config.php', 'config/config['.date('Y-m-d_H-i-s').'][1.32].bak.php');
$createConfigSuccess = createConfig($config);
unset($config);
}
// Upgrade to 1.34
$config = loadConfig();
if (isset($config['database_Location']) && (!isset($config['CONFIG_VERSION']) || $config['CONFIG_VERSION'] < '1.34')) {
// Upgrade database to latest version
updateSQLiteDB($config['database_Location'],'1.33');
// Update Version and Commit
$config['CONFIG_VERSION'] = '1.34';
copy('config/config.php', 'config/config['.date('Y-m-d_H-i-s').'][1.33].bak.php');
$createConfigSuccess = createConfig($config);
unset($config);
}
// Upgrade to 1.40
$config = loadConfig();
if (isset($config['database_Location']) && (!isset($config['CONFIG_VERSION']) || $config['CONFIG_VERSION'] < '1.40')) {
// Upgrade database to latest version
updateSQLiteDB($config['database_Location'],'1.38');
// Update Version and Commit
$config['CONFIG_VERSION'] = '1.40';
copy('config/config.php', 'config/config['.date('Y-m-d_H-i-s').'][1.38].bak.php');
$createConfigSuccess = createConfig($config);
unset($config);
}
return true;
}
// Get OS from server
function getOS(){
if(PHP_SHLIB_SUFFIX == "dll"){
return "win";
}else{
return "nix";
}
}
//Get Error by Server OS
function getError($os, $error){
$ini = (!empty(php_ini_loaded_file()) ? php_ini_loaded_file() : "php.ini");
$ext = (!empty(ini_get('extension_dir')) ? "uncomment ;extension_dir = and make sure it says -> extension_dir = '".ini_get('extension_dir')."'" : "uncomment ;extension_dir = and add path to 'ext' to make it like extension_dir = 'C:\nginx\php\ext'");
$errors = array(
'pdo_sqlite' => array(
'win' => 'PDO:SQLite not enabled, uncomment ;extension=php_pdo_sqlite.dll in the file php.ini | '.$ext,
'nix' => 'PDO:SQLite not enabled, PHP7 -> run sudo apt-get install php7.0-sqlite | PHP5 -> run sudo apt-get install php5-sqlite',
),
'sqlite3' => array(
'win' => 'SQLite3 not enabled, uncomment ;extension=php_sqlite3.dll in the file php.ini | uncomment ;sqlite3.extension_dir = and add "ext" to make it sqlite3.extension_dir = ext',
'nix' => 'SQLite3 not enabled, run sudo apt-get install php-sqlite3',
),
'curl' => array(
'win' => 'cURL not enabled, uncomment ;extension=php_curl.dll in the file php.ini | '.$ext,
'nix' => 'cURL not enabled, PHP7 -> sudo apt-get install php-7.0 | PHP5 -> run sudo apt-get install php5-curl',
),
'zip' => array(
'win' => 'PHP Zip not enabled, uncomment ;extension=php_zip.dll in the file php.ini, if that doesn\'t work remove that line',
'nix' => 'PHP Zip not enabled, PHP7 -> run sudo apt-get install php7.0-zip | PHP5 -> run sudo apt-get install php5.6-zip',
),
);
return (isset($errors[$error][$os]) ? $errors[$error][$os] : 'No Error Info Found');
}
// Check if all software dependancies are met
function dependCheck() {
$output = array();
if (!extension_loaded('pdo_sqlite')) { $output[] = getError(getOS(),'pdo_sqlite'); }
if (!extension_loaded('curl')) { $output[] = getError(getOS(),'curl'); }
if (!extension_loaded('zip')) { $output[] = getError(getOS(),'zip'); }
//if (!extension_loaded('sqlite3')) { $output[] = getError(getOS(),'sqlite3'); }
if ($output) {
$output[] = "Please visit here to also check status of necessary components after you fix them: check.php";
debug_out($output,1);
}
return true;
}
// Process file uploads
function uploadFiles($path, $ext_mask = null) {
if (isset($_FILES) && count($_FILES)) {
require_once('class.uploader.php');
$uploader = new Uploader();
$data = $uploader->upload($_FILES['files'], array(
'limit' => 10,
'maxSize' => 10,
'extensions' => $ext_mask,
'required' => false,
'uploadDir' => str_replace('//','/',$path.'/'),
'title' => array('name'),
'removeFiles' => true,
'replace' => true,
));
if($data['isComplete']){
$files = $data['data'];
writeLog("success", $files['metas'][0]['name']." was uploaded");
echo json_encode($files['metas'][0]['name']);
}
if($data['hasErrors']){
$errors = $data['errors'];
writeLog("error", $files['metas'][0]['name']." was not able to upload");
echo json_encode($errors);
}
} else {
writeLog("error", "image was not uploaded");
echo json_encode('No files submitted!');
}
}
// Remove file
function removeFiles($path) {
if(is_file($path)) {
writeLog("success", "image was removed");
unlink($path);
} else {
writeLog("error", "image was not removed");
echo json_encode('No file specified for removal!');
}
}
// Lazy select options
function resolveSelectOptions($array, $selected = '', $multi = false) {
$output = array();
$selectedArr = ($multi?explode('|', $selected):array());
foreach ($array as $key => $value) {
if (is_array($value)) {
if (isset($value['optgroup'])) {
$output[] = '