2025-07-10 20:01:56 +03:00
<? php
2026-06-24 20:43:40 +03:00
2026-06-25 20:24:36 +03:00
use XcVm\Core\Config\DomainResolver ;
2026-06-24 20:52:00 +03:00
use XcVm\Core\Config\SettingsManager ;
2026-06-25 20:24:36 +03:00
use XcVm\Core\Validation\InputValidator ;
use XcVm\Domain\Stream\CategoryService ;
use XcVm\Domain\Stream\StreamSorter ; /**
2026-03-09 17:29:46 +03:00
* Player Utility Functions
*
* Extracted from player/functions.php — only the utility functions,
* without the legacy standalone bootstrap.
*
* Functions: sortArrayStreamName, getStream,
* getSubtitles, getOrderedCategories,
* getUserStreams, getUserSeries, mapContentTypesToNumbers
*
* Shared with includes/admin.php: sortArrayByArray, getSerie,
* getMovieTMDB, getSeriesTMDB, getSeasonTMDB.
2026-04-05 22:38:36 +03:00
*
* @package XC_VM_Infrastructure_Bootstrap
* @author Divarion_D <https://github.com/Divarion-D>
* @copyright 2025-2026 Vateron Media
2026-06-25 20:32:18 +03:00
* @link https://github.com/Vateron-Media/XC_VM
2026-04-05 22:38:36 +03:00
* @license AGPL-3.0 https://www.gnu.org/licenses/agpl-3.0.html
2026-03-09 17:29:46 +03:00
*/
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
function sortArrayStreamName ( $a , $b ) {
$rColumn = ( isset ( $a [ 'stream_display_name' ]) ? 'stream_display_name' : 'title' );
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
return strcmp ( $a [ $rColumn ], $b [ $rColumn ]);
}
2025-07-10 20:01:56 +03:00
2026-06-22 16:18:44 +03:00
/**
* Fetch a stream row by id.
*
* @param int $rID Stream id.
* @return array|false The stream row, or false if not found.
*/
2025-10-19 18:00:54 +03:00
function getStream ( $rID ) {
global $db ;
$db -> query ( 'SELECT * FROM `streams` WHERE `id` = ?;' , $rID );
if ( $db -> num_rows () == 1 ) {
$rRow = $db -> get_row ();
2025-07-10 20:01:56 +03:00
2026-03-09 17:29:46 +03:00
if ( ! empty ( $rRow [ 'title' ])) {
2025-10-19 18:00:54 +03:00
$rRow [ 'stream_display_name' ] = $rRow [ 'title' ];
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
return $rRow ;
2025-07-10 20:01:56 +03:00
}
2026-06-23 20:02:46 +03:00
return false ;
2025-10-19 18:00:54 +03:00
}
2025-07-10 20:01:56 +03:00
2026-06-22 16:18:44 +03:00
/**
* Resolve subtitle entries for a stream.
*
* @param int $rStreamID Stream id.
* @param mixed $rSubtitles Raw subtitle definition(s).
* @return array Subtitle entries.
*/
2025-10-19 18:00:54 +03:00
function getSubtitles ( $rStreamID , $rSubtitles ) {
global $rUserInfo ;
2026-03-07 21:53:45 +03:00
$rDomainName = DomainResolver :: resolve ( SERVER_ID , ! empty ( $_SERVER [ 'HTTPS' ]) && $_SERVER [ 'HTTPS' ] !== 'off' || $_SERVER [ 'SERVER_PORT' ] == 443 );
2025-10-19 18:00:54 +03:00
$rReturn = array ();
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
if ( is_array ( $rSubtitles )) {
$i = 0 ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
foreach ( $rSubtitles as $rSubtitle ) {
$rLanguage = null ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
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' ) {
$rLanguage = $rSubtitle [ 'tags' ][ $rKey ];
break ;
2025-07-10 20:01:56 +03:00
}
} else {
2025-10-19 18:00:54 +03:00
list (, $rLanguage ) = explode ( '-' , $rKey , 2 );
break ;
2025-07-10 20:01:56 +03:00
}
}
2025-10-19 18:00:54 +03:00
if ( ! $rLanguage ) {
$rLanguage = 'Subtitle #' . ( $i + 1 );
}
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
$rReturn [] = array ( 'label' => $rLanguage , 'file' => $rDomainName . 'subtitle/' . $rUserInfo [ 'username' ] . '/' . $rUserInfo [ 'password' ] . '/' . $rStreamID . '?sub_id=' . $i . '&webvtt=1' , 'kind' => 'subtitles' );
$i ++ ;
2025-07-10 20:01:56 +03:00
}
}
2025-10-19 18:00:54 +03:00
return $rReturn ;
}
2025-07-10 20:01:56 +03:00
2026-06-22 16:18:44 +03:00
/**
* Order categories for a content type per the configured order.
*
* @param array $rCategories Categories to order.
* @param string $rType Content type ('movie', 'series', ...).
* @return array Ordered categories.
*/
2025-10-19 18:00:54 +03:00
function getOrderedCategories ( $rCategories , $rType = 'movie' ) {
$rReturn = array ();
2025-07-10 20:01:56 +03:00
2026-03-07 21:53:45 +03:00
foreach ( CategoryService :: getFromDatabase ( $rType ) as $rCategory ) {
2025-10-19 18:00:54 +03:00
if ( in_array ( $rCategory [ 'id' ], $rCategories )) {
$rReturn [] = array ( 'title' => $rCategory [ 'category_name' ], 'id' => $rCategory [ 'id' ], 'cat_order' => $rCategory [ 'cat_order' ]);
2025-07-10 20:01:56 +03:00
}
}
2025-10-19 18:00:54 +03:00
$rTitle = array_column ( $rReturn , 'cat_order' );
array_multisort ( $rTitle , SORT_ASC , $rReturn );
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
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' ));
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
return $rReturn ;
}
2025-07-10 20:01:56 +03:00
2026-06-22 16:18:44 +03:00
/**
* Fetch the streams visible to a user, with filtering and pagination.
*
* @param array $rUserInfo Authenticated user row.
* @param array $rTypes Content types to include.
* @param int|null $rCategoryID Restrict to a category.
* @param bool|null $rFav Restrict to favourites.
* @param string|null $rOrderBy Sort column.
* @param string|null $rSearchBy Search term.
* @param array $rPicking Specific ids to pick.
* @param int $rStart Pagination offset.
* @param int $rLimit Page size.
* @param bool $rIDs Return only ids instead of full rows.
* @return array Streams (or ids) visible to the user.
*/
2025-10-19 18:00:54 +03:00
function getUserStreams ( $rUserInfo , $rTypes = array (), $rCategoryID = null , $rFav = null , $rOrderBy = null , $rSearchBy = null , $rPicking = array (), $rStart = 0 , $rLimit = 10 , $rIDs = false ) {
global $db ;
2026-03-09 17:29:46 +03:00
$rPicking = $rPicking ?? [];
2025-10-19 18:00:54 +03:00
$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 ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
case 'movie' :
$rChannels = array_merge ( $rChannels , $rUserInfo [ 'vod_ids' ]);
break ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
case 'radio_streams' :
$rChannels = array_merge ( $rChannels , $rUserInfo [ 'radio_ids' ]);
break ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
case 'series' :
$rChannels = array_merge ( $rChannels , $rUserInfo [ 'episode_ids' ]);
break ;
2025-07-10 20:01:56 +03:00
}
}
2025-10-19 18:00:54 +03:00
$rStreams = array ( 'count' => 0 , 'streams' => array ());
$rKey = $rStart + 1 ;
$rWhereV = $rWhere = array ();
2025-07-10 20:01:56 +03:00
2026-03-07 21:53:45 +03:00
if ( SettingsManager :: getAll ()[ 'player_hide_incompatible' ]) {
2025-10-19 18:00:54 +03:00
$rWhere [] = '(SELECT MAX(`compatible`) FROM `streams_servers` WHERE `streams_servers`.`stream_id` = `streams`.`id` LIMIT 1) = 1' ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
if ( count ( $rTypes ) > 0 ) {
$rWhere [] = '`type` IN (' . implode ( ',' , mapContentTypesToNumbers ( $rTypes )) . ')' ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
if ( ! empty ( $rCategoryID )) {
$rWhere [] = "JSON_CONTAINS(`category_id`, ?, ' \$ ')" ;
$rWhereV [] = $rCategoryID ;
} else {
if ( in_array ( 'live' , $rTypes ) && empty ( $rSearchBy )) {
$rStart = 0 ;
$rLimit = 200 ;
$rLiveIDs = igbinary_unserialize ( file_get_contents ( CONTENT_PATH . 'live_popular' ));
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
if ( $rLiveIDs && 0 < count ( $rLiveIDs )) {
$rWhere [] = '`id` IN (' . implode ( ',' , array_map ( 'intval' , $rLiveIDs )) . ')' ;
2025-07-10 20:01:56 +03:00
}
}
}
2026-03-09 17:29:46 +03:00
if ( ! empty ( $rPicking [ 'filter' ])) {
2025-10-19 18:00:54 +03:00
switch ( $rPicking [ 'filter' ]) {
case 'all' :
break ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
case 'timeshift' :
$rWhere [] = '`tv_archive_duration` > 0 AND `tv_archive_server_id` > 0' ;
break ;
2025-07-10 20:01:56 +03:00
}
}
2026-03-07 21:53:45 +03:00
$rChannels = StreamSorter :: sortChannels ( $rChannels );
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
if ( ! empty ( $rFav )) {
$favoriteChannelIds = array ();
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
foreach ( $rTypes as $rType ) {
foreach ( $rUserInfo [ 'fav_channels' ][ $rType ] as $rStreamID ) {
$favoriteChannelIds [] = intval ( $rStreamID );
2025-07-10 20:01:56 +03:00
}
}
2025-10-19 18:00:54 +03:00
$rChannels = array_intersect ( $favoriteChannelIds , $rChannels );
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
if ( ! empty ( $rSearchBy )) {
$rWhere [] = '`stream_display_name` LIKE ?' ;
$rWhereV [] = '%' . $rSearchBy . '%' ;
2025-07-10 20:01:56 +03:00
}
2026-03-09 17:29:46 +03:00
if ( ! empty ( $rPicking [ 'year_range' ]) && is_array ( $rPicking [ 'year_range' ])) {
2025-10-19 18:00:54 +03:00
$rWhere [] = '(`year` >= ? AND `year` <= ?)' ;
$rWhereV [] = $rPicking [ 'year_range' ][ 0 ];
$rWhereV [] = $rPicking [ 'year_range' ][ 1 ];
2025-07-10 20:01:56 +03:00
}
2026-03-09 17:29:46 +03:00
if ( ! empty ( $rPicking [ 'rating_range' ]) && is_array ( $rPicking [ 'rating_range' ])) {
2025-10-19 18:00:54 +03:00
$rWhere [] = '(`rating` >= ? AND `rating` <= ?)' ;
$rWhereV [] = $rPicking [ 'rating_range' ][ 0 ];
$rWhereV [] = $rPicking [ 'rating_range' ][ 1 ];
2025-07-10 20:01:56 +03:00
}
2026-03-07 21:53:45 +03:00
$rChannels = InputValidator :: confirmIDs ( $rChannels );
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
if ( count ( $rChannels ) != 0 ) {
$rWhere [] = '`id` IN (' . implode ( ',' , array_map ( 'intval' , $rChannels )) . ')' ;
$rWhereString = 'WHERE ' . implode ( ' AND ' , $rWhere );
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
switch ( $rOrderBy ) {
case 'name' :
uasort ( $rStreams [ 'streams' ], 'sortArrayStreamName' );
$rOrder = '`stream_display_name` ASC' ;
break ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
case 'top' :
case 'rating' :
$rOrder = '`rating` DESC' ;
break ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
case 'added' :
$rOrder = '`added` DESC' ;
break ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
case 'release' :
$rOrder = '`year` DESC, `stream_display_name` ASC' ;
break ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
case 'number' :
default :
2026-03-07 21:53:45 +03:00
if ( SettingsManager :: getAll ()[ 'channel_number_type' ] != 'manual' && 0 < count ( $rChannels )) {
2025-10-19 18:00:54 +03:00
$rOrder = 'FIELD(id,' . implode ( ',' , $rChannels ) . ')' ;
2025-07-10 20:01:56 +03:00
} else {
2025-10-19 18:00:54 +03:00
$rOrder = '`order` ASC' ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
break ;
}
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
if ( 0 < count ( $rChannels )) {
$db -> query ( 'SELECT COUNT(`id`) AS `count` FROM `streams` ' . $rWhereString . ';' , ... $rWhereV );
2025-09-24 21:31:50 +03:00
2025-10-19 18:00:54 +03:00
$rStreams [ 'count' ] = $db -> get_row ()[ 'count' ];
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
if ( $rLimit ) {
if ( $rIDs ) {
$rQuery = 'SELECT `id` FROM `streams` ' . $rWhereString . ' ORDER BY ' . $rOrder . ' LIMIT ' . $rStart . ', ' . $rLimit . ';' ;
2025-07-10 20:01:56 +03:00
} else {
2025-10-19 18:00:54 +03:00
$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 . ';' ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
} 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 . ';' ;
2025-09-30 16:21:06 +03:00
}
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
$db -> query ( $rQuery , ... $rWhereV );
$rRows = $db -> get_rows ();
2025-07-10 20:01:56 +03:00
} else {
2025-10-19 18:00:54 +03:00
$rRows = array ();
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
if ( $rIDs ) {
return $rRows ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
foreach ( $rRows as $rStream ) {
$rStream [ 'number' ] = $rKey ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
if ( in_array ( $rCategoryID , json_decode ( $rStream [ 'category_id' ], true ))) {
$rStream [ 'category_id' ] = $rCategoryID ;
2025-07-10 20:01:56 +03:00
} else {
2025-10-19 18:00:54 +03:00
list ( $rStream [ 'category_id' ]) = json_decode ( $rStream [ 'category_id' ], true );
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
$rStream [ 'stream_info' ] = json_decode ( $rStream [ 'stream_info' ], true );
$rStreams [ 'streams' ][ $rStream [ 'id' ]] = $rStream ;
$rKey ++ ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
return $rStreams ;
} else {
return $rStreams ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
}
2025-07-10 20:01:56 +03:00
2026-06-22 16:18:44 +03:00
/**
* Fetch the series visible to a user, with filtering and pagination.
*
* @param array $rUserInfo Authenticated user row.
* @param int|null $rCategoryID Restrict to a category.
* @param bool|null $rFav Restrict to favourites.
* @param string|null $rOrderBy Sort column.
* @param string|null $rSearchBy Search term.
* @param array $rPicking Specific ids to pick.
* @param int $rStart Pagination offset.
* @param int $rLimit Page size.
* @param mixed $additionalOptions Extra query options.
* @return array Series visible to the user.
*/
2025-10-19 18:00:54 +03:00
function getUserSeries ( $rUserInfo , $rCategoryID = null , $rFav = null , $rOrderBy = null , $rSearchBy = null , $rPicking = array (), $rStart = 0 , $rLimit = 10 , $additionalOptions = null ) {
global $db ;
2026-03-09 17:29:46 +03:00
$rPicking = $rPicking ?? [];
2025-10-19 18:00:54 +03:00
$rSeries = $rUserInfo [ 'series_ids' ];
$rStreams = array ( 'count' => 0 , 'streams' => array ());
$rKey = $rStart + 1 ;
$rWhereV = $rWhere = array ();
2025-07-10 20:01:56 +03:00
2026-03-07 21:53:45 +03:00
if ( SettingsManager :: getAll ()[ 'player_hide_incompatible' ]) {
2025-10-19 18:00:54 +03:00
$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' ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
if ( ! empty ( $rCategoryID )) {
$rWhere [] = "JSON_CONTAINS(`category_id`, ?, ' \$ ')" ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
$rWhereV [] = $rCategoryID ;
2025-07-10 20:01:56 +03:00
}
2026-03-09 17:29:46 +03:00
if ( ! empty ( $rPicking [ 'year_range' ]) && is_array ( $rPicking [ 'year_range' ])) {
2025-10-19 18:00:54 +03:00
$rWhere [] = '(`year` >= ? AND `year` <= ?)' ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
$rWhereV [] = $rPicking [ 'year_range' ][ 0 ];
$rWhereV [] = $rPicking [ 'year_range' ][ 1 ];
2025-07-10 20:01:56 +03:00
}
2026-03-09 17:29:46 +03:00
if ( ! empty ( $rPicking [ 'rating_range' ]) && is_array ( $rPicking [ 'rating_range' ])) {
2025-10-19 18:00:54 +03:00
$rWhere [] = '(`rating` >= ? AND `rating` <= ?)' ;
$rWhereV [] = $rPicking [ 'rating_range' ][ 0 ];
$rWhereV [] = $rPicking [ 'rating_range' ][ 1 ];
}
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
if ( ! empty ( $rSearchBy )) {
$rWhere [] = '`title` LIKE ?' ;
$rWhereV [] = '%' . $rSearchBy . '%' ;
}
2025-07-10 20:01:56 +03:00
2026-03-07 21:53:45 +03:00
$rSeries = InputValidator :: confirmIDs ( $rSeries );
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
if ( count ( $rSeries ) != 0 ) {
$rWhere [] = '`id` IN (' . implode ( ',' , array_map ( 'intval' , $rSeries )) . ')' ;
$rWhereString = 'WHERE ' . implode ( ' AND ' , $rWhere );
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
switch ( $rOrderBy ) {
case 'name' :
uasort ( $rStreams [ 'streams' ], 'sortArrayStreamName' );
$rOrder = '`title` ASC' ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
break ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
case 'top' :
case 'rating' :
$rOrder = '`rating` DESC' ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
break ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
case 'added' :
$rOrder = '`last_modified` DESC' ;
break ;
2025-09-24 21:31:50 +03:00
2025-10-19 18:00:54 +03:00
case 'release' :
$rOrder = '`release_date` DESC' ;
break ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
case 'number' :
default :
2026-03-07 21:53:45 +03:00
if ( SettingsManager :: getAll ()[ 'vod_sort_newest' ]) {
2025-10-19 18:00:54 +03:00
$rOrder = '`last_modified` DESC' ;
2025-09-24 21:31:50 +03:00
} else {
2025-10-19 18:00:54 +03:00
$rOrder = 'FIELD(id,' . implode ( ',' , $rSeries ) . ')' ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
break ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
if ( 0 < count ( $rSeries )) {
$db -> query ( 'SELECT COUNT(`id`) AS `count` FROM `streams_series` ' . $rWhereString . ';' , ... $rWhereV );
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
$rStreams [ 'count' ] = $db -> get_row ()[ 'count' ];
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
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 . ';' ;
2025-07-10 20:01:56 +03:00
} else {
2025-10-19 18:00:54 +03:00
$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 . ';' ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
$db -> query ( $rQuery , ... $rWhereV );
$rRows = $db -> get_rows ();
2025-09-24 21:31:50 +03:00
} else {
2025-10-19 18:00:54 +03:00
if ( $additionalOptions ) {
return null ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
$rRows = array ();
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
foreach ( $rRows as $rStream ) {
$rStream [ 'number' ] = $rKey ;
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
if ( in_array ( $rCategoryID , json_decode ( $rStream [ 'category_id' ], true ))) {
$rStream [ 'category_id' ] = $rCategoryID ;
2025-07-10 20:01:56 +03:00
} else {
2025-10-19 18:00:54 +03:00
list ( $rStream [ 'category_id' ]) = json_decode ( $rStream [ 'category_id' ], true );
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
$rStreams [ 'streams' ][ $rStream [ 'id' ]] = $rStream ;
$rKey ++ ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
return $rStreams ;
} else {
return $rStreams ;
2025-07-10 20:01:56 +03:00
}
2025-10-19 18:00:54 +03:00
}
2025-07-10 20:01:56 +03:00
2026-06-22 16:18:44 +03:00
/**
* Map content-type names to their numeric ids.
*
* @param string[] $rTypes Content-type names.
* @return int[] Corresponding numeric type ids.
*/
2025-10-19 18:00:54 +03:00
function mapContentTypesToNumbers ( $rTypes ) {
$rReturn = array ();
$rTypeInt = array ( 'live' => 1 , 'movie' => 2 , 'created_live' => 3 , 'radio_streams' => 4 , 'series' => 5 );
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
foreach ( $rTypes as $rType ) {
$rReturn [] = $rTypeInt [ $rType ];
}
2025-07-10 20:01:56 +03:00
2025-10-19 18:00:54 +03:00
return $rReturn ;
2025-09-30 16:21:06 +03:00
}