dbh = false; $this->dbuser = $db_user; $this->dbpassword = $db_pass; $this->dbname = $db_name; $this->dbhost = $host; $this->dbport = $db_port; $this->db_connect(); } public function close_mysql() { if (!$this->connected) { } else { $this->connected = false; $this->dbh = null; } return true; } public function __destruct() { $this->close_mysql(); } public function ping() { try { $this->dbh->query('SELECT 1'); } catch (Exception $e) { return false; } return true; } public function db_connect() { try { $this->dbh = new PDO('mysql:host=' . $this->dbhost . ';port=' . $this->dbport . ';dbname=' . $this->dbname . ';charset=utf8mb4', $this->dbuser, $this->dbpassword); if (!$this->dbh) { exit(json_encode(array('error' => 'MySQL: Cannot connect to database! Please check credentials.'))); } } catch (PDOException $e) { exit(json_encode(array('error' => 'MySQL: ' . $e->getMessage()))); } $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->connected = true; $this->dbh->exec('SET NAMES utf8;'); return true; } public function db_explicit_connect($rHost, $rPort, $rDatabase, $rUsername, $rPassword) { try { $this->dbh = new PDO('mysql:host=' . $rHost . ';port=' . $rPort . ';dbname=' . $rDatabase, $rUsername, $rPassword); if (!$this->dbh) { return false; } } catch (PDOException $e) { return false; } $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->connected = true; $this->dbh->exec('SET NAMES utf8;'); return true; } public function query($query, $buffered = false) { if (!$this->dbh) { return false; } $numargs = func_num_args(); $arg_list = func_get_args(); $next_arg_list = array(); $i = 1; while ($i < $numargs) { if (is_null($arg_list[$i]) || strtolower($arg_list[$i]) == 'null') { $next_arg_list[] = null; } else { $next_arg_list[] = $arg_list[$i]; } $i++; } if ($buffered !== true) { } else { $this->dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); } try { $this->result = $this->dbh->prepare($query); $this->result->execute($next_arg_list); } catch (Exception $e) { return false; } return true; } public function simple_query($query) { try { $this->result = $this->dbh->query($query); } catch (Exception $e) { return false; } return true; } public function get_rows($use_id = false, $column_as_id = '', $unique_row = true, $sub_row_id = '') { if (!($this->dbh && $this->result)) { return false; } $rows = array(); if (0 >= $this->result->rowCount()) { } else { foreach ($this->result->fetchAll(PDO::FETCH_ASSOC) as $row) { if ($use_id && array_key_exists($column_as_id, $row)) { if (isset($rows[$row[$column_as_id]])) { } else { $rows[$row[$column_as_id]] = array(); } if (!$unique_row) { if (!empty($sub_row_id) && array_key_exists($sub_row_id, $row)) { $rows[$row[$column_as_id]][$row[$sub_row_id]] = $row; } else { $rows[$row[$column_as_id]][] = $row; } } else { $rows[$row[$column_as_id]] = $row; } } else { $rows[] = $row; } } } $this->result = null; return $rows; } public function get_row() { if (!($this->dbh && $this->result)) { return false; } $row = array(); if (0 >= $this->result->rowCount()) { } else { $row = $this->result->fetch(PDO::FETCH_ASSOC); } $this->result = null; return $row; } public function get_col() { if (!($this->dbh && $this->result)) { return false; } $row = false; if (0 >= $this->result->rowCount()) { } else { $row = $this->result->fetch(); $row = $row[0]; } $this->result = null; return $row; } public function escape($string) { return $this->dbh->quote($string); } public function num_fields() { $mysqli_num_fields = $this->result->columnCount(); return (empty($mysqli_num_fields) ? 0 : $mysqli_num_fields); } public function last_insert_id() { $mysql_insert_id = $this->dbh->lastInsertId(); return (empty($mysql_insert_id) ? 0 : $mysql_insert_id); } public function num_rows() { $mysqli_num_rows = $this->result->rowCount(); return (empty($mysqli_num_rows) ? 0 : $mysqli_num_rows); } } class CoreUtilities { public static $db = null; public static $rRequest = array(); public static $rSettings = array(); public static $rServers = array(); public static $rBlockedISP = array(); public static $rBouquets = array(); public static $rCategories = array(); public static $rAllowedIPs = array(); public static $rCached = null; public static function init() { if (empty($_GET)) { } else { self::cleanGlobals($_GET); } if (empty($_POST)) { } else { self::cleanGlobals($_POST); } if (empty($_SESSION)) { } else { self::cleanGlobals($_SESSION); } if (empty($_COOKIE)) { } else { self::cleanGlobals($_COOKIE); } $rInput = @self::parseIncomingRecursively($_GET, array()); self::$rRequest = @self::parseIncomingRecursively($_POST, $rInput); if (self::$db->connected) { self::$rSettings = self::getSettings(); self::$rBlockedISP = self::getBlockedISP(); self::$rBouquets = self::getBouquets(); self::$rCategories = self::getCategories(); self::$rAllowedIPs = self::getAllowedIPs(); self::$rCached = (self::$rSettings['enable_cache'] ?: false); if (empty(self::$rSettings['default_timezone'])) { } else { date_default_timezone_set(self::$rSettings['default_timezone']); } self::$rServers = self::getServers(); } } public static function serialize($rData) { if (function_exists('igbinary_serialize')) { return igbinary_serialize($rData); } return serialize($rData); } public static function unserialize($rData) { if (function_exists('igbinary_unserialize')) { return igbinary_unserialize($rData); } return unserialize($rData); } public static function setCache($rCache, $rData) { $rData = self::serialize($rData); file_put_contents(TMP_PATH . $rCache, $rData, LOCK_EX); } public static function getCache($rCache, $rSeconds) { if (!file_exists(TMP_PATH . $rCache)) { } else { if (time() - filemtime(TMP_PATH . $rCache) >= $rSeconds) { } else { $rData = file_get_contents(TMP_PATH . $rCache); return self::unserialize($rData); } } return false; } public static function getBouquets() { $rCache = self::getCache('bouquets', 60); if (empty($rCache)) { $rOutput = array(); self::$db->query('SELECT *, IF(`bouquet_order` > 0, `bouquet_order`, 999) AS `order` FROM `bouquets` ORDER BY `order` ASC;'); foreach (self::$db->get_rows(true, 'id') as $rID => $rChannels) { $rOutput[$rID]['id'] = $rID; $rOutput[$rID]['bouquet_name'] = $rChannels['bouquet_name']; $rOutput[$rID]['order'] = $rChannels['order']; $rOutput[$rID]['streams'] = array_merge(json_decode($rChannels['bouquet_channels'], true), json_decode($rChannels['bouquet_movies'], true), json_decode($rChannels['bouquet_radios'], true)); $rOutput[$rID]['series'] = json_decode($rChannels['bouquet_series'], true); $rOutput[$rID]['channels'] = json_decode($rChannels['bouquet_channels'], true); $rOutput[$rID]['movies'] = json_decode($rChannels['bouquet_movies'], true); $rOutput[$rID]['radios'] = json_decode($rChannels['bouquet_radios'], true); } self::setCache('bouquets', $rOutput); return $rOutput; } else { return $rCache; } } public static function getStream($rID) { self::$db->query('SELECT * FROM `streams` WHERE `id` = ?;', $rID); if (self::$db->num_rows() != 1) { } else { $rRow = self::$db->get_row(); if ($rRow['title']) { $rRow['stream_display_name'] = $rRow['title']; } return $rRow; } } public static function getCategories($rType = null) { if (is_string($rType)) { self::$db->query('SELECT t1.* FROM `streams_categories` t1 WHERE t1.category_type = ? GROUP BY t1.id ORDER BY t1.cat_order ASC', $rType); return (0 < self::$db->num_rows() ? self::$db->get_rows(true, 'id') : array()); } $rCache = self::getCache('categories', 20); if (empty($rCache)) { self::$db->query('SELECT t1.* FROM `streams_categories` t1 ORDER BY t1.cat_order ASC'); $rCategories = (0 < self::$db->num_rows() ? self::$db->get_rows(true, 'id') : array()); self::setCache('categories', $rCategories); return $rCategories; } return $rCache; } public static function getAllowedIPs() { if (empty($rAllowedIPs)) { $rIPs = array('127.0.0.1', $_SERVER['SERVER_ADDR']); foreach (self::$rServers as $rServerID => $rServerInfo) { if (!empty($rServerInfo['whitelist_ips'])) { $rIPs = array_merge($rIPs, json_decode($rServerInfo['whitelist_ips'], true)); } $rIPs[] = $rServerInfo['server_ip']; if ($rServerInfo['private_ip']) { $rIPs[] = $rServerInfo['private_ip']; } } if (!empty(self::$rSettings['allowed_ips_admin'])) { $rIPs = array_merge($rIPs, explode(',', self::$rSettings['allowed_ips_admin'])); } return array_unique($rIPs); } else { return self::$rAllowedIPs; } } public static function mergeRecursive($rArray) { if (is_array($rArray)) { $rArrayValues = array(); foreach ($rArray as $rValue) { if (is_scalar($rValue) || is_resource($rValue)) { $rArrayValues[] = $rValue; } else { if (!is_array($rValue)) { } else { $rArrayValues = array_merge($rArrayValues, self::mergeRecursive($rValue)); } } } return $rArrayValues; } else { return $rArray; } } public static function getBlockedISP() { $rCache = self::getCache('blocked_isp', 20); if ($rCache === false) { self::$db->query('SELECT id, isp, blocked FROM `blocked_isps`'); $rOutput = self::$db->get_rows(); self::setCache('blocked_isp', $rOutput); return $rOutput; } return $rCache; } public static function getServers() { $rCache = self::getCache('servers', 10); if (empty($rCache)) { if (!empty($_SERVER['REQUEST_SCHEME'])) { } else { $_SERVER['REQUEST_SCHEME'] = 'http'; } self::$db->query('SELECT * FROM `servers`'); $rServers = array(); $rOnlineStatus = array(1); foreach (self::$db->get_rows() as $rRow) { if (empty($rRow['domain_name'])) { $rURL = escapeshellcmd($rRow['server_ip']); } else { $rURL = str_replace(array('http://', '/', 'https://'), '', escapeshellcmd(explode(',', $rRow['domain_name'])[0])); } if ($rRow['enable_https'] == 1) { $rProtocol = 'https'; } else { $rProtocol = 'http'; } $rPort = ($rProtocol == 'http' ? intval($rRow['http_broadcast_port']) : intval($rRow['https_broadcast_port'])); $rRow['server_protocol'] = $rProtocol; $rRow['request_port'] = $rPort; $rRow['site_url'] = $rProtocol . '://' . $rURL . ':' . $rPort . '/'; $rRow['http_url'] = 'http://' . $rURL . ':' . intval($rRow['http_broadcast_port']) . '/'; $rRow['https_url'] = 'https://' . $rURL . ':' . intval($rRow['https_broadcast_port']) . '/'; $rRow['domains'] = array('protocol' => $rProtocol, 'port' => $rPort, 'urls' => array_filter(array_map('escapeshellcmd', explode(',', $rRow['domain_name'])))); if (is_numeric($rRow['parent_id'])) { $rRow['parent_id'] = array(intval($rRow['parent_id'])); } else { $rRow['parent_id'] = array_map('intval', json_decode($rRow['parent_id'], true)); } if (!isset($rRow['order'])) { $rRow['order'] = 0; } $rServers[intval($rRow['id'])] = $rRow; } self::setCache('servers', $rServers); return $rServers; } else { return $rCache; } } public static function getSettings() { $rCache = self::getCache('settings', 20); if (empty($rCache)) { $rOutput = array(); self::$db->query('SELECT * FROM `settings`'); $rRows = self::$db->get_row(); foreach ($rRows as $rKey => $rValue) { $rOutput[$rKey] = $rValue; } $rOutput['allow_countries'] = json_decode($rOutput['allow_countries'], true); self::setCache('settings', $rOutput); return $rOutput; } else { return $rCache; } } public static function cleanGlobals(&$rData, $rIteration = 0) { if (10 > $rIteration) { foreach ($rData as $rKey => $rValue) { if (is_array($rValue)) { self::cleanGlobals($rData[$rKey], ++$rIteration); } else { $rValue = str_replace(chr('0'), '', $rValue); $rValue = str_replace('', '', $rValue); $rValue = str_replace('', '', $rValue); $rValue = str_replace('../', '../', $rValue); $rValue = str_replace('‮', '', $rValue); $rData[$rKey] = $rValue; } } } else { return null; } } public static function parseIncomingRecursively(&$rData, $rInput = array(), $rIteration = 0) { if (20 > $rIteration) { if (is_array($rData)) { foreach ($rData as $rKey => $rValue) { if (is_array($rValue)) { $rInput[$rKey] = self::parseIncomingRecursively($rData[$rKey], array(), $rIteration + 1); } else { $rKey = self::parseCleanKey($rKey); $rValue = self::parseCleanValue($rValue); $rInput[$rKey] = $rValue; } } return $rInput; } else { return $rInput; } } else { return $rInput; } } public static function parseCleanKey($rKey) { if ($rKey !== '') { $rKey = htmlspecialchars(urldecode($rKey)); $rKey = str_replace('..', '', $rKey); $rKey = preg_replace('/\\_\\_(.+?)\\_\\_/', '', $rKey); return preg_replace('/^([\\w\\.\\-\\_]+)$/', '$1', $rKey); } return ''; } public static function parseCleanValue($rValue) { if ($rValue != '') { $rValue = str_replace(' ', ' ', stripslashes($rValue)); $rValue = str_replace(array("\r\n", "\n\r", "\r"), "\n", $rValue); $rValue = str_replace('', '-->', $rValue); $rValue = str_ireplace(' $rServerInfo) { if (!($rServerInfo['server_type'] == 1 && in_array($rServerID, $rServerInfo['parent_id']) && ($rServerInfo['server_online'] || !$rOnline))) { } else { $rReturn[$rProxyID] = $rServerInfo; } } return $rReturn; } public static function getDomainName($rForceSSL = false) { $rDomainName = null; $rKey = ($rForceSSL ? 'https_url' : 'site_url'); if (self::$rSettings['use_mdomain_in_lists'] == 1) { if (self::$rServers[SERVER_ID]['enable_proxy']) { $rProxyID = self::getProxyFor(SERVER_ID); if (!$rProxyID) { } else { $rDomainName = self::$rServers[$rProxyID][$rKey]; } } else { $rDomainName = self::$rServers[SERVER_ID][$rKey]; } } else { list($serverIPAddress, $serverPort) = explode(':', $_SERVER['HTTP_HOST']); if ($serverIPAddress == self::$rServers[SERVER_ID]['server_ip'] && self::$rServers[SERVER_ID]['enable_proxy']) { $rProxyID = self::getProxyFor(SERVER_ID); if (!$rProxyID) { } else { $rDomainName = self::$rServers[$rProxyID][$rKey]; } } else { if ($rForceSSL) { $rDomainName = 'https://' . $serverIPAddress . ':' . self::$rServers[SERVER_ID]['https_broadcast_port'] . '/'; } else { $rDomainName = self::$rServers[SERVER_ID]['server_protocol'] . '://' . $serverIPAddress . ':' . self::$rServers[SERVER_ID]['request_port'] . '/'; } } } return $rDomainName; } public static function getSubtitles($rStreamID, $rSubtitles) { global $rUserInfo; $rDomainName = self::getDomainName(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443); $rReturn = array(); if (!is_array($rSubtitles)) { } else { $i = 0; foreach ($rSubtitles as $rSubtitle) { $rLanguage = null; foreach (array_keys($rSubtitle['tags']) as $rKey) { if (!in_array(strtoupper(explode('-', $rKey)[0]), array('BPS', 'DURATION', 'NUMBER_OF_FRAMES', 'NUMBER_OF_BYTES'))) { if ($rKey != 'language') { } else { $rLanguage = $rSubtitle['tags'][$rKey]; break; } } else { list(, $rLanguage) = explode('-', $rKey, 2); break; } } if ($rLanguage) { } else { $rLanguage = 'Subtitle #' . ($i + 1); } $rReturn[] = array('label' => $rLanguage, 'file' => $rDomainName . 'subtitle/' . $rUserInfo['username'] . '/' . $rUserInfo['password'] . '/' . $rStreamID . '?sub_id=' . $i . '&webvtt=1', 'kind' => 'subtitles'); $i++; } } return $rReturn; } public static function mapContentTypesToNumbers($rTypes) { $rReturn = array(); $rTypeInt = array('live' => 1, 'movie' => 2, 'created_live' => 3, 'radio_streams' => 4, 'series' => 5); foreach ($rTypes as $rType) { $rReturn[] = $rTypeInt[$rType]; } return $rReturn; } public static function getOrderedCategories($rCategories, $rType = 'movie') { $rReturn = array(); foreach (self::getCategories($rType) as $rCategory) { if (!in_array($rCategory['id'], $rCategories)) { } else { $rReturn[] = array('title' => $rCategory['category_name'], 'id' => $rCategory['id'], 'cat_order' => $rCategory['cat_order']); } } $rTitle = array_column($rReturn, 'cat_order'); array_multisort($rTitle, SORT_ASC, $rReturn); if ($rType != 'live') { array_unshift($rReturn, array('id' => '0', 'cat_order' => 0, 'title' => 'All Genres')); } else { array_unshift($rReturn, array('id' => '0', 'cat_order' => 0, 'title' => 'Most Popular')); } return $rReturn; } public static function sortChannels($rChannels) { if (!(0 < count($rChannels) && file_exists(CACHE_TMP_PATH . 'channel_order') && self::$rSettings['channel_number_type'] != 'bouquet')) { } else { $rOrder = self::unserialize(file_get_contents(CACHE_TMP_PATH . 'channel_order')); $rChannels = array_flip($rChannels); $rNewOrder = array(); foreach ($rOrder as $rID) { if (!isset($rChannels[$rID])) { } else { $rNewOrder[] = $rID; } } if (0 >= count($rNewOrder)) { } else { return $rNewOrder; } } return $rChannels; } public static function confirmIDs($rIDs) { $rReturn = array(); foreach ($rIDs as $rID) { if (0 >= intval($rID)) { } else { $rReturn[] = $rID; } } return $rReturn; } public static function getUserStreams($rUserInfo, $rTypes = array(), $rCategoryID = null, $rFav = null, $rOrderBy = null, $rSearchBy = null, $rPicking = array(), $rStart = 0, $rLimit = 10, $rIDs = false) { global $db; $rAdded = false; $rChannels = array(); foreach ($rTypes as $rType) { switch ($rType) { case 'live': case 'created_live': if (!$rAdded) { $rChannels = array_merge($rChannels, $rUserInfo['live_ids']); $rAdded = true; break; } break; case 'movie': $rChannels = array_merge($rChannels, $rUserInfo['vod_ids']); break; case 'radio_streams': $rChannels = array_merge($rChannels, $rUserInfo['radio_ids']); break; case 'series': $rChannels = array_merge($rChannels, $rUserInfo['episode_ids']); break; } } $rStreams = array('count' => 0, 'streams' => array()); $rKey = $rStart + 1; $rWhereV = $rWhere = array(); if (self::$rSettings['player_hide_incompatible']) { $rWhere[] = '(SELECT MAX(`compatible`) FROM `streams_servers` WHERE `streams_servers`.`stream_id` = `streams`.`id` LIMIT 1) = 1'; } if (count($rTypes) > 0) { $rWhere[] = '`type` IN (' . implode(',', self::mapContentTypesToNumbers($rTypes)) . ')'; } if (!empty($rCategoryID)) { $rWhere[] = "JSON_CONTAINS(`category_id`, ?, '\$')"; $rWhereV[] = $rCategoryID; } else { if (in_array('live', $rTypes) && empty($rSearchBy)) { $rStart = 0; $rLimit = 200; $rLiveIDs = self::unserialize(file_get_contents(CONTENT_PATH . 'live_popular')); if ($rLiveIDs && 0 < count($rLiveIDs)) { $rWhere[] = '`id` IN (' . implode(',', array_map('intval', $rLiveIDs)) . ')'; } } } if ($rPicking['filter']) { switch ($rPicking['filter']) { case 'all': break; case 'timeshift': $rWhere[] = '`tv_archive_duration` > 0 AND `tv_archive_server_id` > 0'; break; } } $rChannels = self::sortChannels($rChannels); if (empty($rFav)) { } else { $favoriteChannelIds = array(); foreach ($rTypes as $rType) { foreach ($rUserInfo['fav_channels'][$rType] as $rStreamID) { $favoriteChannelIds[] = intval($rStreamID); } } $rChannels = array_intersect($favoriteChannelIds, $rChannels); } if (empty($rSearchBy)) { } else { $rWhere[] = '`stream_display_name` LIKE ?'; $rWhereV[] = '%' . $rSearchBy . '%'; } if (!is_array($rPicking['year_range'])) { } else { $rWhere[] = '(`year` >= ? AND `year` <= ?)'; $rWhereV[] = $rPicking['year_range'][0]; $rWhereV[] = $rPicking['year_range'][1]; } if (!is_array($rPicking['rating_range'])) { } else { $rWhere[] = '(`rating` >= ? AND `rating` <= ?)'; $rWhereV[] = $rPicking['rating_range'][0]; $rWhereV[] = $rPicking['rating_range'][1]; } $rChannels = self::confirmIDs($rChannels); if (count($rChannels) != 0) { $rWhere[] = '`id` IN (' . implode(',', array_map('intval', $rChannels)) . ')'; $rWhereString = 'WHERE ' . implode(' AND ', $rWhere); switch ($rOrderBy) { case 'name': uasort($rStreams['streams'], 'sortArrayStreamName'); $rOrder = '`stream_display_name` ASC'; break; case 'top': case 'rating': $rOrder = '`rating` DESC'; break; case 'added': $rOrder = '`added` DESC'; break; case 'release': $rOrder = '`year` DESC, `stream_display_name` ASC'; break; case 'number': default: if (self::$rSettings['channel_number_type'] != 'manual' && 0 < count($rChannels)) { $rOrder = 'FIELD(id,' . implode(',', $rChannels) . ')'; } else { $rOrder = '`order` ASC'; } break; } if (0 < count($rChannels)) { $db->query('SELECT COUNT(`id`) AS `count` FROM `streams` ' . $rWhereString . ';', ...$rWhereV); $rStreams['count'] = $db->get_row()['count']; if ($rLimit) { if ($rIDs) { $rQuery = 'SELECT `id` FROM `streams` ' . $rWhereString . ' ORDER BY ' . $rOrder . ' LIMIT ' . $rStart . ', ' . $rLimit . ';'; } else { $rQuery = 'SELECT (SELECT `stream_info` FROM `streams_servers` WHERE `streams_servers`.`pid` IS NOT NULL AND `streams_servers`.`stream_id` = `streams`.`id` LIMIT 1) AS `stream_info`, `id`, `stream_display_name`, `movie_properties`, `target_container`, `added`, `year`, `category_id`, `channel_id`, `epg_id`, `tv_archive_duration`, `stream_icon`, `allow_record`, `type` FROM `streams` ' . $rWhereString . ' ORDER BY ' . $rOrder . ' LIMIT ' . $rStart . ', ' . $rLimit . ';'; } } else { if ($rIDs) { $rQuery = 'SELECT `id` FROM `streams` ' . $rWhereString . ' ORDER BY ' . $rOrder . ';'; } else { $rQuery = 'SELECT (SELECT `stream_info` FROM `streams_servers` WHERE `streams_servers`.`pid` IS NOT NULL AND `streams_servers`.`stream_id` = `streams`.`id` LIMIT 1) AS `stream_info`, `id`, `stream_display_name`, `movie_properties`, `target_container`, `added`, `year`, `category_id`, `channel_id`, `epg_id`, `tv_archive_duration`, `stream_icon`, `allow_record`, `type` FROM `streams` ' . $rWhereString . ' ORDER BY ' . $rOrder . ';'; } } $db->query($rQuery, ...$rWhereV); $rRows = $db->get_rows(); } else { $rRows = array(); } if ($rIDs) { return $rRows; } foreach ($rRows as $rStream) { $rStream['number'] = $rKey; if (in_array($rCategoryID, json_decode($rStream['category_id'], true))) { $rStream['category_id'] = $rCategoryID; } else { list($rStream['category_id']) = json_decode($rStream['category_id'], true); } $rStream['stream_info'] = json_decode($rStream['stream_info'], true); $rStreams['streams'][$rStream['id']] = $rStream; $rKey++; } return $rStreams; } else { return $rStreams; } } public static function getUserSeries($rUserInfo, $rCategoryID = null, $rFav = null, $rOrderBy = null, $rSearchBy = null, $rPicking = array(), $rStart = 0, $rLimit = 10, $additionalOptions = null) { global $db; $rSeries = $rUserInfo['series_ids']; $rStreams = array('count' => 0, 'streams' => array()); $rKey = $rStart + 1; $rWhereV = $rWhere = array(); if (!self::$rSettings['player_hide_incompatible']) { } else { $rWhere[] = '(SELECT MAX(`compatible`) FROM `streams_servers` LEFT JOIN `streams_episodes` ON `streams_episodes`.`stream_id` = `streams_servers`.`stream_id` WHERE `streams_episodes`.`series_id` = `streams_series`.`id`) = 1'; } if (empty($rCategoryID)) { } else { $rWhere[] = "JSON_CONTAINS(`category_id`, ?, '\$')"; $rWhereV[] = $rCategoryID; } if (!is_array($rPicking['year_range'])) { } else { $rWhere[] = '(`year` >= ? AND `year` <= ?)'; $rWhereV[] = $rPicking['year_range'][0]; $rWhereV[] = $rPicking['year_range'][1]; } if (!is_array($rPicking['rating_range'])) { } else { $rWhere[] = '(`rating` >= ? AND `rating` <= ?)'; $rWhereV[] = $rPicking['rating_range'][0]; $rWhereV[] = $rPicking['rating_range'][1]; } if (empty($rSearchBy)) { } else { $rWhere[] = '`title` LIKE ?'; $rWhereV[] = '%' . $rSearchBy . '%'; } $rSeries = self::confirmIDs($rSeries); if (count($rSeries) != 0) { $rWhere[] = '`id` IN (' . implode(',', array_map('intval', $rSeries)) . ')'; $rWhereString = 'WHERE ' . implode(' AND ', $rWhere); switch ($rOrderBy) { case 'name': uasort($rStreams['streams'], 'sortArrayStreamName'); $rOrder = '`title` ASC'; break; case 'top': case 'rating': $rOrder = '`rating` DESC'; break; case 'added': $rOrder = '`last_modified` DESC'; break; case 'release': $rOrder = '`release_date` DESC'; break; case 'number': default: if (CoreUtilities::$rSettings['vod_sort_newest']) { $rOrder = '`last_modified` DESC'; } else { $rOrder = 'FIELD(id,' . implode(',', $rSeries) . ')'; } break; } if (0 < count($rSeries)) { $db->query('SELECT COUNT(`id`) AS `count` FROM `streams_series` ' . $rWhereString . ';', ...$rWhereV); $rStreams['count'] = $db->get_row()['count']; if ($rLimit) { $rQuery = 'SELECT `id`, `title`, `category_id`, `cover`, `rating`, `release_date`, `last_modified`, `tmdb_id`, `seasons`, `backdrop_path`, `year` FROM `streams_series` ' . $rWhereString . ' ORDER BY ' . $rOrder . ' LIMIT ' . $rStart . ', ' . $rLimit . ';'; } else { $rQuery = 'SELECT `id`, `title`, `category_id`, `cover`, `rating`, `release_date`, `last_modified`, `tmdb_id`, `seasons`, `backdrop_path`, `year` FROM `streams_series` ' . $rWhereString . ' ORDER BY ' . $rOrder . ';'; } $db->query($rQuery, ...$rWhereV); $rRows = $db->get_rows(); } else { if ($additionalOptions) { return null; } $rRows = array(); } foreach ($rRows as $rStream) { $rStream['number'] = $rKey; if (in_array($rCategoryID, json_decode($rStream['category_id'], true))) { $rStream['category_id'] = $rCategoryID; } else { list($rStream['category_id']) = json_decode($rStream['category_id'], true); } $rStreams['streams'][$rStream['id']] = $rStream; $rKey++; } return $rStreams; } else { return $rStreams; } } public static function getSerie($rID) { self::$db->query('SELECT * FROM `streams_series` WHERE `id` = ?;', $rID); if (self::$db->num_rows() != 1) { } else { return self::$db->get_row(); } } public static function getIPInfo($rIP) { if (!empty($rIP)) { if (!file_exists(CONS_TMP_PATH . md5($rIP) . '_geo2')) { $rGeoIP = new MaxMind\Db\Reader(GEOLITE2_BIN); $rResponse = $rGeoIP->get($rIP); $rGeoIP->close(); if (!$rResponse) { } else { file_put_contents(CONS_TMP_PATH . md5($rIP) . '_geo2', json_encode($rResponse)); } return $rResponse; } return json_decode(file_get_contents(CONS_TMP_PATH . md5($rIP) . '_geo2'), true); } return false; } public static function getISP($rIP) { if (!empty($rIP)) { if (!file_exists(CONS_TMP_PATH . md5($rIP) . '_isp')) { $rGeoIP = new MaxMind\Db\Reader(GEOISP_BIN); $rResponse = $rGeoIP->get($rIP); $rGeoIP->close(); if (!$rResponse) { } else { file_put_contents(CONS_TMP_PATH . md5($rIP) . '_isp', json_encode($rResponse)); } return $rResponse; } return json_decode(file_get_contents(CONS_TMP_PATH . md5($rIP) . '_isp'), true); } return false; } public static function checkISP($rConISP) { foreach (self::$rBlockedISP as $rISP) { if (strtolower($rConISP) != strtolower($rISP['isp'])) { } else { return intval($rISP['blocked']); } } return 0; } public static function getUserInfo($rUserID = null, $rUsername = null, $rPassword = null, $rGetChannelIDs = false, $rGetConnections = false, $rIP = '') { $rUserInfo = null; if (self::$rCached) { if (empty($rPassword) && empty($rUserID) && strlen($rUsername) == 32) { if (self::$rSettings['case_sensitive_line']) { $rUserID = intval(file_get_contents(LINES_TMP_PATH . 'line_t_' . $rUsername)); } else { $rUserID = intval(file_get_contents(LINES_TMP_PATH . 'line_t_' . strtolower($rUsername))); } } else { if (!empty($rUsername) && !empty($rPassword)) { if (self::$rSettings['case_sensitive_line']) { $rUserID = intval(file_get_contents(LINES_TMP_PATH . 'line_c_' . $rUsername . '_' . $rPassword)); } else { $rUserID = intval(file_get_contents(LINES_TMP_PATH . 'line_c_' . strtolower($rUsername) . '_' . strtolower($rPassword))); } } else { if (!empty($rUserID)) { } else { return false; } } } if (!$rUserID) { } else { $rUserInfo = self::unserialize(file_get_contents(LINES_TMP_PATH . 'line_i_' . $rUserID)); } } else { if (empty($rPassword) && empty($rUserID) && strlen($rUsername) == 32) { self::$db->query('SELECT * FROM `lines` WHERE `is_mag` = 0 AND `is_e2` = 0 AND `access_token` = ? AND LENGTH(`access_token`) = 32', $rUsername); } else { if (!empty($rUsername) && !empty($rPassword)) { self::$db->query('SELECT * FROM `lines` WHERE `username` = ? AND `password` = ? LIMIT 1', $rUsername, $rPassword); } else { if (!empty($rUserID)) { self::$db->query('SELECT * FROM `lines` WHERE `id` = ?', $rUserID); } else { return false; } } } if (0 >= self::$db->num_rows()) { } else { $rUserInfo = self::$db->get_row(); } } if (!$rUserInfo) { return false; } if (self::$rSettings['county_override_1st'] == 1 && empty($rUserInfo['forced_country']) && !empty($rIP) && $rUserInfo['max_connections'] == 1) { $rUserInfo['forced_country'] = self::getIPInfo($rIP)['registered_country']['iso_code']; if (self::$rCached) { self::setSignal('forced_country/' . $rUserInfo['id'], $rUserInfo['forced_country']); } else { self::$db->query('UPDATE `lines` SET `forced_country` = ? WHERE `id` = ?', $rUserInfo['forced_country'], $rUserInfo['id']); } } $rUserInfo['bouquet'] = json_decode($rUserInfo['bouquet'], true); $rUserInfo['allowed_ips'] = @array_filter(@array_map('trim', @json_decode($rUserInfo['allowed_ips'], true))); $rUserInfo['allowed_ua'] = @array_filter(@array_map('trim', @json_decode($rUserInfo['allowed_ua'], true))); $rUserInfo['allowed_outputs'] = array_map('intval', json_decode($rUserInfo['allowed_outputs'], true)); $rUserInfo['output_formats'] = array(); if (self::$rCached) { foreach (self::unserialize(file_get_contents(CACHE_TMP_PATH . 'output_formats')) as $rRow) { if (!in_array(intval($rRow['access_output_id']), $rUserInfo['allowed_outputs'])) { } else { $rUserInfo['output_formats'][] = $rRow['output_key']; } } } else { self::$db->query('SELECT `access_output_id`, `output_key` FROM `output_formats`;'); foreach (self::$db->get_rows() as $rRow) { if (!in_array(intval($rRow['access_output_id']), $rUserInfo['allowed_outputs'])) { } else { $rUserInfo['output_formats'][] = $rRow['output_key']; } } } $rUserInfo['con_isp_name'] = null; $rUserInfo['isp_violate'] = 0; $rUserInfo['isp_is_server'] = 0; if (self::$rSettings['show_isps'] == 1 && !empty($rIP)) { $rISPLock = self::getISP($rIP); if (!is_array($rISPLock)) { } else { if (empty($rISPLock['isp'])) { } else { $rUserInfo['con_isp_name'] = $rISPLock['isp']; $rUserInfo['isp_asn'] = $rISPLock['autonomous_system_number']; $rUserInfo['isp_violate'] = self::checkISP($rUserInfo['con_isp_name']); } } if (!(!empty($rUserInfo['con_isp_name']) && self::$rSettings['enable_isp_lock'] == 1 && $rUserInfo['is_stalker'] == 0 && $rUserInfo['is_isplock'] == 1 && !empty($rUserInfo['isp_desc']) && strtolower($rUserInfo['con_isp_name']) != strtolower($rUserInfo['isp_desc']))) { } else { $rUserInfo['isp_violate'] = 1; } if (!($rUserInfo['isp_violate'] == 0 && strtolower($rUserInfo['con_isp_name']) != strtolower($rUserInfo['isp_desc']))) { } else { if (self::$rCached) { self::setSignal('isp/' . $rUserInfo['id'], json_encode(array($rUserInfo['con_isp_name'], $rUserInfo['isp_asn']))); } else { self::$db->query('UPDATE `lines` SET `isp_desc` = ?, `as_number` = ? WHERE `id` = ?', $rUserInfo['con_isp_name'], $rUserInfo['isp_asn'], $rUserInfo['id']); } } } if (!$rGetChannelIDs) { } else { $rLiveIDs = $rVODIDs = $rRadioIDs = $rCategoryIDs = $rChannelIDs = $rSeriesIDs = array(); foreach ($rUserInfo['bouquet'] as $rID) { if (!isset(self::$rBouquets[$rID]['streams'])) { } else { $rChannelIDs = array_merge($rChannelIDs, self::$rBouquets[$rID]['streams']); } if (!isset(self::$rBouquets[$rID]['series'])) { } else { $rSeriesIDs = array_merge($rSeriesIDs, self::$rBouquets[$rID]['series']); } if (!isset(self::$rBouquets[$rID]['channels'])) { } else { $rLiveIDs = array_merge($rLiveIDs, self::$rBouquets[$rID]['channels']); } if (!isset(self::$rBouquets[$rID]['movies'])) { } else { $rVODIDs = array_merge($rVODIDs, self::$rBouquets[$rID]['movies']); } if (!isset(self::$rBouquets[$rID]['radios'])) { } else { $rRadioIDs = array_merge($rRadioIDs, self::$rBouquets[$rID]['radios']); } } $rUserInfo['channel_ids'] = array_map('intval', array_unique($rChannelIDs)); $rUserInfo['series_ids'] = array_map('intval', array_unique($rSeriesIDs)); $rUserInfo['vod_ids'] = array_map('intval', array_unique($rVODIDs)); $rUserInfo['live_ids'] = array_map('intval', array_unique($rLiveIDs)); $rUserInfo['radio_ids'] = array_map('intval', array_unique($rRadioIDs)); if (self::$rCached) { $channelCategoryMap = self::unserialize(file_get_contents(STREAMS_TMP_PATH . 'channels_categories')); $seriesCategoryMap = self::unserialize(file_get_contents(SERIES_TMP_PATH . 'series_categories')); if (0 >= count($rUserInfo['channel_ids'])) { } else { foreach ($rUserInfo['channel_ids'] as $rStreamID) { if (!isset($channelCategoryMap[$rStreamID])) { } else { foreach (array_values($channelCategoryMap[$rStreamID]) as $rCategoryID) { if (!$rCategoryID || in_array($rCategoryID, $rCategoryIDs)) { } else { $rCategoryIDs[] = $rCategoryID; } } } } } if (0 >= count($rUserInfo['series_ids'])) { } else { foreach ($rUserInfo['series_ids'] as $rSeriesID) { if (!isset($seriesCategoryMap[$rSeriesID])) { } else { foreach (array_values($seriesCategoryMap[$rSeriesID]) as $rCategoryID) { if (!$rCategoryID || in_array($rCategoryID, $rCategoryIDs)) { } else { $rCategoryIDs[] = $rCategoryID; } } } } } } else { if (0 >= count($rUserInfo['channel_ids'])) { } else { self::$db->query('SELECT DISTINCT(`category_id`) FROM `streams` WHERE `id` IN (' . implode(',', array_map('intval', $rUserInfo['channel_ids'])) . ');'); foreach (self::$db->get_rows(true, 'category_id') as $rGroup) { foreach (json_decode($rGroup['category_id'], true) as $rCategoryID) { if (in_array($rCategoryID, $rCategoryIDs)) { } else { $rCategoryIDs[] = $rCategoryID; } } } } if (0 >= count($rUserInfo['series_ids'])) { } else { self::$db->query('SELECT DISTINCT(`category_id`) FROM `streams_series` WHERE `id` IN (' . implode(',', array_map('intval', $rUserInfo['series_ids'])) . ');'); foreach (self::$db->get_rows(true, 'category_id') as $rGroup) { foreach (json_decode($rGroup['category_id'], true) as $rCategoryID) { if (in_array($rCategoryID, $rCategoryIDs)) { } else { $rCategoryIDs[] = $rCategoryID; } } } } } $rUserInfo['category_ids'] = array_map('intval', array_unique($rCategoryIDs)); } return $rUserInfo; } public static function setSignal($rKey, $rData) { file_put_contents(SIGNALS_TMP_PATH . 'cache_' . md5($rKey), json_encode(array($rKey, $rData))); } public static function getMainID() { foreach (self::$rServers as $rServerID => $rServer) { if (!(isset($rServer['is_main']) && $rServer['is_main'] == 1 || isset($rServer['can_delete']) && $rServer['can_delete'] == 0)) { } else { return $rServerID; } } } public static function getUserIP() { return $_SERVER['REMOTE_ADDR']; } public static function checkFlood($rIP = null) { if (self::$rSettings['flood_limit'] != 0) { if ($rIP) { } else { $rIP = self::getUserIP(); } if (!(empty($rIP) || in_array($rIP, self::$rAllowedIPs))) { $rFloodExclude = array_filter(array_unique(explode(',', self::$rSettings['flood_ips_exclude']))); if (!in_array($rIP, $rFloodExclude)) { $rIPFile = TMP_PATH . $rIP; if (file_exists($rIPFile)) { $rFloodRow = json_decode(file_get_contents($rIPFile), true); $rFloodSeconds = self::$rSettings['flood_seconds']; $rFloodLimit = self::$rSettings['flood_limit']; if (time() - $rFloodRow['last_request'] <= $rFloodSeconds) { $rFloodRow['requests']++; $rFloodRow['last_request'] = time(); file_put_contents($rIPFile, json_encode($rFloodRow), LOCK_EX); if ($rFloodLimit > $rFloodRow['requests']) { } else { sleep(10); exit(); } } else { $rFloodRow['requests'] = 0; $rFloodRow['last_request'] = time(); file_put_contents($rIPFile, json_encode($rFloodRow), LOCK_EX); } } else { file_put_contents($rIPFile, json_encode(array('requests' => 0, 'last_request' => time())), LOCK_EX); } } else { return null; } } else { return null; } } else { return null; } } public static function validateImage($rURL, $rForceProtocol = null) { if (substr($rURL, 0, 2) == 's:') { $rSplit = explode(':', $rURL, 3); $rServerURL = self::getPublicURL(intval($rSplit[1]), $rForceProtocol); if ($rServerURL) { return $rServerURL . 'images/' . basename($rURL); } return ''; } return $rURL; } public static function getPublicURL($rServerID = null, $rForceProtocol = null) { $rOriginatorID = null; if (isset($rServerID)) { } else { $rServerID = SERVER_ID; } if ($rForceProtocol) { $rProtocol = $rForceProtocol; } else { if (isset($_SERVER['SERVER_PORT']) && self::$rSettings['keep_protocol']) { $rProtocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443 ? 'https' : 'http'); } else { $rProtocol = self::$rServers[$rServerID]['server_protocol']; } } if (!self::$rServers[$rServerID]) { } else { if (!self::$rServers[$rServerID]['enable_proxy']) { } else { $rProxyIDs = array_keys(self::getProxies($rServerID)); if (count($rProxyIDs) != 0) { } else { $rProxyIDs = array_keys(self::getProxies($rServerID, false)); } if (count($rProxyIDs) != 0) { $rOriginatorID = $rServerID; $rServerID = $rProxyIDs[array_rand($rProxyIDs)]; } else { return ''; } } $rHost = (defined('host') ? HOST : null); if ($rHost && in_array(strtolower($rHost), array_map('strtolower', self::$rServers[$rServerID]['domains']['urls']))) { $rDomain = $rHost; } else { $rDomain = (empty(self::$rServers[$rServerID]['domain_name']) ? self::$rServers[$rServerID]['server_ip'] : explode(',', self::$rServers[$rServerID]['domain_name'])[0]); } $rServerURL = $rProtocol . '://' . $rDomain . ':' . self::$rServers[$rServerID][$rProtocol . '_broadcast_port'] . '/'; if (!(self::$rServers[$rServerID]['server_type'] == 1 && $rOriginatorID && self::$rServers[$rOriginatorID]['is_main'] == 0)) { } else { $rServerURL .= md5($rServerID . '_' . $rOriginatorID . '_' . OPENSSL_EXTRA) . '/'; } return $rServerURL; } } public static function getMovieTMDB($rID) { if (0 < strlen(self::$rSettings['tmdb_language'])) { $rTMDB = new TMDB(self::$rSettings['tmdb_api_key'], self::$rSettings['tmdb_language']); } else { $rTMDB = new TMDB(self::$rSettings['tmdb_api_key']); } return ($rTMDB->getMovie($rID) ?: null); } public static function getSeriesTMDB($rID) { if (0 < strlen(self::$rSettings['tmdb_language'])) { $rTMDB = new TMDB(self::$rSettings['tmdb_api_key'], self::$rSettings['tmdb_language']); } else { $rTMDB = new TMDB(self::$rSettings['tmdb_api_key']); } return (json_decode($rTMDB->getTVShow($rID)->getJSON(), true) ?: null); } public static function getSeasonTMDB($rID, $rSeason) { if (0 < strlen(self::$rSettings['tmdb_language'])) { $rTMDB = new TMDB(self::$rSettings['tmdb_api_key'], self::$rSettings['tmdb_language']); } else { $rTMDB = new TMDB(self::$rSettings['tmdb_api_key']); } return json_decode($rTMDB->getSeason($rID, intval($rSeason))->getJSON(), true); } public static function getSimilarMovies($rID, $rPage = 1) { if (0 < strlen(self::$rSettings['tmdb_language'])) { $rTMDB = new TMDB(self::$rSettings['tmdb_api_key'], self::$rSettings['tmdb_language']); } else { $rTMDB = new TMDB(self::$rSettings['tmdb_api_key']); } return json_decode(json_encode($rTMDB->getSimilarMovies($rID, $rPage)), true); } public static function getSimilarSeries($rID, $rPage = 1) { if (0 < strlen(self::$rSettings['tmdb_language'])) { $rTMDB = new TMDB(self::$rSettings['tmdb_api_key'], self::$rSettings['tmdb_language']); } else { $rTMDB = new TMDB(self::$rSettings['tmdb_api_key']); } return json_decode(json_encode($rTMDB->getSimilarSeries($rID, $rPage)), true); } public static function getYear($rTitle, $rProperties) { $rYear = null; if (!isset($rProperties['release_date'])) { } else { $rYear = substr($rProperties['release_date'], 0, 4); } if (!isset($rProperties['releaseDate'])) { } else { $rYear = substr($rProperties['releaseDate'], 0, 4); } $rRegex = '/\\(([0-9)]+)\\)/'; preg_match($rRegex, $rTitle, $rMatches, PREG_OFFSET_CAPTURE, 0); $rTitleYear = null; $rMatchType = 0; if (count($rMatches) == 2) { $rTitleYear = intval($rMatches[1][0]); $rMatchType = 1; } else { $rSplit = explode('-', $rTitle); if (!(1 < count($rSplit) && is_numeric(trim(end($rSplit))))) { } else { $rTitleYear = intval(trim(end($rSplit))); $rMatchType = 2; } } if (0 >= $rMatchType) { } else { if (!(1900 <= $rTitleYear && $rTitleYear <= intval(date('Y') + 1))) { } else { if (!empty($rYear)) { } else { $rYear = $rTitleYear; } if ($rMatchType == 1) { $rTitle = trim(preg_replace('!\\s+!', ' ', str_replace($rMatches[0][0], '', $rTitle))); } else { $rTitle = trim(implode('-', array_slice($rSplit, 0, -1))); } } } return array('title' => $rTitle, 'year' => $rYear); } public static function encrypt($rData, $decryptionKey, $rDeviceID) { return self::base64url_encode(openssl_encrypt($rData, 'aes-256-cbc', md5(sha1($rDeviceID) . $decryptionKey), OPENSSL_RAW_DATA, substr(md5(sha1($decryptionKey)), 0, 16))); } public static function decrypt($rData, $decryptionKey, $rDeviceID) { return openssl_decrypt(self::base64url_decode($rData), 'aes-256-cbc', md5(sha1($rDeviceID) . $decryptionKey), OPENSSL_RAW_DATA, substr(md5(sha1($decryptionKey)), 0, 16)); } private static function base64url_encode($rData) { return rtrim(strtr(base64_encode($rData), '+/', '-_'), '='); } private static function base64url_decode($rData) { return base64_decode(strtr($rData, '-_', '+/')); } public static function getMAC() { exec('ip --json address list', $rOutput); $rAddresses = json_decode(implode('', $rOutput), true); $rValidMAC = null; foreach ($rAddresses as $rAddress) { foreach ($rAddress['addr_info'] as $rInterface) { if ($rInterface['label'] == 'lo' || empty($rInterface['local'])) { } else { if (!(filter_var($rAddress['address'], FILTER_VALIDATE_MAC) && $rAddress['address'] != '00:00:00:00:00:00')) { } else { $rValidMAC = $rAddress['address']; break; } } } } return $rValidMAC; } public static function getEPG($rStreamID, $rStartDate = null, $rFinishDate = null, $rByID = false) { $rReturn = array(); $rData = (file_exists(EPG_PATH . 'stream_' . $rStreamID) ? igbinary_unserialize(file_get_contents(EPG_PATH . 'stream_' . $rStreamID)) : array()); foreach ($rData as $rItem) { if ($rStartDate && !($rStartDate < $rItem['end'] && $rItem['start'] < $rFinishDate)) { } else { if ($rByID) { $rReturn[$rItem['id']] = $rItem; } else { $rReturn[] = $rItem; } } } return $rReturn; } public static function getEPGs($rStreamIDs, $rStartDate = null, $rFinishDate = null) { $rReturn = array(); foreach ($rStreamIDs as $rStreamID) { $rReturn[$rStreamID] = self::getEPG($rStreamID, $rStartDate, $rFinishDate); } return $rReturn; } public static function getProgramme($rStreamID, $rProgrammeID) { $rData = self::getEPG($rStreamID, null, null, true); if (!isset($rData[$rProgrammeID])) { } else { return $rData[$rProgrammeID]; } } } function sortArrayStreamName($a, $b) { $rColumn = (isset($a['stream_display_name']) ? 'stream_display_name' : 'title'); return strcmp($a[$rColumn], $b[$rColumn]); } function destroySession() { global $_SESSION; foreach (array('phash', 'pverify') as $rKey) { if (!isset($_SESSION[$rKey])) { } else { unset($_SESSION[$rKey]); } } } function sortArrayByArray($rArray, $rSort) { if (!(empty($rArray) || empty($rSort))) { $rOrdered = array(); foreach ($rSort as $rValue) { if (($rKey = array_search($rValue, $rArray)) === false) { } else { $rOrdered[] = $rValue; unset($rArray[$rKey]); } } return $rOrdered + $rArray; } else { return array(); } }