593 lines
29 KiB
PHP
593 lines
29 KiB
PHP
<?php
|
|
|
|
require_once 'includes/globals.php';
|
|
require_once 'vendor/autoload.php';
|
|
|
|
use DJMixHosting\Database;
|
|
use DJMixHosting\Genre;
|
|
use DJMixHosting\Mix;
|
|
use DJMixHosting\Mixshow;
|
|
use DJMixHosting\Playcount;
|
|
|
|
$db = new Database($config);
|
|
$mixFound = false;
|
|
if (isset($_GET['mix']) && $_GET['mix'] != "") {
|
|
$mix = new Mix($_GET['mix'], $db);
|
|
if ($mix->get_name() != "") {
|
|
$mixFound = true;
|
|
$title = $mix->get_name();
|
|
} else {
|
|
$title = $locale['notfound'];
|
|
}
|
|
} else {
|
|
$title = $locale['notfound'];
|
|
}
|
|
|
|
// if this is a playcount PUT request, update the playcount
|
|
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
|
|
$data = json_decode(file_get_contents('php://input'), true);
|
|
if (isset($data['mix']) && $data['mix'] != "") {
|
|
$playcount = new Playcount($data['mix'], $db);
|
|
$playcount->updatePlaycount();
|
|
}
|
|
}
|
|
require_once 'includes/header.php'; ?>
|
|
<section>
|
|
<div class="container py-5">
|
|
<div class="row">
|
|
<div class="col">
|
|
<nav aria-label="breadcrumb" class="bg-body-tertiary rounded-3 p-3 mb-4">
|
|
<ol class="breadcrumb mb-0">
|
|
<li class="breadcrumb-item"><a href="/"><?php echo $locale['home']; ?></a></li>
|
|
<li class="breadcrumb-item"><a href="/mix"><?php echo $locale['mixes']; ?></a></li>
|
|
<li class="breadcrumb-item active"
|
|
aria-current="page"><?php
|
|
if (isset($mix) && $mix->get_name() != "") {
|
|
echo $mix->get_name();
|
|
} else {
|
|
echo $locale['notfound'];
|
|
}
|
|
?></li>
|
|
</ol>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if ($mixFound): ?>
|
|
<div class="row">
|
|
<div class="col-lg-4">
|
|
<div class="card mb-4">
|
|
<div class="card-body bg-body-secondary text-center">
|
|
<?php
|
|
if ($mix->get_img() != "") {
|
|
echo "<img src='" . $mix->get_img() . "' alt='avatar' class='img-fluid' style='width: 150px;'>";
|
|
} ?>
|
|
<h1 class="my-3 fs-4"><?php echo $mix->get_name();
|
|
?></h1>
|
|
<?php
|
|
if ($mix->get_description() != "") {
|
|
echo "<h2 class='text-muted mb-4 fs-6'>" . $mix->get_description() . "</h2>";
|
|
}
|
|
?>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="card mb-4">
|
|
<div class="card-body bg-body-secondary text-center">
|
|
<?php
|
|
if ($mix->is_download_only()) {
|
|
echo "<a href='/mix/" . $mix->get_slug() . "/download" . "' class='btn btn-primary'>" . $locale['download'] . "</a>";
|
|
} else {
|
|
?>
|
|
<div id="audio-player">
|
|
<audio id="audio" src="<?php echo $mix->get_url(); ?>"></audio>
|
|
<div class="player-controls">
|
|
<button id="play-pause-btn">
|
|
<i class="fas fa-play" style="font-size: 12px;"></i>
|
|
</button>
|
|
<input type="range" id="seek-bar" value="0">
|
|
</div>
|
|
<div id="time-display">
|
|
<span id="current-time">0:00</span> / <span id="duration">0:00</span>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
|
|
|
|
}
|
|
|
|
?>
|
|
</div>
|
|
</div>
|
|
<div class="card mb-4">
|
|
<div class="card-body bg-body-secondary text-center ">
|
|
<button type="button" id="shareBtn" class="w-100 mb-2 btn btn-secondary"
|
|
data-bs-toggle="modal" data-bs-target="#shareModal">
|
|
<?php echo $locale['share']; ?>
|
|
</button>
|
|
|
|
<?php if (!$mix->is_download_only()) : ?>
|
|
<a href="<?php
|
|
|
|
echo "/mix/" . $mix->get_slug() . "/download";
|
|
|
|
?>"
|
|
class="btn btn-primary w-100 mb-2"><?php echo $locale['download']; ?></a>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-8">
|
|
<div class="card mb-4">
|
|
<div class="card-body bg-body-secondary">
|
|
<div class="row">
|
|
<div class="col-sm-3">
|
|
<p class="mb-0"><?php echo $locale['mixname'] ?></p>
|
|
</div>
|
|
<div class="col-sm-9">
|
|
<p class="text-muted mb-0"><?php echo $mix->get_name(); ?></p>
|
|
</div>
|
|
</div>
|
|
<hr>
|
|
<div class="row">
|
|
<div class="col-sm-3">
|
|
<p class="mb-0"><?php echo $locale['djs'] ?></p>
|
|
</div>
|
|
<div class="col-sm-9">
|
|
<p class="text-muted mb-0">
|
|
<?php
|
|
|
|
// loop through the $mix['djs'] array and output them in comma separated format
|
|
$djs = $mix->get_djs();
|
|
$djCount = count($djs);
|
|
$i = 0;
|
|
foreach ($djs as $dj) {
|
|
echo "<a href='/dj/";
|
|
echo $dj->getSlug();
|
|
echo "'>" . $dj->getName() . "</a>";
|
|
if ($i < $djCount - 1) {
|
|
echo ", ";
|
|
}
|
|
$i++;
|
|
}
|
|
|
|
?>
|
|
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
$genres = $mix->get_genres();
|
|
$genreCount = count($genres);
|
|
if ($genreCount > 0) {
|
|
?>
|
|
<hr>
|
|
<div class="row">
|
|
<div class="col-sm-3">
|
|
<p class="mb-0"><?php echo $locale['genres'] ?></p>
|
|
</div>
|
|
<div class="col-sm-9">
|
|
<p class="text-muted mb-0">
|
|
<?php
|
|
$i = 0;
|
|
foreach ($genres as $genre) {
|
|
$genre = new Genre($genre, $db);
|
|
echo "<a href='/genre/";
|
|
echo $genre->get_slug();
|
|
echo "'>" . $genre->get_name() . "</a>";
|
|
if ($i < $genreCount - 1) {
|
|
echo ", ";
|
|
}
|
|
$i++;
|
|
}
|
|
?>
|
|
</div>
|
|
</div><?php } ?>
|
|
|
|
<?php
|
|
$mixshows = $mix->get_mixshow();
|
|
$mixshowsCount = count($mixshows);
|
|
if ($mixshowsCount > 0) {
|
|
?>
|
|
<hr>
|
|
<div class="row">
|
|
<div class="col-sm-3">
|
|
<p class="mb-0"><?php echo $locale['mixshow'] ?></p>
|
|
</div>
|
|
<div class="col-sm-9">
|
|
<p class="text-muted mb-0">
|
|
<?php
|
|
$i = 0;
|
|
foreach ($mixshows as $mixshow) {
|
|
$mixshow = new Mixshow($mixshow, $db);
|
|
echo "<a href='/mixshow/";
|
|
echo $mixshow->get_slug();
|
|
echo "'>" . $mixshow->get_name() . "</a>";
|
|
if ($i < $mixshowsCount - 1) {
|
|
echo ", ";
|
|
}
|
|
$i++;
|
|
}
|
|
?>
|
|
</div>
|
|
</div><?php } ?>
|
|
<hr>
|
|
<div class="row">
|
|
<div class="col-sm-3">
|
|
<p class="mb-0"><?php echo $locale['duration'] ?></p>
|
|
</div>
|
|
<div class="col-sm-9">
|
|
<p class="text-muted mb-0">
|
|
<?php
|
|
$time = $mix->get_duration();
|
|
// Decide the correct singular or plural term
|
|
$hour_text = $time['h'] == 1 ? $locale['hour'] : $locale['hours'];
|
|
$minute_text = $time['m'] == 1 ? $locale['minute'] : $locale['minutes'];
|
|
$second_text = $time['s'] == 1 ? $locale['second'] : $locale['seconds'];
|
|
|
|
// Output the time, skipping hours if it is less than one hour
|
|
if ($time['h'] > 0) {
|
|
// If there are hours, always show hours.
|
|
echo $time['h'] . " " . $hour_text;
|
|
if ($time['m'] > 0) {
|
|
// Show minutes only if they are greater than 0.
|
|
echo ", " . $time['m'] . " " . $minute_text;
|
|
}
|
|
// Always show seconds, regardless of minutes.
|
|
echo ", " . $time['s'] . " " . $second_text;
|
|
} else {
|
|
// No hours, check minutes.
|
|
if ($time['m'] != 0) {
|
|
echo $time['m'] . " " . $minute_text . ", " . $time['s'] . " " . $second_text;
|
|
} else {
|
|
// Only seconds to show.
|
|
echo $time['s'] . " " . $second_text;
|
|
}
|
|
}
|
|
echo " (" . $time['t'] . ")";
|
|
?>
|
|
|
|
</div>
|
|
</div>
|
|
<?php if ($mix->get_recorded() != ""): ?>
|
|
<hr>
|
|
<div class="row">
|
|
<div class="col-sm-3">
|
|
<p class="mb-0"><?php echo $locale['recorded'] ?></p>
|
|
</div>
|
|
<div class="col-sm-9">
|
|
<p class="text-muted mb-0">
|
|
<?php echo $mix->get_recorded(); ?>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
<?php if ($mix->get_created() != ""): ?>
|
|
<hr>
|
|
<div class="row">
|
|
<div class="col-sm-3">
|
|
<p class="mb-0"><?php echo $locale['added'] ?></p>
|
|
</div>
|
|
<div class="col-sm-9">
|
|
<p class="text-muted mb-0">
|
|
<?php echo $mix->get_created(); ?>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
<hr>
|
|
<div class="row">
|
|
<div class="col-sm-3">
|
|
<p class="mb-0"><?php echo $locale['downloads'] ?></p>
|
|
</div>
|
|
<div class="col-sm-9">
|
|
<p class="text-muted mb-0">
|
|
<?php echo $mix->get_downloads(); ?>
|
|
</div>
|
|
</div>
|
|
<hr>
|
|
<div class="row">
|
|
<div class="col-sm-3">
|
|
<p class="mb-0"><?php echo $locale['plays'] ?></p>
|
|
</div>
|
|
<div class="col-sm-9">
|
|
<p class="text-muted mb-0">
|
|
<?php echo $mix->get_plays(); ?>
|
|
</div>
|
|
</div>
|
|
<?php if ($mix->get_updated() != ""): ?>
|
|
<hr>
|
|
<div class="row">
|
|
<div class="col-sm-3">
|
|
<p class="mb-0"><?php echo $locale['lastupdated'] ?></p>
|
|
</div>
|
|
<div class="col-sm-9">
|
|
<p class="text-muted mb-0">
|
|
<?php echo $mix->get_updated(); ?>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const audioElement = document.querySelector('audio');
|
|
|
|
if ('mediaSession' in navigator) {
|
|
navigator.mediaSession.metadata = new MediaMetadata({
|
|
title: '<?php echo addslashes($mix->get_name()); ?>',
|
|
artist: '<?php
|
|
$djs = $mix->get_djs();
|
|
$djCount = count($djs);
|
|
$i = 0;
|
|
$djnamelist = [];
|
|
foreach ($djs as $dj) {
|
|
$djnamelist[] = $dj->getName();
|
|
$i++;
|
|
}
|
|
|
|
echo addslashes(implode(", ", $djnamelist));?>',
|
|
album: '<?php echo addslashes($mix->get_name()); ?>',
|
|
artwork: [
|
|
{
|
|
src: '<?php echo $mix->get_cover('small'); ?>',
|
|
sizes: '96x96',
|
|
type: 'image/jpeg'
|
|
},
|
|
{
|
|
src: '<?php echo $mix->get_cover('large'); ?>',
|
|
sizes: '128x128',
|
|
type: 'image/jpeg'
|
|
}
|
|
]
|
|
});
|
|
// Define action handlers
|
|
navigator.mediaSession.setActionHandler('play', function () {
|
|
audioElement.play();
|
|
});
|
|
navigator.mediaSession.setActionHandler('pause', function () {
|
|
audioElement.pause();
|
|
});
|
|
|
|
audioElement.addEventListener('timeupdate', () => {
|
|
// Update the position state
|
|
navigator.mediaSession.setPositionState({
|
|
duration: audioElement.duration,
|
|
playbackRate: audioElement.playbackRate,
|
|
position: audioElement.currentTime
|
|
});
|
|
});
|
|
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
if ($mix->get_tracklist() != []) {
|
|
echo "<div class='card mb-4 bg-body-secondary'>";
|
|
echo "<div class='card-body '>";
|
|
echo "<p class='mb-4'><span class='text-primary font-italic me-1'>" . $locale['tracklist'] . "</span></p>";
|
|
echo "<ul class='list-group list-group-flush rounded-3 bg-body-secondary'>";
|
|
$tracklist = $mix->get_tracklist();
|
|
foreach ($tracklist as $track) {
|
|
echo "<li class='list-group-item bg-body-secondary d-flex justify-content-between align-items-center'>";
|
|
echo $track;
|
|
echo "</li>";
|
|
}
|
|
echo "</ul>";
|
|
echo "</div>";
|
|
echo "</div>";
|
|
}
|
|
|
|
?>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="shareModal" tabindex="-1" aria-labelledby="shareModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="shareModalLabel"><?php echo $locale['share']; ?></h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<?php
|
|
$url = 'https://utahsdjs.com/mix/' . $_GET['mix'];
|
|
$utm_params = '?utm_source=website&utm_medium=share_modal&utm_campaign=sharing';
|
|
$share_url = urlencode($url . $utm_params);
|
|
?>
|
|
<a href="#" id="copyLinkBtn" class="btn btn-secondary w-100 mb-2">Copy URL</a>
|
|
<a href="https://www.facebook.com/sharer/sharer.php?u=<?php echo $share_url; ?>"
|
|
target="_blank" class="btn btn-primary w-100 mb-2" onclick="hideModal()">Share to
|
|
Facebook</a>
|
|
<a href="https://twitter.com/intent/tweet?url=<?php echo $share_url; ?>"
|
|
target="_blank" class="btn btn-dark w-100 mb-2" onclick="hideModal()">Share to X (formerly Twitter)</a>
|
|
<a href="https://www.instagram.com/" target="_blank" class="btn btn-danger w-100"
|
|
onclick="hideModal()">Share to Instagram</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<script>
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
var shareBtn = document.getElementById('shareBtn');
|
|
var shareModal = new bootstrap.Modal(document.getElementById('shareModal'));
|
|
var copyLinkBtn = document.getElementById("copyLinkBtn");
|
|
var urlToCopy = window.location.href + '?utm_source=website&utm_medium=share_modal&utm_campaign=sharing';
|
|
|
|
shareBtn.addEventListener('click', function () {
|
|
shareModal.show();
|
|
});
|
|
|
|
copyLinkBtn.onclick = function () {
|
|
navigator.clipboard.writeText(urlToCopy).then(function () {
|
|
alert('URL copied to clipboard');
|
|
shareModal.hide();
|
|
}, function (err) {
|
|
alert('Failed to copy URL: ' + err);
|
|
});
|
|
}
|
|
|
|
window.hideModal = function () {
|
|
shareModal.hide();
|
|
}
|
|
});
|
|
|
|
|
|
// when the audio is played, send a PUT request to the page to update the playcount
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const audioElement = document.querySelector('audio');
|
|
audioElement.addEventListener('play', function () {
|
|
fetch(window.location.href, {
|
|
method: 'PUT',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({mix: '<?php echo $mix->get_id(); ?>'}),
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log('Success:', data);
|
|
})
|
|
.catch((error) => {
|
|
console.error('Error:', error);
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
|
|
|
|
<script type="application/ld+json">
|
|
{
|
|
"@context": "https://schema.org",
|
|
"@type": "MusicRecording",
|
|
"name": "<?php echo $mix->get_name(); ?>",
|
|
"byArtist": {
|
|
"@type": "MusicGroup",
|
|
"name": "<?php
|
|
$djs = $mix->get_djs();
|
|
echo $djs[0]->getName();
|
|
?>",
|
|
"image": "<?php echo $djs[0]->getImg(); ?>"
|
|
},
|
|
"inAlbum": {
|
|
"@type": "MusicAlbum",
|
|
"name": "<?php echo $mix->get_name(); ?>"
|
|
},
|
|
"genre": "<?php
|
|
$genre = new Genre($mix->get_genres()[0], $db);
|
|
echo $genre->get_name();
|
|
?>",
|
|
"url": "<?php echo "https://utahsdjs.com/mix/" . $mix->get_slug(); ?>",
|
|
"image": "<?php echo $mix->get_cover(); ?>",
|
|
|
|
"duration": "<?php echo $mix->get_duration()['S']; ?>",
|
|
<?php
|
|
// if recorded is empty, use created; if created is empty, use 2008-01-01;
|
|
if (empty($mix->get_recorded())) {
|
|
if (empty($mix->get_created())) {
|
|
$recorded = '2008-01-01 00:00:00';
|
|
} else {
|
|
$recorded = $mix->get_created();
|
|
}
|
|
} else {
|
|
$recorded = $mix->get_recorded();
|
|
|
|
} ?>
|
|
|
|
"datePublished": "<?php echo $recorded; ?>",
|
|
"description": "<?php
|
|
|
|
if (empty($mix->get_description())) {
|
|
$description = 'Listen to ' . $mix->get_name() . ' on Utah\'s DJs.';
|
|
}
|
|
echo $mix->get_description(); ?>",
|
|
"interactionStatistic": {
|
|
"@type": "InteractionCounter",
|
|
"interactionType": "https://schema.org/ListenAction",
|
|
"userInteractionCount": "<?php echo $mix->get_plays() + $mix->get_downloads() ?>",
|
|
"url": "<?php echo "https://utahsdjs.com/mix/" . $mix->get_slug() . "/download"; ?>"
|
|
}
|
|
}
|
|
|
|
|
|
</script>
|
|
<script>
|
|
$(document).ready(function() {
|
|
const audio = $('#audio')[0];
|
|
const playPauseBtn = $('#play-pause-btn');
|
|
const playPauseIcon = playPauseBtn.find('i');
|
|
const seekBar = $('#seek-bar');
|
|
const currentTime = $('#current-time');
|
|
const duration = $('#duration');
|
|
|
|
function formatTime(seconds) {
|
|
const hours = Math.floor(seconds / 3600);
|
|
const minutes = Math.floor((seconds % 3600) / 60);
|
|
seconds = Math.floor(seconds % 60);
|
|
|
|
if (hours > 0) {
|
|
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
|
} else {
|
|
return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
|
}
|
|
}
|
|
|
|
function togglePlayPause() {
|
|
if (audio.paused) {
|
|
audio.play();
|
|
playPauseIcon.removeClass('fa-play').addClass('fa-pause');
|
|
} else {
|
|
audio.pause();
|
|
playPauseIcon.removeClass('fa-pause').addClass('fa-play');
|
|
}
|
|
}
|
|
|
|
audio.addEventListener('loadedmetadata', function() {
|
|
seekBar.attr('max', audio.duration);
|
|
duration.text(formatTime(audio.duration));
|
|
});
|
|
|
|
playPauseBtn.click(togglePlayPause);
|
|
|
|
seekBar.on('input', function() {
|
|
const time = seekBar.val();
|
|
audio.currentTime = time;
|
|
});
|
|
|
|
audio.addEventListener('timeupdate', function() {
|
|
seekBar.val(audio.currentTime);
|
|
currentTime.text(formatTime(audio.currentTime));
|
|
});
|
|
|
|
audio.addEventListener('ended', function() {
|
|
playPauseIcon.removeClass('fa-pause').addClass('fa-play');
|
|
});
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
<?php else: ?>
|
|
<div class="row">
|
|
<div class="col">
|
|
<div class="alert alert-danger" role="alert">
|
|
<?php echo $locale['mixNotFound']; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php endif;
|
|
|
|
?>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<?php require_once 'includes/footer.php'; ?>
|