245 lines
10 KiB
PHP
245 lines
10 KiB
PHP
<?php
|
||
// upload_details.php - Step 2: Enter mix details and finalize upload
|
||
|
||
require_once 'includes/globals.php';
|
||
require_once 'vendor/autoload.php';
|
||
|
||
use DJMixHosting\Database;
|
||
use DJMixHosting\Genres;
|
||
use DJMixHosting\DJs;
|
||
use Aws\Credentials\Credentials;
|
||
|
||
// Ensure user is authenticated and an upload task exists
|
||
if (!isset($_SESSION['user']) || !isset($_SESSION['upload_task'])) {
|
||
header("Location: upload.php");
|
||
exit;
|
||
}
|
||
|
||
$uploadTask = $_SESSION['upload_task'];
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
// Get form fields
|
||
$title = trim($_POST['title'] ?? '');
|
||
$description = trim($_POST['description'] ?? '');
|
||
$recorded = trim($_POST['recorded'] ?? '');
|
||
$selectedGenres = $_POST['genres'] ?? []; // an array of genre IDs or names
|
||
$dj1 = $_POST['dj1'] ?? 0;
|
||
$dj2 = $_POST['dj2'] ?? 0;
|
||
$dj3 = $_POST['dj3'] ?? 0;
|
||
|
||
// Basic validation
|
||
if (empty($title)) {
|
||
$_SESSION['error'] = "Mix title is required.";
|
||
header("Location: upload_details.php");
|
||
exit;
|
||
}
|
||
|
||
// Generate a slug from the title
|
||
function slugify($text) {
|
||
// Replace non-letter or digits by -
|
||
$text = preg_replace('~[^\pL\d]+~u', '-', $text);
|
||
// Transliterate
|
||
$text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
|
||
// Remove unwanted characters
|
||
$text = preg_replace('~[^-\w]+~', '', $text);
|
||
// Trim
|
||
$text = trim($text, '-');
|
||
// Remove duplicate -
|
||
$text = preg_replace('~-+~', '-', $text);
|
||
// Lowercase
|
||
$text = strtolower($text);
|
||
return empty($text) ? 'n-a' : $text;
|
||
}
|
||
$slug = slugify($title);
|
||
|
||
|
||
|
||
$credentials = new Credentials(
|
||
$config['aws']['s3']['access_key'],
|
||
$config['aws']['s3']['secret_key']
|
||
);
|
||
|
||
$s3Client = new Aws\S3\S3Client([
|
||
'version' => 'latest',
|
||
'region' => $config['aws']['s3']['region'],
|
||
'endpoint' => $config['aws']['s3']['host'],
|
||
'credentials' => $credentials,
|
||
'use_path_style_endpoint' => true,
|
||
'profile' => null, // disable reading ~/.aws/config
|
||
'use_aws_shared_config_files' => false,
|
||
]);
|
||
|
||
// Determine remote file path – for now, store in a temporary folder on Spaces
|
||
$remotePath = "temp/mixes/" . uniqid() . "_" . basename($uploadTask['local_path']);
|
||
|
||
// Determine MIME type from file extension
|
||
$mimeType = ($uploadTask['ext'] === 'mp3') ? 'audio/mpeg' : 'application/zip';
|
||
|
||
try {
|
||
$s3Client->putObject([
|
||
'Bucket' => $config['aws']['s3']['bucket'],
|
||
'Key' => $remotePath,
|
||
'SourceFile' => $uploadTask['local_path'],
|
||
'ACL' => 'private', // file remains hidden until approved
|
||
'ContentType' => $mimeType,
|
||
]);
|
||
} catch (Exception $e) {
|
||
$_SESSION['error'] = "Error uploading file to CDN: " . $e->getMessage();
|
||
header("Location: upload_details.php");
|
||
exit;
|
||
}
|
||
|
||
// Now insert a new mix record into the database with pending status.
|
||
$db = new Database($config);
|
||
$stmt = $db->prepare("INSERT INTO mix (title, slug, description, cover, url, seconds, mediaplayer, dj1, dj2, dj3, pending, recorded) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)");
|
||
|
||
// Determine the duration and mediaplayer flag from the upload task:
|
||
// For an MP3 file, set mediaplayer to 0; for a ZIP file, set it to 1.
|
||
$seconds = 0;
|
||
if ($uploadTask['file_type'] === 'mp3') {
|
||
$seconds = (int)$uploadTask['metadata']['duration'];
|
||
$mediaplayer = 0; // MP3 gets a player
|
||
} elseif ($uploadTask['file_type'] === 'zip') {
|
||
$seconds = (int)$uploadTask['metadata']['total_duration'];
|
||
$mediaplayer = 1; // ZIPs are download only, so flag them as 1
|
||
}
|
||
// The URL can be constructed as per your CDN structure; for now, we store the remote path.
|
||
$url = $remotePath;
|
||
|
||
// For DJs, cast to integer (0 if none selected)
|
||
$dj1 = (int)$dj1;
|
||
$dj2 = (int)$dj2;
|
||
$dj3 = (int)$dj3;
|
||
$cover = "";
|
||
$stmt->bind_param("sssssiiiiss", $title, $slug, $description, $cover, $url, $seconds, $mediaplayer, $dj1, $dj2, $dj3, $recorded);
|
||
if (!$stmt->execute()) {
|
||
$_SESSION['error'] = "Error saving mix to database.";
|
||
header("Location: upload_details.php");
|
||
exit;
|
||
}
|
||
$mixId = $stmt->insert_id;
|
||
$stmt->close();
|
||
|
||
// Insert mix_meta entries for genres and tracklist
|
||
// For genres, assume $selectedGenres is an array of genre IDs (or names, if new genres need to be added)
|
||
foreach ($selectedGenres as $genreId) {
|
||
$stmt = $db->prepare("INSERT INTO mix_meta (mix_id, attribute, value) VALUES (?, 'genre', ?)");
|
||
$stmt->bind_param("is", $mixId, $genreId);
|
||
$stmt->execute();
|
||
$stmt->close();
|
||
}
|
||
// If the file was mp3 and metadata includes a track title or tracklist, insert that as well:
|
||
if ($uploadTask['file_type'] === 'mp3' && !empty($uploadTask['metadata']['title'])) {
|
||
$tracklist = $uploadTask['metadata']['title'];
|
||
$stmt = $db->prepare("INSERT INTO mix_meta (mix_id, attribute, value) VALUES (?, 'tracklist', ?)");
|
||
$stmt->bind_param("is", $mixId, $tracklist);
|
||
$stmt->execute();
|
||
$stmt->close();
|
||
} elseif ($uploadTask['file_type'] === 'zip' && !empty($uploadTask['metadata']['tracklist'])) {
|
||
// If multiple tracks, you might store them as a newline-separated string
|
||
$tracklist = implode("\n", $uploadTask['metadata']['tracklist']);
|
||
$stmt = $db->prepare("INSERT INTO mix_meta (mix_id, attribute, value) VALUES (?, 'tracklist', ?)");
|
||
$stmt->bind_param("is", $mixId, $tracklist);
|
||
$stmt->execute();
|
||
$stmt->close();
|
||
}
|
||
|
||
// Cleanup: delete the local temporary file and clear session task
|
||
unlink($uploadTask['local_path']);
|
||
unset($_SESSION['upload_task']);
|
||
|
||
$_SESSION['success'] = "Mix uploaded successfully and is pending approval.";
|
||
header("Location: profile.php");
|
||
exit;
|
||
}
|
||
|
||
require_once 'includes/header.php';
|
||
|
||
// Load available genres and DJs for the form
|
||
$db = new Database($config);
|
||
$genresObj = new DJMixHosting\Genres($db);
|
||
$allGenres = $genresObj->get_all_genres();
|
||
$djsObj = new DJMixHosting\DJs($db);
|
||
$allDJs = $djsObj->get_all_djs();
|
||
|
||
?>
|
||
|
||
<section class="upload-details-section py-5">
|
||
<div class="container">
|
||
<h2 class="mb-4">Enter Mix Details</h2>
|
||
<?php
|
||
if(isset($_SESSION['error'])) {
|
||
echo '<div class="alert alert-danger">' . htmlspecialchars($_SESSION['error']) . '</div>';
|
||
unset($_SESSION['error']);
|
||
}
|
||
?>
|
||
<div class="card mb-4">
|
||
<div class="card-body">
|
||
<h5>File Summary</h5>
|
||
<p><strong>Original Name:</strong> <?php echo htmlspecialchars($uploadTask['original_name']); ?></p>
|
||
<p><strong>File Type:</strong> <?php echo htmlspecialchars(strtoupper($uploadTask['file_type'])); ?></p>
|
||
<p><strong>Size:</strong> <?php echo round($uploadTask['size'] / 1024, 2); ?> KB</p>
|
||
<?php if ($uploadTask['file_type'] === 'mp3'): ?>
|
||
<p><strong>Duration:</strong> <?php echo htmlspecialchars($uploadTask['metadata']['duration']); ?> seconds</p>
|
||
<?php elseif ($uploadTask['file_type'] === 'zip'): ?>
|
||
<p><strong>Total Duration:</strong> <?php echo htmlspecialchars($uploadTask['metadata']['total_duration']); ?> seconds</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<form action="upload_details.php" method="post" class="needs-validation" novalidate>
|
||
<div class="mb-3">
|
||
<label for="title" class="form-label">Mix Title</label>
|
||
<input type="text" class="form-control" id="title" name="title" required>
|
||
</div>
|
||
<div class="mb-3">
|
||
<label for="description" class="form-label">Mix Description</label>
|
||
<textarea class="form-control" id="description" name="description" rows="3"></textarea>
|
||
</div>
|
||
<div class="mb-3">
|
||
<label for="recorded" class="form-label">Recorded Date</label>
|
||
<input type="date" class="form-control" id="recorded" name="recorded" required>
|
||
</div>
|
||
<div class="mb-3">
|
||
<label for="genres" class="form-label">Select Genres (type to search)</label>
|
||
<select class="form-select" id="genres" name="genres[]" multiple required>
|
||
<?php foreach ($allGenres as $genre): ?>
|
||
<option value="<?php echo htmlspecialchars($genre['id']); ?>"><?php echo htmlspecialchars($genre['name']); ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<div class="mb-3">
|
||
<label class="form-label">Select DJs (Maximum 3)</label>
|
||
<div class="row">
|
||
<div class="col">
|
||
<select class="form-select" name="dj1" required>
|
||
<option value="">Select DJ 1</option>
|
||
<?php foreach ($allDJs as $dj): ?>
|
||
<option value="<?php echo htmlspecialchars($dj['id']); ?>"><?php echo htmlspecialchars($dj['name']); ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<div class="col">
|
||
<select class="form-select" name="dj2">
|
||
<option value="">Select DJ 2 (Optional)</option>
|
||
<?php foreach ($allDJs as $dj): ?>
|
||
<option value="<?php echo htmlspecialchars($dj['id']); ?>"><?php echo htmlspecialchars($dj['name']); ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<div class="col">
|
||
<select class="form-select" name="dj3">
|
||
<option value="">Select DJ 3 (Optional)</option>
|
||
<?php foreach ($allDJs as $dj): ?>
|
||
<option value="<?php echo htmlspecialchars($dj['id']); ?>"><?php echo htmlspecialchars($dj['name']); ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<button type="submit" class="btn btn-primary">Submit Mix</button>
|
||
</form>
|
||
</div>
|
||
</section>
|
||
|
||
<?php require_once 'includes/footer.php'; ?>
|