'db_videofiles', 'short' => 'db_shortfiles', 'live' => 'db_livefiles', 'image' => 'db_imagefiles', 'audio' => 'db_audiofiles', 'document' => 'db_documentfiles', 'blog' => 'db_blogfiles' ]; if (!isset($table_map[$type])) { return []; } $table = $table_map[$type]; // Calculate trending score: (views * 2 + likes * 5 + comments * 3) / age_in_days $sql = "SELECT f.*, u.usr_user, u.usr_dname, u.usr_key, ((f.file_views * 2) + (f.file_like * 5) + (f.file_comments * 3)) / GREATEST(DATEDIFF(NOW(), f.upload_date), 1) as trending_score FROM `{$table}` f JOIN `db_accountuser` u ON f.usr_id = u.usr_id WHERE f.active = 1 AND f.approved = 1 AND f.deleted = 0 AND f.privacy = 'public' AND f.upload_date >= DATE_SUB(NOW(), INTERVAL 30 DAY) ORDER BY trending_score DESC LIMIT %d"; $result = $class_database->doQuery($sql, $limit); $items = []; while ($row = $result->fetch_assoc()) { $items[] = $row; } return $items; } /** * Get latest content from subscribed channels * * @param int $usr_id User ID * @param int $limit Number of items * @param string $type Content type * @return array Items from subscriptions */ public static function getFromSubscriptions($usr_id, $limit = 20, $type = 'video') { global $class_database; $table_map = [ 'video' => 'db_videofiles', 'short' => 'db_shortfiles', 'live' => 'db_livefiles', 'image' => 'db_imagefiles', 'audio' => 'db_audiofiles', 'document' => 'db_documentfiles', 'blog' => 'db_blogfiles' ]; if (!isset($table_map[$type])) { return []; } $table = $table_map[$type]; $sql = "SELECT DISTINCT f.*, u.usr_user, u.usr_dname, u.usr_key FROM `{$table}` f JOIN `db_accountuser` u ON f.usr_id = u.usr_id JOIN `db_subscribers` s ON s.subscriber_id = f.usr_id WHERE s.usr_id = %d AND f.active = 1 AND f.approved = 1 AND f.deleted = 0 AND f.privacy = 'public' ORDER BY f.upload_date DESC LIMIT %d"; $result = $class_database->doQuery($sql, $usr_id, $limit); $items = []; while ($row = $result->fetch_assoc()) { $items[] = $row; } return $items; } /** * Get content based on watch history (similar categories/tags) * * @param int $usr_id User ID * @param int $limit Number of items * @param string $type Content type * @return array Similar items */ public static function getBasedOnWatchHistory($usr_id, $limit = 20, $type = 'video') { global $class_database; $table_map = [ 'video' => 'db_videofiles', 'short' => 'db_shortfiles', 'live' => 'db_livefiles', 'image' => 'db_imagefiles', 'audio' => 'db_audiofiles', 'document' => 'db_documentfiles', 'blog' => 'db_blogfiles' ]; if (!isset($table_map[$type])) { return []; } $table = $table_map[$type]; // Get categories from watch history $sql = "SELECT DISTINCT fcr.ct_id FROM `db_filehistory` fh JOIN `db_filecategories` fcr ON fcr.file_key = fh.file_key WHERE fh.usr_id = %d AND fh.file_type = '%s' ORDER BY fh.db_id DESC LIMIT 10"; $result = $class_database->doQuery($sql, $usr_id, $type); $category_ids = []; while ($row = $result->fetch_assoc()) { $category_ids[] = $row['ct_id']; } if (empty($category_ids)) { return self::getTrending($limit, $type); } $category_list = implode(',', $category_ids); // Get content from these categories, excluding already watched $sql = "SELECT DISTINCT f.*, u.usr_user, u.usr_dname, u.usr_key FROM `{$table}` f JOIN `db_accountuser` u ON f.usr_id = u.usr_id JOIN `db_filecategories` fc ON fc.file_key = f.file_key WHERE fc.ct_id IN ({$category_list}) AND f.active = 1 AND f.approved = 1 AND f.deleted = 0 AND f.privacy = 'public' AND f.file_key NOT IN ( SELECT file_key FROM `db_filehistory` WHERE usr_id = %d ) ORDER BY f.file_views DESC, f.upload_date DESC LIMIT %d"; $result = $class_database->doQuery($sql, $usr_id, $limit); $items = []; while ($row = $result->fetch_assoc()) { $items[] = $row; } return $items; } /** * Get content based on liked videos * * @param int $usr_id User ID * @param int $limit Number of items * @param string $type Content type * @return array Similar items */ public static function getBasedOnLikes($usr_id, $limit = 20, $type = 'video') { global $class_database; $table_map = [ 'video' => 'db_videofiles', 'short' => 'db_shortfiles', 'live' => 'db_livefiles', 'image' => 'db_imagefiles', 'audio' => 'db_audiofiles', 'document' => 'db_documentfiles', 'blog' => 'db_blogfiles' ]; if (!isset($table_map[$type])) { return []; } $table = $table_map[$type]; // Get categories from liked content $sql = "SELECT DISTINCT fcr.ct_id FROM `db_filelike` fl JOIN `db_filecategories` fcr ON fcr.file_key = fl.file_key WHERE fl.usr_id = %d AND fl.file_type = '%s' AND fl.vote = 1 ORDER BY fl.db_id DESC LIMIT 10"; $result = $class_database->doQuery($sql, $usr_id, $type); $category_ids = []; while ($row = $result->fetch_assoc()) { $category_ids[] = $row['ct_id']; } if (empty($category_ids)) { return []; } $category_list = implode(',', $category_ids); // Get content from these categories, excluding already liked $sql = "SELECT DISTINCT f.*, u.usr_user, u.usr_dname, u.usr_key FROM `{$table}` f JOIN `db_accountuser` u ON f.usr_id = u.usr_id JOIN `db_filecategories` fc ON fc.file_key = f.file_key WHERE fc.ct_id IN ({$category_list}) AND f.active = 1 AND f.approved = 1 AND f.deleted = 0 AND f.privacy = 'public' AND f.file_key NOT IN ( SELECT file_key FROM `db_filelike` WHERE usr_id = %d AND vote = 1 ) ORDER BY f.file_like DESC, f.upload_date DESC LIMIT %d"; $result = $class_database->doQuery($sql, $usr_id, $limit); $items = []; while ($row = $result->fetch_assoc()) { $items[] = $row; } return $items; } /** * Get "Continue Watching" section * * @param int $usr_id User ID * @param int $limit Number of items * @return array Partially watched items */ public static function getContinueWatching($usr_id, $limit = 10) { global $class_database; // Get recently watched items that aren't fully watched $sql = "SELECT DISTINCT fh.*, CASE WHEN fh.file_type = 'video' THEN v.file_title WHEN fh.file_type = 'short' THEN s.file_title WHEN fh.file_type = 'live' THEN l.file_title WHEN fh.file_type = 'audio' THEN a.file_title END as file_title, u.usr_user, u.usr_dname, u.usr_key FROM `db_filehistory` fh LEFT JOIN `db_videofiles` v ON fh.file_key = v.file_key AND fh.file_type = 'video' LEFT JOIN `db_shortfiles` s ON fh.file_key = s.file_key AND fh.file_type = 'short' LEFT JOIN `db_livefiles` l ON fh.file_key = l.file_key AND fh.file_type = 'live' LEFT JOIN `db_audiofiles` a ON fh.file_key = a.file_key AND fh.file_type = 'audio' JOIN `db_accountuser` u ON COALESCE(v.usr_id, s.usr_id, l.usr_id, a.usr_id) = u.usr_id WHERE fh.usr_id = %d AND fh.watch_progress > 0 AND fh.watch_progress < 90 ORDER BY fh.db_id DESC LIMIT %d"; $result = $class_database->doQuery($sql, $usr_id, $limit); $items = []; while ($row = $result->fetch_assoc()) { $items[] = $row; } return $items; } /** * Remove duplicates and shuffle results * * @param array $items Array of items * @param int $limit Maximum items to return * @return array Deduplicated and shuffled items */ private static function deduplicateAndShuffle($items, $limit) { // Remove duplicates based on file_key $seen = []; $unique = []; foreach ($items as $item) { if (!isset($seen[$item['file_key']])) { $seen[$item['file_key']] = true; $unique[] = $item; } } // Shuffle for variety shuffle($unique); // Return limited number return array_slice($unique, 0, $limit); } }