2025-07-10 20:01:56 +03:00
<? php
ini_set ( 'memory_limit' , - 1 );
setlocale ( LC_ALL , 'en_US.UTF-8' );
putenv ( 'LC_ALL=en_US.UTF-8' );
if ( posix_getpwuid ( posix_geteuid ())[ 'name' ] == 'xc_vm' ) {
if ( $argc ) {
register_shutdown_function ( 'shutdown' );
require str_replace ( '\\' , '/' , dirname ( $argv [ 0 ])) . '/../www/init.php' ;
ini_set ( 'display_errors' , 1 );
ini_set ( 'display_startup_errors' , 1 );
error_reporting ( 30711 );
$rForce = null ;
2025-11-30 19:48:24 +03:00
if ( count ( $argv ) == 2 ) {
2025-07-10 20:01:56 +03:00
$rForce = intval ( $argv [ 1 ]);
}
2025-11-30 19:48:24 +03:00
if ( ! $rForce ) {
2025-07-10 20:01:56 +03:00
if ( file_exists ( CACHE_TMP_PATH . 'plex_pid' )) {
$rPrevPID = intval ( file_get_contents ( CACHE_TMP_PATH . 'plex_pid' ));
} else {
$rPrevPID = null ;
}
2025-11-30 19:48:24 +03:00
if ( $rPrevPID && CoreUtilities :: isProcessRunning ( $rPrevPID , 'php' )) {
2025-07-10 20:01:56 +03:00
echo 'Plex Sync is already running. Please wait until it finishes.' . " \n " ;
exit ();
}
}
file_put_contents ( CACHE_TMP_PATH . 'plex_pid' , getmypid ());
cli_set_process_title ( 'XC_VM[Plex Sync]' );
$rScanOffset = ( intval ( CoreUtilities :: $rSettings [ 'scan_seconds' ]) ?: 3600 );
set_time_limit ( 0 );
2026-01-28 20:04:39 +03:00
if ( ! empty ( CoreUtilities :: $rSettings [ 'tmdb_api_key' ])) {
2025-07-10 20:01:56 +03:00
loadCron ();
} else {
exit ( 'No TMDb API key.' );
}
} else {
exit ( 0 );
}
} else {
exit ( 'Please run as XC_VM!' . " \n " );
}
class Thread {
public $process = null ;
public $pipes = null ;
public $buffer = null ;
public $output = null ;
public $error = null ;
public $timeout = null ;
public $start_time = null ;
public function __construct () {
$this -> process = 0 ;
$this -> buffer = '' ;
$this -> pipes = ( array ) null ;
$this -> output = '' ;
$this -> error = '' ;
$this -> start_time = time ();
$this -> timeout = 0 ;
}
public static function create ( $command ) {
$t = new Thread ();
$descriptor = array ( array ( 'pipe' , 'r' ), array ( 'pipe' , 'w' ), array ( 'pipe' , 'w' ));
$t -> process = proc_open ( $command , $descriptor , $t -> pipes );
stream_set_blocking ( $t -> pipes [ 1 ], 0 );
stream_set_blocking ( $t -> pipes [ 2 ], 0 );
return $t ;
}
public function isActive () {
$this -> buffer .= $this -> listen ();
$f = stream_get_meta_data ( $this -> pipes [ 1 ]);
return ! $f [ 'eof' ];
}
public function close () {
$r = proc_close ( $this -> process );
$this -> process = null ;
return $r ;
}
public function tell ( $thought ) {
fwrite ( $this -> pipes [ 0 ], $thought );
}
public function listen () {
$buffer = $this -> buffer ;
$this -> buffer = '' ;
while ( $r = fgets ( $this -> pipes [ 1 ], 1024 )) {
$buffer .= $r ;
$this -> output .= $r ;
}
return $buffer ;
}
public function getStatus () {
return proc_get_status ( $this -> process );
}
public function isBusy () {
return 0 < $this -> timeout && $this -> start_time + $this -> timeout < time ();
}
public function getError () {
$buffer = '' ;
while ( $r = fgets ( $this -> pipes [ 2 ], 1024 )) {
$buffer .= $r ;
}
return $buffer ;
}
}
class Multithread {
public $output = array ();
public $error = array ();
public $thread = null ;
public $commands = array ();
public $hasPool = false ;
public $toExecuted = array ();
public function __construct ( $commands , $sizePool = 0 ) {
$this -> hasPool = 0 < $sizePool ;
if ( ! $this -> hasPool ) {
} else {
$this -> toExecuted = array_splice ( $commands , $sizePool );
}
$this -> commands = $commands ;
foreach ( $this -> commands as $key => $command ) {
$this -> thread [ $key ] = Thread :: create ( $command );
}
}
public function run () {
while ( 0 < count ( $this -> commands )) {
foreach ( $this -> commands as $key => $command ) {
$this -> output [ $key ] .= @ $this -> thread [ $key ] -> listen ();
$this -> error [ $key ] .= @ $this -> thread [ $key ] -> getError ();
if ( $this -> thread [ $key ] -> isActive ()) {
$this -> output [ $key ] .= $this -> thread [ $key ] -> listen ();
if ( ! $this -> thread [ $key ] -> isBusy ()) {
} else {
$this -> thread [ $key ] -> close ();
unset ( $this -> commands [ $key ]);
self :: launchNextInQueue ();
}
} else {
$this -> thread [ $key ] -> close ();
unset ( $this -> commands [ $key ]);
self :: launchNextInQueue ();
}
}
}
return $this -> output ;
}
public function launchNextInQueue () {
if ( count ( $this -> toExecuted ) != 0 ) {
reset ( $this -> toExecuted );
$keyToExecuted = key ( $this -> toExecuted );
$this -> commands [ $keyToExecuted ] = $this -> toExecuted [ $keyToExecuted ];
$this -> thread [ $keyToExecuted ] = Thread :: create ( $this -> toExecuted [ $keyToExecuted ]);
unset ( $this -> toExecuted [ $keyToExecuted ]);
} else {
return true ;
}
}
}
function getPlexCategories ( $rType = null ) {
global $db ;
$rReturn = array ();
if ( $rType ) {
$db -> query ( 'SELECT * FROM `watch_categories` WHERE `type` = ? ORDER BY `genre_id` ASC;' , $rType );
} else {
$db -> query ( 'SELECT * FROM `watch_categories` ORDER BY `genre_id` ASC;' );
}
foreach ( $db -> get_rows () as $rRow ) {
$rReturn [ $rRow [ 'genre' ]] = $rRow ;
}
return $rReturn ;
}
function readURL ( $rURL ) {
$rCurl = curl_init ( $rURL );
curl_setopt ( $rCurl , CURLOPT_RETURNTRANSFER , true );
curl_setopt ( $rCurl , CURLOPT_CONNECTTIMEOUT , 10 );
curl_setopt ( $rCurl , CURLOPT_TIMEOUT , 10 );
return curl_exec ( $rCurl );
}
2025-11-30 19:48:24 +03:00
2025-07-10 20:01:56 +03:00
function loadCron () {
global $db ;
global $rScanOffset ;
global $rForce ;
$rPlexCategories = array ( 3 => getplexcategories ( 3 ), 4 => getplexcategories ( 4 ));
checkBouquets ();
checkCategories ();
if ( ! $rForce ) {
$db -> query ( "SELECT * FROM `watch_folders` WHERE `type` = 'plex' AND `server_id` = ? AND `active` = 1 AND (UNIX_TIMESTAMP() - `last_run` > ? OR `last_run` IS NULL) ORDER BY `id` ASC;" , SERVER_ID , $rScanOffset );
} else {
$db -> query ( "SELECT * FROM `watch_folders` WHERE `type` = 'plex' AND `server_id` = ? AND `id` = ?;" , SERVER_ID , $rForce );
}
$rRows = $db -> get_rows ();
2025-11-30 19:48:24 +03:00
if ( count ( $rRows ) > 0 ) {
2025-07-10 20:01:56 +03:00
shell_exec ( 'rm -f ' . WATCH_TMP_PATH . '*.ppid' );
$rLeafCount = $rUUIDs = $rSeriesTMDB = $rStreamDatabase = array ();
$rTMDBDatabase = array ( 'movie' => array (), 'series' => array ());
$rPlexDatabase = array ( 'movie' => array (), 'series' => array ());
echo 'Generating cache...' . " \n " ;
$db -> query ( 'SELECT `id`, `tmdb_id`, `plex_uuid` FROM `streams_series` WHERE `tmdb_id` IS NOT NULL AND `tmdb_id` > 0;' );
foreach ( $db -> get_rows () as $rRow ) {
$rSeriesTMDB [ $rRow [ 'id' ]] = $rRow [ 'tmdb_id' ];
2025-11-30 19:48:24 +03:00
if ( ! empty ( $rRow [ 'plex_uuid' ])) {
2025-07-10 20:01:56 +03:00
$rUUIDs [] = $rRow [ 'plex_uuid' ];
}
}
$db -> query ( 'SELECT `streams`.`id`, `streams_series`.`plex_uuid`, `streams_episodes`.`series_id`, `streams_episodes`.`season_num`, `streams_episodes`.`episode_num`, `streams`.`stream_source` FROM `streams_episodes` LEFT JOIN `streams` ON `streams`.`id` = `streams_episodes`.`stream_id` LEFT JOIN `streams_servers` ON `streams_servers`.`stream_id` = `streams`.`id` LEFT JOIN `streams_series` ON `streams_series`.`id` = `streams_episodes`.`series_id` WHERE `streams_servers`.`server_id` = ?;' , SERVER_ID );
foreach ( $db -> get_rows () as $rRow ) {
$rStreamDatabase [] = $rRow [ 'stream_source' ];
$rTMDBID = ( $rSeriesTMDB [ $rRow [ 'series_id' ]] ?: null );
list ( $rSource ) = json_decode ( $rRow [ 'stream_source' ], true );
2025-11-30 19:48:24 +03:00
if ( $rTMDBID ) {
2025-07-10 20:01:56 +03:00
$rTMDBDatabase [ 'series' ][ $rTMDBID ][ $rRow [ 'season_num' ] . '_' . $rRow [ 'episode_num' ]] = array ( 'id' => $rRow [ 'id' ], 'source' => $rSource );
}
2025-11-30 19:48:24 +03:00
if ( ! empty ( $rRow [ 'plex_uuid' ])) {
2025-07-10 20:01:56 +03:00
$rPlexDatabase [ 'series' ][ $rRow [ 'plex_uuid' ]][ $rRow [ 'season_num' ] . '_' . $rRow [ 'episode_num' ]] = array ( 'id' => $rRow [ 'id' ], 'source' => $rSource );
$rLeafCount [ $rRow [ 'plex_uuid' ]] ++ ;
}
}
$db -> query ( 'SELECT `streams`.`id`, `streams`.`plex_uuid`, `streams`.`stream_source`, `streams`.`movie_properties` FROM `streams` LEFT JOIN `streams_servers` ON `streams_servers`.`stream_id` = `streams`.`id` WHERE `streams`.`type` = 2 AND `streams_servers`.`server_id` = ?;' , SERVER_ID );
foreach ( $db -> get_rows () as $rRow ) {
$rStreamDatabase [] = $rRow [ 'stream_source' ];
$rTMDBID = ( json_decode ( $rRow [ 'movie_properties' ], true )[ 'tmdb_id' ] ?: null );
list ( $rSource ) = json_decode ( $rRow [ 'stream_source' ], true );
2025-11-30 19:48:24 +03:00
if ( $rTMDBID ) {
2025-07-10 20:01:56 +03:00
$rTMDBDatabase [ 'movie' ][ $rTMDBID ] = array ( 'id' => $rRow [ 'id' ], 'source' => $rSource );
}
2025-11-30 19:48:24 +03:00
if ( ! empty ( $rRow [ 'plex_uuid' ])) {
2025-07-10 20:01:56 +03:00
$rPlexDatabase [ 'movie' ][ $rRow [ 'plex_uuid' ]] = array ( 'id' => $rRow [ 'id' ], 'source' => $rSource );
$rUUIDs [] = $rRow [ 'plex_uuid' ];
}
}
exec ( 'find ' . WATCH_TMP_PATH . ' -maxdepth 1 -name "*.pcache" -print0 | xargs -0 rm' );
file_put_contents ( WATCH_TMP_PATH . 'stream_database.pcache' , json_encode ( $rStreamDatabase ));
foreach ( $rTMDBDatabase [ 'series' ] as $rTMDBID => $rData ) {
file_put_contents ( WATCH_TMP_PATH . 'series_' . $rTMDBID . '.pcache' , json_encode ( $rData ));
}
foreach ( $rTMDBDatabase [ 'movie' ] as $rTMDBID => $rData ) {
file_put_contents ( WATCH_TMP_PATH . 'movie_' . $rTMDBID . '.pcache' , json_encode ( $rData ));
}
foreach ( $rPlexDatabase [ 'series' ] as $rPlexID => $rData ) {
file_put_contents ( WATCH_TMP_PATH . 'series_' . $rPlexID . '.pcache' , json_encode ( $rData ));
}
foreach ( $rPlexDatabase [ 'movie' ] as $rPlexID => $rData ) {
file_put_contents ( WATCH_TMP_PATH . 'movie_' . $rPlexID . '.pcache' , json_encode ( $rData ));
}
unset ( $rTMDBDatabase , $rPlexDatabase );
echo 'Finished generating cache!' . " \n " ;
}
foreach ( $rRows as $rRow ) {
$rLimit = 100 ;
$rThreadData = array ();
2025-11-30 19:48:24 +03:00
// Get a Plex token (with caching)
$rToken = CoreUtilities :: getPlexToken ( $rRow [ 'plex_ip' ], $rRow [ 'plex_port' ], $rRow [ 'plex_username' ], $rRow [ 'plex_password' ]);
$db -> query ( 'UPDATE `watch_folders` SET `last_run` = UNIX_TIMESTAMP() WHERE `id` = ?;' , $rRow [ 'id' ]);
$rSectionURL = 'http://' . $rRow [ 'plex_ip' ] . ':' . $rRow [ 'plex_port' ] . '/library/sections?X-Plex-Token=' . $rToken ;
$rSections = json_decode ( json_encode ( simplexml_load_string ( readurl ( $rSectionURL ))), true );
$rThreadCount = 1 ;
foreach ( makeArray ( $rSections [ 'Directory' ]) as $F24f1be2729b363d ) {
if ( $F24f1be2729b363d [ '@attributes' ][ 'type' ] == 'movie' ) {
$rThreadCount = ( intval ( CoreUtilities :: $rSettings [ 'thread_count_movie' ]) ?: 25 );
2025-07-10 20:01:56 +03:00
} else {
2025-11-30 19:48:24 +03:00
$rThreadCount = ( intval ( CoreUtilities :: $rSettings [ 'thread_count_show' ]) ?: 5 );
2025-07-10 20:01:56 +03:00
}
2025-11-30 19:48:24 +03:00
$rKey = $F24f1be2729b363d [ '@attributes' ][ 'key' ];
if ( $rKey == $rRow [ 'directory' ]) {
$B9690335cedc4164 = 'http://' . $rRow [ 'plex_ip' ] . ':' . $rRow [ 'plex_port' ] . '/library/sections/' . $rKey . '/all?X-Plex-Token=' . $rToken . '&X-Plex-Container-Start=0&X-Plex-Container-Size=1' ;
$rCount = ( intval ( json_decode ( json_encode ( simplexml_load_string ( readurl ( $B9690335cedc4164 ))), true )[ '@attributes' ][ 'totalSize' ]) ?: 0 );
echo 'Count: ' . $rCount . " \n " ;
if ( $rCount > 0 ) {
$rSteps = [];
for ( $i = 0 ; $i <= $rCount ; $i += $rLimit ) {
$rSteps [] = $i ;
}
if ( ! $rSteps ) {
$rSteps = [ 0 ];
}
foreach ( $rSteps as $rStart ) {
$d7bd8e11c885f937 = 'http://' . $rRow [ 'plex_ip' ] . ':' . $rRow [ 'plex_port' ] . '/library/sections/' . $rKey . '/all?X-Plex-Token=' . $rToken . '&X-Plex-Container-Start=' . $rStart . '&X-Plex-Container-Size=' . $rLimit . '&sort=updatedAt%3Adesc' ;
$rContent = json_decode ( json_encode ( simplexml_load_string ( readurl ( $d7bd8e11c885f937 ))), true );
if ( ! isset ( $rContent [ 'Video' ])) {
$rContent [ 'Video' ] = $rContent [ 'Directory' ];
2025-07-10 20:01:56 +03:00
}
2025-11-30 19:48:24 +03:00
foreach ( makeArray ( $rContent [ 'Video' ]) as $rItem ) {
$rUUID = $rKey . '_' . $rItem [ '@attributes' ][ 'ratingKey' ];
$rUpdatedAt = intval ( $rItem [ '@attributes' ][ 'updatedAt' ] ?? 0 );
$lastRun = intval ( $rRow [ 'last_run' ] ?? 0 );
$rIsNewOrUpdated = ! $lastRun || $rUpdatedAt === 0 || $lastRun < $rUpdatedAt ;
if ( $F24f1be2729b363d [ '@attributes' ][ 'type' ] == 'movie' ) {
// Movies
$rIsMissing = $rRow [ 'scan_missing' ] && ! in_array ( $rUUID , $rUUIDs , true );
if ( $rIsNewOrUpdated || $rIsMissing || $rForce ) {
$rThreadData [] = [
'folder_id' => $rRow [ 'id' ],
'type' => 'movie' ,
'key' => $rItem [ '@attributes' ][ 'ratingKey' ],
'uuid' => $rUUID ,
'plex_categories' => $rPlexCategories ,
'read_native' => $rRow [ 'read_native' ],
'movie_symlink' => $rRow [ 'movie_symlink' ],
'remove_subtitles' => $rRow [ 'remove_subtitles' ],
'auto_encode' => $rRow [ 'auto_encode' ],
'auto_upgrade' => $rRow [ 'auto_upgrade' ],
'transcode_profile_id' => $rRow [ 'transcode_profile_id' ],
'max_genres' => intval ( CoreUtilities :: $rSettings [ 'max_genres' ] ?? 5 ),
'plex' => true ,
'ip' => $rRow [ 'plex_ip' ],
'port' => $rRow [ 'plex_port' ],
'token' => $rToken ,
'fb_bouquets' => $rRow [ 'fb_bouquets' ],
'store_categories' => $rRow [ 'store_categories' ],
'category_id' => $rRow [ 'category_id' ],
'bouquets' => $rRow [ 'bouquets' ],
'fb_category_id' => $rRow [ 'fb_category_id' ],
'check_tmdb' => $rRow [ 'check_tmdb' ],
'target_container' => $rRow [ 'target_container' ],
'server_add' => $rRow [ 'server_add' ],
'direct_proxy' => $rRow [ 'direct_proxy' ]
];
}
2025-07-10 20:01:56 +03:00
} else {
2025-11-30 19:48:24 +03:00
// TV series
$rCurrentLeafCount = intval ( $rItem [ '@attributes' ][ 'leafCount' ] ?? 0 );
$rPreviousLeafCount = $rLeafCount [ $rUUID ] ?? 0 ;
$rLeafCountChanged = $rCurrentLeafCount != $rPreviousLeafCount ;
$rIsMissing = $rRow [ 'scan_missing' ] && empty ( $rLeafCount [ $rUUID ]);
if ( $rIsNewOrUpdated || $rLeafCountChanged || $rIsMissing ) {
$rThreadData [] = [
'folder_id' => $rRow [ 'id' ],
'type' => $F24f1be2729b363d [ '@attributes' ][ 'type' ],
'key' => $rItem [ '@attributes' ][ 'ratingKey' ],
'uuid' => $rUUID ,
'plex_categories' => $rPlexCategories ,
'read_native' => $rRow [ 'read_native' ],
'movie_symlink' => $rRow [ 'movie_symlink' ],
'remove_subtitles' => $rRow [ 'remove_subtitles' ],
'auto_encode' => $rRow [ 'auto_encode' ],
'auto_upgrade' => $rRow [ 'auto_upgrade' ],
'transcode_profile_id' => $rRow [ 'transcode_profile_id' ],
'max_genres' => intval ( CoreUtilities :: $rSettings [ 'max_genres' ] ?? 5 ),
'plex' => true ,
'ip' => $rRow [ 'plex_ip' ],
'port' => $rRow [ 'plex_port' ],
'token' => $rToken ,
'fb_bouquets' => $rRow [ 'fb_bouquets' ],
'store_categories' => $rRow [ 'store_categories' ],
'category_id' => $rRow [ 'category_id' ],
'bouquets' => $rRow [ 'bouquets' ],
'fb_category_id' => $rRow [ 'fb_category_id' ],
'check_tmdb' => $rRow [ 'check_tmdb' ],
'target_container' => $rRow [ 'target_container' ],
'server_add' => $rRow [ 'server_add' ],
'direct_proxy' => $rRow [ 'direct_proxy' ]
];
2025-07-10 20:01:56 +03:00
}
}
}
}
}
2025-11-30 19:48:24 +03:00
break ;
2025-07-10 20:01:56 +03:00
}
}
2025-11-30 19:48:24 +03:00
if ( count ( $rThreadData ) > 0 ) {
echo 'Scan complete! Adding ' . count ( $rThreadData ) . ' files...' . " \n " ;
}
2025-07-10 20:01:56 +03:00
$cacheDataKey = array ();
foreach ( $rThreadData as $rData ) {
if ( $rData [ 'type' ] == 'movie' ) {
$rCommand = '/usr/bin/timeout 20 ' . PHP_BIN . ' ' . INCLUDES_PATH . 'cli/plex_item.php "' . base64_encode ( json_encode ( $rData , JSON_UNESCAPED_UNICODE )) . '"' ;
} else {
$rCommand = '/usr/bin/timeout 300 ' . PHP_BIN . ' ' . INCLUDES_PATH . 'cli/plex_item.php "' . base64_encode ( json_encode ( $rData , JSON_UNESCAPED_UNICODE )) . '"' ;
}
$cacheDataKey [] = $rCommand ;
}
unset ( $rThreadData );
$db -> close_mysql ();
if ( $rThreadCount <= 1 ) {
foreach ( $cacheDataKey as $rCommand ) {
shell_exec ( $rCommand );
}
} else {
$cacheMetadataKey = new Multithread ( $cacheDataKey , $rThreadCount );
$cacheMetadataKey -> run ();
}
$db -> db_connect ();
checkBouquets ();
checkCategories ();
}
}
2025-11-30 19:48:24 +03:00
2025-07-10 20:01:56 +03:00
function makeArray ( $rArray ) {
2025-11-30 19:48:24 +03:00
if ( isset ( $rArray [ '@attributes' ])) {
2025-07-10 20:01:56 +03:00
$rArray = array ( $rArray );
}
return $rArray ;
}
2025-11-30 19:48:24 +03:00
2025-07-10 20:01:56 +03:00
function getBouquet ( $rID ) {
global $db ;
$db -> query ( 'SELECT * FROM `bouquets` WHERE `id` = ?;' , $rID );
2025-11-30 19:48:24 +03:00
if ( $db -> num_rows () == 1 ) {
2025-07-10 20:01:56 +03:00
return $db -> get_row ();
}
}
2025-11-30 19:48:24 +03:00
2025-07-10 20:01:56 +03:00
function checkCategories () {
global $db ;
$rPlexCategories = array ( 'movie' => getplexcategories ( 3 ), 'show' => getplexcategories ( 4 ));
$rCategories = glob ( WATCH_TMP_PATH . '*.pcat' );
$rCatID = array ( 'movie' => 1 , 'show' => 1 );
$db -> query ( 'SELECT MAX(`genre_id`) AS `max` FROM `watch_categories` WHERE `type` = 3;' );
$rCatID [ 'movie' ] = intval ( $db -> get_row ()[ 'max' ]);
$db -> query ( 'SELECT MAX(`genre_id`) AS `max` FROM `watch_categories` WHERE `type` = 4;' );
$rCatID [ 'show' ] = intval ( $db -> get_row ()[ 'max' ]);
foreach ( $rCategories as $a539efc67de58f76 ) {
$rCategory = json_decode ( file_get_contents ( $a539efc67de58f76 ), true );
if ( in_array ( $rCategory [ 'title' ], array_keys ( $rPlexCategories [ $rCategory [ 'type' ]]))) {
} else {
$rCatID [ $rCategory [ 'type' ]] += 1 ;
$db -> query ( "INSERT INTO `watch_categories` (`type`, `genre_id`, `genre`, `category_id`, `bouquets`) VALUES (?, ?, ?, 0, '[]');" , array ( 'movie' => 3 , 'show' => 4 )[ $rCategory [ 'type' ]], $rCatID [ $rCategory [ 'type' ]], $rCategory [ 'title' ]);
}
unlink ( $a539efc67de58f76 );
}
}
2025-11-30 19:48:24 +03:00
2025-07-10 20:01:56 +03:00
function checkBouquets () {
global $db ;
$a39a336ad3894348 = array ();
$rBouquets = glob ( WATCH_TMP_PATH . '*.pbouquet' );
foreach ( $rBouquets as $D3e2134ebfab5c71 ) {
$rBouquet = json_decode ( file_get_contents ( $D3e2134ebfab5c71 ), true );
if ( isset ( $a39a336ad3894348 [ $rBouquet [ 'bouquet_id' ]])) {
} else {
$a39a336ad3894348 [ $rBouquet [ 'bouquet_id' ]] = array ( 'movie' => array (), 'series' => array ());
}
$a39a336ad3894348 [ $rBouquet [ 'bouquet_id' ]][ $rBouquet [ 'type' ]][] = $rBouquet [ 'id' ];
unlink ( $D3e2134ebfab5c71 );
}
foreach ( $a39a336ad3894348 as $rBouquetID => $rBouquetData ) {
$rBouquet = getBouquet ( $rBouquetID );
2025-11-30 19:48:24 +03:00
if ( $rBouquet ) {
2025-07-10 20:01:56 +03:00
foreach ( array_keys ( $rBouquetData ) as $rType ) {
if ( $rType == 'movie' ) {
$rColumn = 'bouquet_movies' ;
} else {
$rColumn = 'bouquet_series' ;
}
$rChannels = json_decode ( $rBouquet [ $rColumn ], true );
foreach ( $rBouquetData [ $rType ] as $rID ) {
if ( 0 >= intval ( $rID ) || in_array ( $rID , $rChannels )) {
} else {
$rChannels [] = $rID ;
}
}
$db -> query ( 'UPDATE `bouquets` SET `' . $rColumn . '` = ? WHERE `id` = ?;' , '[' . implode ( ',' , array_map ( 'intval' , $rChannels )) . ']' , $rBouquetID );
}
}
}
}
2025-11-30 19:48:24 +03:00
2025-07-10 20:01:56 +03:00
function shutdown () {
global $db ;
global $rIdentifier ;
2025-11-30 19:48:24 +03:00
if ( is_object ( $db )) {
2025-07-10 20:01:56 +03:00
$db -> close_mysql ();
}
@ unlink ( $rIdentifier );
}