feat: Add comprehensive documentation suite and reorganize project structure

- Created complete documentation in docs/ directory
- Added PROJECT_OVERVIEW.md with feature highlights and getting started guide
- Added ARCHITECTURE.md with system design and technical details
- Added SECURITY.md with comprehensive security implementation guide
- Added DEVELOPMENT.md with development workflows and best practices
- Added DEPLOYMENT.md with production deployment instructions
- Added API.md with complete REST API documentation
- Added CONTRIBUTING.md with contribution guidelines
- Added CHANGELOG.md with version history and migration notes
- Reorganized all documentation files into docs/ directory for better organization
- Updated README.md with proper documentation links and quick navigation
- Enhanced project structure with professional documentation standards
This commit is contained in:
SamiAhmed7777
2025-10-21 00:39:45 -07:00
commit 0b7e2d0a5b
6080 changed files with 1332936 additions and 0 deletions

View File

@@ -0,0 +1,407 @@
<?php
/*******************************************************************************************************************
| Software Name : EasyStream
| Software Description : High End YouTube Clone Script with Videos, Shorts, Streams, Images, Audio, Documents, Blogs
| Software Author : (c) Sami Ahmed
|*******************************************************************************************************************
|
|*******************************************************************************************************************
| This source file is subject to the EasyStream Proprietary License Agreement.
|
| By using this software, you acknowledge having read this Agreement and agree to be bound thereby.
|*******************************************************************************************************************
| Copyright (c) 2025 Sami Ahmed. All rights reserved.
|*******************************************************************************************************************/
/**
* Subtitle Management Page
*
* Allows users to:
* - Upload subtitle files (.srt, .vtt) for their videos
* - Manage multiple language tracks
* - Set default subtitle language
* - Delete subtitle tracks
* - Preview subtitles
*
* URL: /f_modules/m_frontend/m_file/manage_subtitles.php?v={file_key}&type={file_type}
*/
define('_ISVALID', true);
$main_dir = realpath(dirname(__FILE__) . '/../../../');
set_include_path($main_dir);
include_once 'f_core/config.core.php';
// Check if user is logged in
if (!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID'] == 0) {
header('Location: ' . $cfg['main_url'] . '/login.php');
exit;
}
$error_message = null;
$notice_message = null;
// Get file info from URL
$file_key = isset($_GET['v']) ? VSecurity::getParam('v', 'string') : '';
$file_type = isset($_GET['type']) ? VSecurity::getParam('type', 'string') : 'video';
// Validate file type
$allowed_types = ['video', 'short', 'live', 'audio'];
if (!in_array($file_type, $allowed_types)) {
$file_type = 'video';
}
// Get file ID from key
$table_map = [
'video' => 'db_videofiles',
'short' => 'db_shortfiles',
'live' => 'db_livefiles',
'audio' => 'db_audiofiles'
];
$sql = "SELECT `db_id`, `usr_id`, `file_title` FROM `{$table_map[$file_type]}`
WHERE `file_key` = '%s' AND `usr_id` = %d LIMIT 1";
$result = $class_database->doQuery($sql, $file_key, (int) $_SESSION['USER_ID']);
$file_info = $result->fetch_assoc();
if (!$file_info) {
$error_message = 'File not found or you do not have permission to manage its subtitles.';
} else {
$file_id = $file_info['db_id'];
// Handle subtitle upload
if (isset($_POST['upload_subtitle']) && isset($_FILES['subtitle_file'])) {
$language = VSecurity::postParam('language', 'string');
$label = VSecurity::postParam('label', 'string');
$is_default = isset($_POST['is_default']) ? true : false;
$result = VSubtitles::uploadSubtitle(
$file_id,
$file_type,
$_FILES['subtitle_file'],
$language,
$label,
$is_default
);
if ($result['success']) {
$notice_message = $result['message'];
} else {
$error_message = $result['message'];
}
}
// Handle subtitle deletion
if (isset($_POST['delete_subtitle'])) {
$sub_id = VSecurity::postParam('sub_id', 'int');
if (VSubtitles::deleteSubtitle($sub_id)) {
$notice_message = 'Subtitle deleted successfully';
} else {
$error_message = 'Failed to delete subtitle';
}
}
// Handle set default
if (isset($_POST['set_default'])) {
$sub_id = VSecurity::postParam('sub_id', 'int');
// Implement set default logic
$sql = "UPDATE `db_subtitles` SET `sub_default` = 0
WHERE `file_id` = %d AND `file_type` = '%s'";
$class_database->doQuery($sql, $file_id, $file_type);
$sql = "UPDATE `db_subtitles` SET `sub_default` = 1 WHERE `sub_id` = %d";
$class_database->doQuery($sql, $sub_id);
$notice_message = 'Default subtitle updated';
}
// Get existing subtitles
$subtitles = VSubtitles::getSubtitles($file_id, $file_type, false);
}
// Get configuration
$cfg = $class_database->getConfigurations('subtitles_enabled,subtitles_max_size,subtitles_allowed_formats,subtitles_max_per_video');
?>
<!DOCTYPE html>
<html>
<head>
<title>Manage Subtitles - <?php echo htmlspecialchars($file_info['file_title'] ?? 'EasyStream'); ?></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
max-width: 900px;
margin: 40px auto;
padding: 20px;
background: #f9f9f9;
}
.container {
background: white;
border-radius: 8px;
padding: 30px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
h1 {
color: #333;
margin-bottom: 10px;
}
.file-title {
color: #666;
margin-bottom: 30px;
font-size: 14px;
}
.message {
padding: 12px 16px;
border-radius: 4px;
margin-bottom: 20px;
}
.error {
background: #fee;
color: #c33;
border-left: 4px solid #c33;
}
.notice {
background: #efe;
color: #3c3;
border-left: 4px solid #3c3;
}
.upload-form {
background: #f5f5f5;
padding: 20px;
border-radius: 6px;
margin-bottom: 30px;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: 500;
color: #333;
}
input[type="text"],
input[type="file"],
select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.checkbox-group {
display: flex;
align-items: center;
}
.checkbox-group input {
width: auto;
margin-right: 8px;
}
button {
background: #1a73e8;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
}
button:hover {
background: #1557b0;
}
.subtitle-list {
margin-top: 20px;
}
.subtitle-item {
background: #fff;
border: 1px solid #e0e0e0;
border-radius: 6px;
padding: 16px;
margin-bottom: 12px;
display: flex;
justify-content: space-between;
align-items: center;
}
.subtitle-info {
flex: 1;
}
.subtitle-label {
font-weight: 500;
color: #333;
margin-bottom: 4px;
}
.subtitle-meta {
font-size: 13px;
color: #666;
}
.subtitle-actions {
display: flex;
gap: 8px;
}
.btn-small {
padding: 6px 12px;
font-size: 13px;
}
.btn-danger {
background: #d93025;
}
.btn-danger:hover {
background: #a71e15;
}
.btn-secondary {
background: #5f6368;
}
.btn-secondary:hover {
background: #3c4043;
}
.badge {
background: #1a73e8;
color: white;
padding: 2px 8px;
border-radius: 12px;
font-size: 11px;
margin-left: 8px;
}
.badge-success {
background: #34a853;
}
.badge-warning {
background: #fbbc04;
color: #333;
}
.back-link {
display: inline-block;
margin-bottom: 20px;
color: #1a73e8;
text-decoration: none;
}
.back-link:hover {
text-decoration: underline;
}
.info-box {
background: #e8f0fe;
padding: 12px 16px;
border-radius: 4px;
margin-bottom: 20px;
font-size: 14px;
color: #174ea6;
}
</style>
</head>
<body>
<div class="container">
<a href="<?php echo $cfg['main_url']; ?>/watch?v=<?php echo htmlspecialchars($file_key); ?>" class="back-link">
← Back to Video
</a>
<h1>Manage Subtitles</h1>
<?php if (isset($file_info)): ?>
<div class="file-title">For: <strong><?php echo htmlspecialchars($file_info['file_title']); ?></strong></div>
<?php endif; ?>
<?php if ($error_message): ?>
<div class="message error"><?php echo htmlspecialchars($error_message); ?></div>
<?php endif; ?>
<?php if ($notice_message): ?>
<div class="message notice"><?php echo htmlspecialchars($notice_message); ?></div>
<?php endif; ?>
<?php if ($cfg['subtitles_enabled'] == 1 && isset($file_info)): ?>
<div class="info-box">
📝 Upload subtitle files in .VTT or .SRT format. Maximum file size: <?php echo round($cfg['subtitles_max_size'] / 1048576, 2); ?>MB.
You can upload up to <?php echo $cfg['subtitles_max_per_video']; ?> subtitle tracks per video.
</div>
<div class="upload-form">
<h3 style="margin-top: 0;">Upload New Subtitle</h3>
<form method="POST" enctype="multipart/form-data">
<div class="form-group">
<label for="subtitle_file">Subtitle File (.vtt or .srt)</label>
<input type="file" id="subtitle_file" name="subtitle_file" accept=".vtt,.srt" required>
</div>
<div class="form-group">
<label for="language">Language Code</label>
<select id="language" name="language" required>
<option value="en">English (en)</option>
<option value="es">Spanish (es)</option>
<option value="fr">French (fr)</option>
<option value="de">German (de)</option>
<option value="it">Italian (it)</option>
<option value="pt">Portuguese (pt)</option>
<option value="ru">Russian (ru)</option>
<option value="ja">Japanese (ja)</option>
<option value="ko">Korean (ko)</option>
<option value="zh">Chinese (zh)</option>
<option value="ar">Arabic (ar)</option>
<option value="hi">Hindi (hi)</option>
</select>
</div>
<div class="form-group">
<label for="label">Display Label</label>
<input type="text" id="label" name="label" placeholder="e.g., English, Spanish, etc." required>
</div>
<div class="form-group checkbox-group">
<input type="checkbox" id="is_default" name="is_default">
<label for="is_default" style="margin-bottom: 0;">Set as default subtitle</label>
</div>
<button type="submit" name="upload_subtitle">Upload Subtitle</button>
</form>
</div>
<div class="subtitle-list">
<h3>Existing Subtitles</h3>
<?php if (empty($subtitles)): ?>
<p style="color: #666; font-style: italic;">No subtitles uploaded yet.</p>
<?php else: ?>
<?php foreach ($subtitles as $sub): ?>
<div class="subtitle-item">
<div class="subtitle-info">
<div class="subtitle-label">
<?php echo htmlspecialchars($sub['sub_label']); ?> (<?php echo htmlspecialchars($sub['sub_language']); ?>)
<?php if ($sub['sub_default'] == 1): ?>
<span class="badge badge-success">Default</span>
<?php endif; ?>
<?php if ($sub['active'] == 0): ?>
<span class="badge badge-warning">Pending Approval</span>
<?php endif; ?>
<?php if ($sub['sub_auto_generated'] == 1): ?>
<span class="badge">Auto-generated</span>
<?php endif; ?>
</div>
<div class="subtitle-meta">
Format: <?php echo strtoupper($sub['sub_format']); ?> |
Size: <?php echo round($sub['sub_filesize'] / 1024, 2); ?> KB |
Uploaded: <?php echo date('M d, Y', strtotime($sub['upload_date'])); ?>
</div>
</div>
<div class="subtitle-actions">
<?php if ($sub['sub_default'] != 1): ?>
<form method="POST" style="display: inline;">
<input type="hidden" name="sub_id" value="<?php echo $sub['sub_id']; ?>">
<button type="submit" name="set_default" class="btn-small btn-secondary">Set as Default</button>
</form>
<?php endif; ?>
<form method="POST" style="display: inline;">
<input type="hidden" name="sub_id" value="<?php echo $sub['sub_id']; ?>">
<button type="submit" name="delete_subtitle" class="btn-small btn-danger" onclick="return confirm('Are you sure you want to delete this subtitle?')">Delete</button>
</form>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php else: ?>
<p style="color: #666;">Subtitles are not enabled on this platform or file not found.</p>
<?php endif; ?>
</div>
</body>
</html>