I'm in a rush to release so I am adding features that are needed to make it usable.

This commit is contained in:
Cody Cook 2025-02-17 22:03:33 -08:00
commit 4c2857b445
25 changed files with 2475 additions and 3475 deletions

245
upload_details.php Normal file
View file

@ -0,0 +1,245 @@
<?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'; ?>