Check-in; adding features like mixshow and google analytics.

This commit is contained in:
Cody Cook 2024-05-02 19:21:24 -07:00
commit 8288ebc67a
50 changed files with 1492 additions and 483 deletions

71
classes/CustomCDN.php Normal file
View file

@ -0,0 +1,71 @@
<?php
class CustomCDN
{
private $space;
private $region;
private $storageType;
private $accessKey;
private $secretKey;
private $public = false;
public function __construct($space, $region, $storageType, $accessKey, $secretKey)
{
$this->space = $space;
$this->region = $region;
$this->storageType = $storageType;
$this->accessKey = $accessKey;
$this->secretKey = $secretKey;
}
public function uploadFile($filePath, $spacePath)
{
$file = basename($filePath);
$date = gmdate('D, d M Y H:i:s T');
if ($this->public) {
$acl = "x-amz-acl:public-read";
} else {
$acl = "x-amz-acl:private";
}
$contentType = $this->getContentType($filePath);
$storageClass = "x-amz-storage-class:{$this->storageType}";
$stringToSign = "PUT\n\n{$contentType}\n{$date}\n{$acl}\n{$storageClass}\n/{$this->space}{$spacePath}{$file}";
$signature = base64_encode(hash_hmac('sha1', $stringToSign, $this->secretKey, true));
$headers = ["Host: {$this->space}.{$this->region}.digitaloceanspaces.com", "Date: {$date}", "Content-Type: {$contentType}", "{$storageClass}", "{$acl}", "Authorization: AWS {$this->accessKey}:{$signature}"];
$ch = curl_init("https://{$this->space}.{$this->region}.digitaloceanspaces.com{$spacePath}{$file}");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, fopen($filePath, 'r'));
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filePath));
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
return $error ? $error : $response;
}
private function getContentType($filePath)
{
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $filePath);
finfo_close($finfo);
return $mimeType ?: 'application/octet-stream';
}
public function setPublic()
{
$this->public = true;
}
public function setPrivate()
{
$this->public = false;
}
}
?>

View file

@ -17,6 +17,7 @@ class DJ
private string $updated = ""; private string $updated = "";
private string $claimed_by = ""; private string $claimed_by = "";
private mysqli $db; private mysqli $db;
private array $mixes = [];
public function __construct($value, $db) public function __construct($value, $db)
@ -118,8 +119,6 @@ class DJ
if (isset($dj['claimed_by']) && $dj['claimed_by'] != null) { if (isset($dj['claimed_by']) && $dj['claimed_by'] != null) {
// TODO: pull some quick data on the user who claimed this DJ // TODO: pull some quick data on the user who claimed this DJ
$this->claimed = true; $this->claimed = true;
} }
if (isset($dj['created'])) { if (isset($dj['created'])) {
@ -129,6 +128,8 @@ class DJ
$this->updated = $dj['lastupdated']; $this->updated = $dj['lastupdated'];
} }
$this->load_dj_mixes();
return true; return true;
} else { } else {
return false; return false;
@ -208,5 +209,24 @@ class DJ
return $this->claimed; return $this->claimed;
} }
private function load_dj_mixes(): void
{
$stmt = $this->db->prepare("SELECT * FROM mix WHERE dj1 = ? OR dj2 = ? OR dj3 = ?");
$stmt->bind_param("iii", $this->id, $this->id, $this->id);
$stmt->execute();
$result = $stmt->get_result();
$mixes = [];
while ($mix = $result->fetch_assoc()) {
$mixes[] = $mix;
}
$stmt->close();
$this->mixes = $mixes;
}
public function get_dj_mixes()
{
return $this->mixes;
}
} }

View file

@ -3,12 +3,13 @@
class Genre class Genre
{ {
private $id = -1 ; private $id = -1;
private $enabled = ""; private $enabled = "";
private $count = 0; private $count = 0;
private $name = ""; private $name = "";
private $slug = ""; private $slug = "";
private $db = ""; private $db = "";
private $mixes = [];
public function __construct($value, $db) public function __construct($value, $db)
{ {
@ -22,6 +23,7 @@ class Genre
return $this->load_by_slug(); return $this->load_by_slug();
} }
} }
private function load_by_id(): bool private function load_by_id(): bool
{ {
$genre = $this->get_genre_by_id(); $genre = $this->get_genre_by_id();
@ -30,6 +32,7 @@ class Genre
$this->count = $genre['count']; $this->count = $genre['count'];
$this->name = $genre['name']; $this->name = $genre['name'];
$this->slug = $genre['slug']; $this->slug = $genre['slug'];
$this->mixes = $this->load_mixes();
return true; return true;
} else { } else {
return false; return false;
@ -56,6 +59,7 @@ class Genre
$this->enabled = $genre['enabled']; $this->enabled = $genre['enabled'];
$this->count = $genre['count']; $this->count = $genre['count'];
$this->name = $genre['name']; $this->name = $genre['name'];
$this->mixes = $this->load_mixes();
return true; return true;
} }
return false; return false;
@ -98,4 +102,23 @@ class Genre
return $this->count; return $this->count;
} }
public function get_mixes(): array
{
return $this->mixes;
}
private function load_mixes(): array
{
$stmt = $this->db->prepare("SELECT mix_id FROM mix_meta WHERE attribute = 'genre' AND value = ?");
$stmt->bind_param("i", $this->id);
$stmt->execute();
$result = $stmt->get_result();
$mixes = [];
while ($row = $result->fetch_assoc()) {
$mixes[] = $row['mix_id'];
}
$stmt->close();
return $mixes;
}
} }

View file

@ -7,26 +7,32 @@ class Mix
private $enabled = false; private $enabled = false;
private $name = ""; private $name = "";
private $slug = ""; private $slug = "";
private $genre = [];
private $db = null; private $db = null;
private $description = ""; private $description = "";
private $cover = ""; private $cover = "";
private $url = ""; private $url = "";
private $seconds = 0; private $seconds = 0;
private $mediaplayer = false; private $download_only = true;
private $djs = []; private $djs = [];
private $genres = []; private $genres = [];
private $recorded; private $recorded;
private $downloads = 0;
private $created; private $created;
private $updated; private $updated;
private $playcount = 0; private $playcount = 0;
private $tracklist = []; private $tracklist = [];
private $loadDJs = true;
private $related_mixes = [];
private $duration = [];
private $mixshow = [];
public function __construct($value, $db) public function __construct($value, $db, $loadDJs = true)
{ {
$this->db = $db; $this->db = $db;
// echo the type of value
if (ctype_digit((string)$value)) { if (ctype_digit((string)$value)) {
$this->id = (int)$value; $this->id = (int)$value;
return $this->load_by_id(); return $this->load_by_id();
@ -40,7 +46,7 @@ class Mix
private function load_by_id(): bool private function load_by_id(): bool
{ {
$mix = $this->get_mix_by_id(); $mix = $this->get_mix_by_id();
if ($mix && $mix['name'] != "") { if ($mix && $mix['title'] != "") {
return $this->build_mix($mix); return $this->build_mix($mix);
} else { } else {
return false; return false;
@ -58,122 +64,6 @@ class Mix
return $mix; return $mix;
} }
private function get_mix_genres()
{
$stmt = $this->db->prepare("SELECT * FROM mix_meta WHERE attribute = 'genre' AND mix_id = ?");
$stmt->bind_param("i", $this->id);
$stmt->execute();
$result = $stmt->get_result();
$genres = $result->fetch_all(MYSQLI_ASSOC);
$stmt->close();
return $genres;
}
private function get_playcount()
{
$stmt = $this->db->prepare("SELECT value FROM mix_meta WHERE attribute = 'playcount' AND mix_id = ?");
$stmt->bind_param("i", $this->id);
$stmt->execute();
$result = $stmt->get_result();
$genres = $result->fetch_all(MYSQLI_ASSOC);
$stmt->close();
return $genres;
}
private function load_by_slug(): bool
{
$mix = $this->get_mix_by_slug();
if ($mix['title'] != "") {
return $this->build_mix($mix);
} else {
return false;
}
}
private function get_mix_by_slug()
{
$stmt = $this->db->prepare("SELECT * FROM mix WHERE slug = ?");
$stmt->bind_param("s", $this->slug);
$stmt->execute();
$result = $stmt->get_result();
$mix = $result->fetch_assoc();
$stmt->close();
return $mix;
}
private function load_mix_genres()
{
$genres = $this->get_mix_genres();
if (count($genres) == 0) {
$this->genres = [];
} else {
// iterate through the genres; add each of the rest to the array
$this->genres = [];
require_once 'Genre.php';
foreach ($genres as $genre) {
$genre = new Genre($genre['value'], $this->db);
if ($genre->get_id() != -1) {
$this->genres[] = ['id' => $genre->get_id(), 'name' => $genre->get_name(), 'slug' => $genre->get_slug()];
}
}
}
}
private function evaluate_tracklist(): array
{
if (empty($this->tracklist)){
return [];
} else {
// if the first item in the array is also an array, then return it
if (is_array($this->tracklist[0]['value'])){
return $this->tracklist[0]['value'];
} else {
return explode("\n", $this->tracklist[0]['value']);
}
}
}
private function load_mix_tracklist()
{
$stmt = $this->db->prepare("SELECT value FROM mix_meta WHERE attribute = 'tracklist' AND mix_id = ?");
$stmt->bind_param("i", $this->id);
$stmt->execute();
$result = $stmt->get_result();
$tracklist = $result->fetch_all(MYSQLI_ASSOC);
$stmt->close();
return $tracklist;
}
public function get_img(): string
{
return $this->cover;
}
public function get_id(): int
{
return $this->id;
}
public function get_name(): string
{
return $this->name;
}
public function get_slug(): string
{
return $this->slug;
}
public function get_djs(){
return $this->djs;
}
/** /**
* @param $mix * @param $mix
* @return true * @return true
@ -198,29 +88,157 @@ class Mix
} }
$this->url = $mix['url']; $this->url = $mix['url'];
$this->seconds = $mix['seconds']; $this->seconds = $mix['seconds'];
$this->mediaplayer = $mix['mediaplayer']; $this->duration = $this->configure_duration();
$this->download_only = $mix['mediaplayer'];
$this->recorded = $mix['recorded']; $this->recorded = $mix['recorded'];
$this->created = $mix['created']; $this->created = $mix['created'];
$this->updated = $mix['lastupdated']; $this->updated = $mix['lastupdated'];
$this->enabled = $mix['pending']; $this->enabled = $mix['pending'];
require 'DJ.php'; if ($this->loadDJs) {
$this->djs[] = new DJ($mix['dj1'], $this->db); require_once 'DJ.php';
if ($mix['dj2'] != null) $this->djs[] = new DJ($mix['dj1'], $this->db);
$this->djs[] = new DJ($mix['dj2'], $this->db); if ($mix['dj2'] != null) $this->djs[] = new DJ($mix['dj2'], $this->db);
if ($mix['dj3'] != null) if ($mix['dj3'] != null) $this->djs[] = new DJ($mix['dj3'], $this->db);
$this->djs[] = new DJ($mix['dj3'], $this->db);
// delete any nulls from the array $this->djs = array_filter($this->djs);
$this->djs = array_filter($this->djs); }
$this->genre = $this->get_mix_genres(); $this->load_mix_meta();
$this->playcount = $this->get_playcount();
$this->tracklist = $this->load_mix_tracklist();
$this->tracklist = $this->evaluate_tracklist(); $this->tracklist = $this->evaluate_tracklist();
return true; return true;
} }
private function configure_duration(): array
{
$seconds = $this->seconds;
$hours = floor($seconds / 3600);
$minutes = floor(($seconds / 60) % 60);
$seconds = $seconds % 60;
// for 't', we need to show it as 01:02:03
if ($hours < 10) {
$hours0 = "0" . $hours;
} else {
$hours0 = $hours;
}
if ($minutes < 10) {
$minutes0 = "0" . $minutes;
} else {
$minutes0 = $minutes;
}
if ($seconds < 10) {
$seconds0 = "0" . $seconds;
} else {
$seconds0 = $seconds;
}
// if hours is 0, we don't need to show it
$time = $hours > 0 ? $hours0 . ":" . $minutes0 . ":" . $seconds0 : $minutes0 . ":" . $seconds0;
return ['h' => $hours, 'm' => $minutes, 's' => $seconds, 't' => $time, 'S' => $this->seconds];
}
private function load_mix_meta(): void
{
$stmt = $this->db->prepare("SELECT attribute,value FROM mix_meta WHERE mix_id = ?");
$stmt->bind_param("i", $this->id);
$stmt->execute();
$result = $stmt->get_result();
$meta = $result->fetch_all(MYSQLI_ASSOC);
$stmt->close();
foreach ($meta as $key => $value) {
if ($value['attribute'] == "genre") {
$this->genres[] = $value['value'];
unset($meta[$key]);
}
if ($value['attribute'] == "related") {
$this->related_mixes[] = $value['value'];
unset($meta[$key]);
}
if ($value['attribute'] == "playcount") {
$this->playcount = $value['value'];
unset($meta[$key]);
}
if ($value['attribute'] == "downloads") {
$this->downloads = $value['value'];
unset($meta[$key]);
}
if ($value['attribute'] == "tracklist") {
$this->tracklist = $value['value'];
unset($meta[$key]);
}
if ($value['attribute'] == "mixshow") {
$this->mixshow[] = $value['value'];
unset($meta[$key]);
}
}
}
private function evaluate_tracklist()
{
if (empty($this->tracklist)) {
return [];
} else {
// if the first item in the array is also an array, then return it
if (is_array($this->tracklist)) {
return $this->tracklist;
} else {
return explode("\n", (string)$this->tracklist);
}
}
}
private function load_by_slug(): bool
{
$mix = $this->get_mix_by_slug();
if ($mix['title'] != "") {
return $this->build_mix($mix);
} else {
return false;
}
}
private function get_mix_by_slug()
{
$stmt = $this->db->prepare("SELECT * FROM mix WHERE slug = ?");
$stmt->bind_param("s", $this->slug);
$stmt->execute();
$result = $stmt->get_result();
$mix = $result->fetch_assoc();
$stmt->close();
return $mix;
}
public function get_recorded()
{
return $this->recorded;
}
public function get_created()
{
return $this->created;
}
public function get_updated()
{
return $this->updated;
}
public function get_img(): string
{
return $this->cover;
}
public function get_djs()
{
return $this->djs;
}
public function get_description() public function get_description()
{ {
return $this->description; return $this->description;
@ -231,5 +249,66 @@ class Mix
return $this->tracklist; return $this->tracklist;
} }
public function get_genres()
{
return $this->genres;
}
public function get_seconds(): int
{
return $this->seconds;
}
public function is_download_only(): bool
{
return $this->download_only;
}
public function get_url(): string
{
return $this->url;
}
public function get_cover(): string
{
return $this->cover;
}
public function get_downloads(): int
{
return $this->downloads;
}
public function get_plays(): int
{
return $this->playcount;
}
public function get_id(): int
{
return $this->id;
}
public function get_name(): string
{
return $this->name;
}
public function get_slug(): string
{
return $this->slug;
}
public function get_duration(): array
{
return $this->duration;
}
public function get_mixshow(): array
{
return $this->mixshow;
}
} }

134
classes/Mixshow.php Normal file
View file

@ -0,0 +1,134 @@
<?php
class Mixshow
{
private $id = -1;
private $enabled = false;
private $name = "";
private $slug = "";
private $db = null;
private $description = "";
private $cover = "";
private $count;
private $mixes = [];
public function __construct($value, $db)
{
$this->db = $db;
if (ctype_digit((string)$value)) {
$this->id = (int)$value;
return $this->load_by_id();
} else {
$this->slug = $value;
return $this->load_by_slug();
}
}
private function load_by_id()
{
$mixshow = $this->get_mixshow_by_id();
if ($mixshow && $mixshow['title'] != "") {
return $this->build_mixshow($mixshow);
} else {
return false;
}
}
private function get_mixshow_by_id()
{
$stmt = $this->db->prepare("SELECT * FROM shows WHERE id = ?");
$stmt->bind_param("i", $this->id);
$stmt->execute();
$result = $stmt->get_result();
return $result->fetch_assoc();
}
private function build_mixshow($mixshow)
{
$this->id = $mixshow['id'];
$this->name = $mixshow['name'];
$this->slug = $mixshow['slug'];
$this->description = $mixshow['description'];
$this->cover = $mixshow['cover'];
$this->enabled = $mixshow['enabled'];
$this->count = $mixshow['count'];
$this->load_mixes();
return true;
}
private function load_mixes()
{
$stmt = $this->db->prepare("SELECT value FROM mix_meta WHERE value = ?");
$stmt->bind_param("i", $this->id);
$stmt->execute();
$result = $stmt->get_result();
$this->mixes = [];
while ($mix = $result->fetch_assoc()) {
$this->mixes[] = $mix;
}
}
private function load_by_slug()
{
$mixshow = $this->get_mixshow_by_slug();
if ($mixshow && $mixshow['title'] != "") {
return $this->build_mixshow($mixshow);
} else {
return false;
}
}
private function get_mixshow_by_slug()
{
$stmt = $this->db->prepare("SELECT * FROM shows WHERE slug = ?");
$stmt->bind_param("s", $this->slug);
$stmt->execute();
$result = $stmt->get_result();
return $result->fetch_assoc();
}
public function get_id()
{
return $this->id;
}
public function get_name()
{
return $this->name;
}
public function get_slug()
{
return $this->slug;
}
public function get_description()
{
return $this->description;
}
public function get_cover()
{
return $this->cover;
}
public function get_enabled()
{
return $this->enabled;
}
public function get_count()
{
return $this->count;
}
public function get_mixes()
{
return $this->mixes;
}
}

8
classes/S3.php Normal file
View file

@ -0,0 +1,8 @@
<?php
require_once 'vendor/autoload.php';
Class S3 extends Aws\S3\S3Client{
}

View file

@ -13,6 +13,7 @@
"require": { "require": {
"php": ">=8.2.0", "php": ">=8.2.0",
"yosymfony/toml": "*", "yosymfony/toml": "*",
"ext-mysqli": "*" "ext-mysqli": "*",
"ext-curl": "*"
} }
} }

202
dj.php
View file

@ -3,6 +3,8 @@
require 'includes/globals.php'; require 'includes/globals.php';
require_once 'classes/Database.php'; require_once 'classes/Database.php';
require_once 'classes/DJ.php'; require_once 'classes/DJ.php';
require_once 'classes/Genre.php';
require_once 'classes/Mix.php';
// if there's a query parameter named 'dj', load the DJ class // if there's a query parameter named 'dj', load the DJ class
$db = new Database($config); $db = new Database($config);
@ -13,6 +15,7 @@ if (isset($_GET['dj']) && $_GET['dj'] != "") {
$djFound = true; $djFound = true;
} }
} }
$title = $dj->get_name();
require_once 'includes/header.php'; require_once 'includes/header.php';
?> ?>
<section style="background-color: #eee;"> <section style="background-color: #eee;">
@ -27,7 +30,6 @@ require_once 'includes/header.php';
aria-current="page"><?php aria-current="page"><?php
if ($dj && $dj->get_name() != "") { if ($dj && $dj->get_name() != "") {
echo $dj->get_name(); echo $dj->get_name();
} else { } else {
echo $locale['notfound']; echo $locale['notfound'];
} }
@ -38,88 +40,142 @@ require_once 'includes/header.php';
</div> </div>
<?php if ($djFound): ?> <?php if ($djFound): ?>
<div class="row"> <div class="row">
<div class="col-lg-4"> <div class="col-lg-4">
<div class="card mb-4"> <div class="card mb-4">
<div class="card-body text-center"> <div class="card-body text-center">
<img src="<?php echo $dj->get_img(); ?>" <img src="<?php echo $dj->get_img(); ?>"
alt="avatar" alt="avatar"
class="rounded-circle img-fluid" style="width: 150px;"> class="rounded-circle img-fluid" style="width: 150px;">
<h5 class="my-3"><?php echo $dj->get_name(); <h5 class="my-3"><?php echo $dj->get_name();
?></h5> ?></h5>
<?php <?php
if ($dj->get_claimed()) { if ($dj->get_claimed()) {
echo '<p class="text-muted mb-1">'; echo '<p class="text-muted mb-1">';
echo "<i class='fa fa-user-shield' style='color: gold'>Claimed</i>"; echo "<i class='fa fa-user-shield' style='color: gold'>Claimed</i>";
echo "</p>"; echo "</p>";
} }
?>
</p>
<p class="text-muted mb-4">$location1</p>
<div class="d-flex justify-content-center mb-2">
<button type="button" data-mdb-button-init data-mdb-ripple-init class="btn btn-primary">
<?php echo $locale['follow']; ?>
</button>
<button type="button" data-mdb-button-init data-mdb-ripple-init
class="btn btn-outline-primary ms-1"><?php echo $locale['message']; ?>
</button>
</div>
</div>
</div>
<?php
if ($dj->get_socials() != []) {
?> ?>
<div class="card mb-4 mb-lg-0"> <div class="d-flex justify-content-center mb-2">
<div class="card-body p-0"> <button type="button" data-mdb-button-init data-mdb-ripple-init class="btn btn-primary">
<ul class="list-group list-group-flush rounded-3"> <?php echo $locale['follow']; ?>
<?php </button>
$socials = $dj->get_socials(); <button type="button" data-mdb-button-init data-mdb-ripple-init
foreach ($socials as $key => $value) { class="btn btn-outline-primary ms-1"><?php echo $locale['message']; ?>
echo social_line($key, $value); </button>
</div>
</div>
</div>
<?php
if ($dj->get_socials() != []) {
?>
<div class="card mb-4 mb-lg-0">
<div class="card-body p-0">
<ul class="list-group list-group-flush rounded-3">
<?php
$socials = $dj->get_socials();
foreach ($socials as $key => $value) {
echo social_line($key, $value);
}
?>
</ul>
</div>
</div>
<?php } ?>
</div>
<div class="col-lg-8">
<div class="card mb-4">
<div class="card-body">
<div class="row">
<div class="col-sm-3">
<p class="mb-0"><?php echo $locale['djName']; ?></p>
</div>
<div class="col-sm-9">
<p class="text-muted mb-0"><?php echo $dj->get_name(); ?></p>
</div>
</div>
<?php
if ($dj->get_bio() != "") {
echo box_line($locale['bio'], $dj->get_bio());
}
echo box_line($locale['lastupdated'], $dj->get_updated());
?>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="card mb-4">
<div class="card-body">
<?php
$mixes = $dj->get_dj_mixes();
$count = 0;
foreach ($mixes as $mix) {
$output = new Mix($mix['slug'], $db);
$genres = $output->get_genres();
$genrelist = [];
foreach ($genres as $genre) {
$genr = new Genre($genre, $db);
$genrelist[$genr->get_slug()] = $genr->get_name();
} }
?>
</ul> echo '<div class="row">'; // Start row for each mix
// Column for mix name and link
echo '<div class="col-md-4">';
echo '<p class="mb-0">';
echo '<a href="/mix.php?mix=' . $output->get_slug() . '">';
echo $output->get_name();
echo '</a>';
echo '</p>';
echo '</div>'; // End column
// Column for genres
echo '<div class="col-md-4">';
echo '<p class="mb-0">';
foreach ($genrelist as $slug => $name) {
echo ' <a href="/genre.php?genre=' . $slug . '">';
echo '<span class="">' . $name . '</span>';
echo '</a>';
}
echo '</p>';
echo '</div>'; // End column
// Column for duration
echo '<div class="col-md-4">';
echo '<p class="mb-0">';
$duration = $output->get_duration();
echo $duration['t'];
echo '</p>';
echo '</div>'; // End column
echo '</div>'; // End row
$count++;
// Add horizontal rule only if it's not the last mix
if ($count < count($mixes)) {
echo '<hr>';
}
}
?>
</div> </div>
</div> </div>
<?php } ?> </div>
</div> </div>
<div class="col-lg-8"> <?php else: ?>
<div class="card mb-4"> <div class="row">
<div class="card-body"> <div class="col">
<div class="row"> <div class="alert alert-danger" role="alert">
<div class="col-sm-3"> <?php echo $locale['djNotFound']; ?>
<p class="mb-0"><?php echo $locale['djName']; ?></p>
</div>
<div class="col-sm-9">
<p class="text-muted mb-0"><?php echo $dj->get_name(); ?></p>
</div>
</div> </div>
<?php
if ($dj->get_bio() != "") {
echo box_line($locale['bio'], $dj->get_bio());
}
echo box_line($locale['lastupdated'], $dj->get_updated());
?>
</div> </div>
</div> </div><?php endif;?>
</div>
</div> </div>
<?php else: ?> </div>
<div class="row">
<div class="col">
<div class="alert alert-danger" role="alert">
<?php echo $locale['djNotFound']; ?>
</div>
</div>
</div>
<?php endif;
?>
</div> </div>
</section> </section>
<?php require 'includes/footer.php'; ?> <?php require 'includes/footer.php'; ?>

View file

@ -6,6 +6,7 @@ require_once 'classes/DJs.php';
$db = new Database($config); $db = new Database($config);
$djs = new DJs($db); $djs = new DJs($db);
$title = $locale['djs'];
require_once 'includes/header.php'; require_once 'includes/header.php';
?> ?>
<section style="background-color: #eee;"> <section style="background-color: #eee;">

249
genre.php
View file

@ -3,6 +3,7 @@
require 'includes/globals.php'; require 'includes/globals.php';
require_once 'classes/Database.php'; require_once 'classes/Database.php';
require_once 'classes/Genre.php'; require_once 'classes/Genre.php';
require_once 'classes/Mix.php';
$genre = null; $genre = null;
$genreFound = false; $genreFound = false;
@ -17,166 +18,108 @@ if (isset($_GET['genre']) && $_GET['genre'] != "") {
} }
} }
$title = $genre->get_name();
require_once 'includes/header.php'; require_once 'includes/header.php';
?> ?>
<section style="background-color: #eee;"> <section style="background-color: #eee;">
<div class="container py-5"> <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="/genres.php"><?php echo $locale['genres']; ?></a></li>
<li class="breadcrumb-item active"
aria-current="page"><?php
if ($genre && $genre->get_name() != "") {
echo $genre->get_name();
} else {
echo $locale['notfound'];
}
?></li>
</ol>
</nav>
</div>
</div>
<?php if ($genreFound): ?>
<div class="row">
<div class="col-lg-4">
<div class="card mb-4">
<div class="card-body text-center">
<img src="<?php echo $genre->get_img(); ?>"
alt="avatar"
class="rounded-circle img-fluid" style="width: 150px;">
<h5 class="my-3"><?php echo $genre->get_name();
?></h5>
</p>
<div class="d-flex justify-content-center mb-2">
<button type="button" data-mdb-button-init data-mdb-ripple-init class="btn btn-primary">
<?php echo $locale['follow']; ?>
</button>
</div>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="card mb-4">
<div class="card-body">
<div class="row">
<div class="col-sm-3">
<p class="mb-0"><?php echo $locale['mix-count']; ?></p>
</div>
<div class="col-sm-9">
<p class="text-muted mb-0"><?php echo $genre->get_count(); ?>
</p>
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-3">
<p class="mb-0">Email</p>
</div>
<div class="col-sm-9">
<p class="text-muted mb-0">example@example.com</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="card mb-4 mb-md-0">
<div class="card-body">
<p class="mb-4"><span class="text-primary font-italic me-1">assigment</span> Project
Status
</p>
<p class="mb-1" style="font-size: .77rem;">Web Design</p>
<div class="progress rounded" style="height: 5px;">
<div class="progress-bar" role="progressbar" style="width: 80%"
aria-valuenow="80"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
<p class="mt-4 mb-1" style="font-size: .77rem;">Website Markup</p>
<div class="progress rounded" style="height: 5px;">
<div class="progress-bar" role="progressbar" style="width: 72%"
aria-valuenow="72"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
<p class="mt-4 mb-1" style="font-size: .77rem;">One Page</p>
<div class="progress rounded" style="height: 5px;">
<div class="progress-bar" role="progressbar" style="width: 89%"
aria-valuenow="89"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
<p class="mt-4 mb-1" style="font-size: .77rem;">Mobile Template</p>
<div class="progress rounded" style="height: 5px;">
<div class="progress-bar" role="progressbar" style="width: 55%"
aria-valuenow="55"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
<p class="mt-4 mb-1" style="font-size: .77rem;">Backend API</p>
<div class="progress rounded mb-2" style="height: 5px;">
<div class="progress-bar" role="progressbar" style="width: 66%"
aria-valuenow="66"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card mb-4 mb-md-0">
<div class="card-body">
<p class="mb-4"><span class="text-primary font-italic me-1">assigment</span> Project
Status
</p>
<p class="mb-1" style="font-size: .77rem;">Web Design</p>
<div class="progress rounded" style="height: 5px;">
<div class="progress-bar" role="progressbar" style="width: 80%"
aria-valuenow="80"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
<p class="mt-4 mb-1" style="font-size: .77rem;">Website Markup</p>
<div class="progress rounded" style="height: 5px;">
<div class="progress-bar" role="progressbar" style="width: 72%"
aria-valuenow="72"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
<p class="mt-4 mb-1" style="font-size: .77rem;">One Page</p>
<div class="progress rounded" style="height: 5px;">
<div class="progress-bar" role="progressbar" style="width: 89%"
aria-valuenow="89"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
<p class="mt-4 mb-1" style="font-size: .77rem;">Mobile Template</p>
<div class="progress rounded" style="height: 5px;">
<div class="progress-bar" role="progressbar" style="width: 55%"
aria-valuenow="55"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
<p class="mt-4 mb-1" style="font-size: .77rem;">Backend API</p>
<div class="progress rounded mb-2" style="height: 5px;">
<div class="progress-bar" role="progressbar" style="width: 66%"
aria-valuenow="66"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php else: ?>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="alert alert-danger" role="alert"> <nav aria-label="breadcrumb" class="bg-body-tertiary rounded-3 p-3 mb-4">
<?php echo $locale['genreNotFound']; ?> <ol class="breadcrumb mb-0">
</div> <li class="breadcrumb-item"><a href="/"><?php echo $locale['home']; ?></a></li>
<li class="breadcrumb-item"><a href="/genres.php"><?php echo $locale['genres']; ?></a></li>
<li class="breadcrumb-item active"
aria-current="page"><?php
if ($genre && $genre->get_name() != "") {
echo $genre->get_name();
} else {
echo $locale['notfound'];
}
?></li>
</ol>
</nav>
</div> </div>
</div> </div>
<?php endif; <?php if ($genreFound): ?>
<div class="row">
<div class="col-lg-4">
<div class="card mb-4">
<div class="card-body text-center">
<img src="<?php echo $genre->get_img(); ?>"
alt="avatar"
class="rounded-circle img-fluid" style="width: 150px;">
<h5 class="my-3"><?php echo $genre->get_name();
?></h5>
?> </p>
<div class="d-flex justify-content-center mb-2">
<button type="button" data-mdb-button-init data-mdb-ripple-init
class="btn btn-primary">
<?php echo $locale['follow']; ?>
</button>
</div>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="card mb-4">
<div class="card-body">
<div class="row">
<div class="col-sm-3">
<p class="mb-0"><?php echo $locale['mix-count']; ?></p>
</div>
<div class="col-sm-9">
<p class="text-muted mb-0"><?php echo $genre->get_count(); ?>
</p>
</div>
</div>
</div> </div>
</section> </div>
<div class="row">
<div class="col-lg-12">
<div class="card mb-4">
<div class="card-body">
<?php
$count = 0;
$mixes = $genre->get_mixes();
foreach ($mixes as $mix) {
$output = new Mix($mix, $db);
echo '<div class="row">';
echo '<p class="mb-0">';
echo '<a href="/mix.php?mix=' . $output->get_slug() . '">';
echo $output->get_name();
echo '</a>';
echo '</p>';
echo ' </div>';
$count++;
if ($count < count($mixes)) {
echo '<hr>';
}
}
?>
</div>
</div>
</div>
</div>
</div>
</div>
<?php else: ?>
<div class="row">
<div class="col">
<div class="alert alert-danger" role="alert">
<?php echo $locale['genreNotFound']; ?>
</div>
</div>
</div>
<?php endif;
?>
</div>
</section>
<?php require 'includes/footer.php'; ?> <?php require 'includes/footer.php'; ?>

View file

@ -8,6 +8,7 @@ $genresFound = false;
// if there's a query parameter named 'dj', load the DJ class // if there's a query parameter named 'dj', load the DJ class
$db = new Database($config); $db = new Database($config);
$genres = new Genres($db); $genres = new Genres($db);
$title = $locale['genres'];
require_once 'includes/header.php'; require_once 'includes/header.php';
?> ?>
<section style="background-color: #eee;"> <section style="background-color: #eee;">

View file

@ -1,12 +1,5 @@
<script src="../js/bootstrap.bundle.min.js"></script> <script src="../js/bootstrap.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
var dropdownElementList = [].slice.call(document.querySelectorAll('.dropdown-toggle'));
var dropdownList = dropdownElementList.map(function (dropdownToggleEl) {
return new bootstrap.Dropdown(dropdownToggleEl);
});
});
</script>
</body> </body>
</html> </html>

View file

@ -84,12 +84,18 @@ function social_line($social, $value): string
$color = "#1DB954"; $color = "#1DB954";
$name = "Spotify"; $name = "Spotify";
break; break;
case "linktree":
$icon = "fa-solid fa-link";
$url = "https://www.linktr.ee/$value";
$color = "#39E09B";
$name = "Linktree";
break;
} }
return " return "
<li class='list-group-item d-flex justify-content-between align-items-center p-3'> <li class='list-group-item d-flex justify-content-between align-items-center p-3' title='$name'>
<i class='fa $icon fa-lg' style='color: $color;'></i> <i class='fa $icon fa-lg' style='color: $color;' title='$name'></i>
<p class='mb-0'><a href='$url'>$value</a> <p class='mb-0'><a href='$url' title='$name' >$value</a>
</p> </p>
</li>"; </li>";
} }

View file

@ -0,0 +1,15 @@
<?php
function get_google_tag_manager_header($tag): string
{
return <<<HTML
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','$tag')</script>
HTML;
}
function get_google_tag_manager_body($tag): string
{
return <<<HTML
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=$tag" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
HTML;
}

View file

@ -1,16 +1,34 @@
<!doctype html > <!doctype html >
<html lang="<?php echo $lang ?>"> <html lang="<?php echo $lang ?>">
<head> <head>
<?php if (isset($config['seo']['google']) && $config['seo']['google']) {
require_once 'includes/google_tag_manager.php';
echo get_google_tag_manager_header($config['seo']['gtm']['key']);
}?>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php echo $config['app']['name']; ?></title> <title><?php echo $title . " | " . $config['app']['name']; ?></title>
<link href="../css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/css/bootstrap.min.css"
<link href="fontawesome/css/all.css" rel="stylesheet"/> integrity="sha512-jnSuA4Ss2PkkikSOLtYs8BlYIeeIK1h99ty4YfvRPAlzr377vr3CXDb7sb7eEEBYjDtcYj+AjBH3FLv5uSJuXg=="
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet"/> crossorigin="anonymous" referrerpolicy="no-referrer"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css"
integrity="sha512-SnH5WK+bZxgPHs44uWIX+LLJAJ9/2PkPKZ5QiAj6Ta86w+fsb2TkcmfRyVX3pBnMFcV7oQPJkl9QevSCWr3W6A=="
crossorigin="anonymous" referrerpolicy="no-referrer"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"
integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css"
integrity="sha512-nMNlpuaDPrqlEls3IX/Q56H36qvBASwb3ipuo3MxeWbsQB1881ox0cRv7UPTgBlriqoynt35KjEwgGUeUXIPnw=="
crossorigin="anonymous" referrerpolicy="no-referrer"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"
integrity="sha512-2ImtlRlf2VVmiGZsjm9bEyhjGW4dU7B6TNwh/hx/iSByxNENtj3WVE6o/9Lj4TJeVXPi4bnOIMXFIJJAeufa0A=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link href="data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAA////APj4+AB/f38A8fHxAOrq6gATExMA/v7+AAUFBQASEhIA/f39AAsLCwCYmJgABAQEAOjo6AD8/PwAq6urAO7u7gADAwMA+/v7APT09AACAgIAvr6+AAEBAQC2trYA+fn5AJubmwDy8vIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQoHEwEHEwEKBwEBAQEBAQEKCQAAAAAQCgEBAQEBAQEOAxcAAAAAFwAZAQEBAQEFBxMTFQAAAAAXFQEBAQ8TFRcHDwgAFwAAAAAXBwcBCxIIEhMAEg0SAAAADRgBCgAAAAAAAQEBDwgAAAAACgcAAAAVDwEBBwEAAAAAFwcKAAAAFQEBBgIBABUAABUBAQAAABcAEwEBAQAXAAAXCgENAAAAAAwHAQAXFwAXGgEBGwAAAAAAABUTARUAFAEPAQESAAAAAAAAEgoKFBEBAQEHARUAFwAAAAAPBA4BAQEBAQcHFg0AAAAAFxMBAQEBAQEBAQoKAQcBBwoPAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
rel="icon" type="image/x-icon">
<?php <?php include 'includes/hreflang.php'; ?>
if (basename($_SERVER['SCRIPT_NAME']) == 'genres.php' || basename($_SERVER['SCRIPT_NAME']) == 'djs.php') { ?>
<?php if (basename($_SERVER['SCRIPT_NAME']) == 'genres.php' || basename($_SERVER['SCRIPT_NAME']) == 'djs.php') { ?>
<style> <style>
.card { .card {
height: 160px; height: 160px;
@ -42,4 +60,9 @@
<?php } ?> <?php } ?>
</head> </head>
<body style="background-color: #eee;"> <body style="background-color: #eee;">
<?php
if (isset($config['seo']['google']) && $config['seo']['google']) {
echo get_google_tag_manager_body($config['seo']['gtm']['key']);
}
?>
<?php require 'includes/navbar.php'; ?> <?php require 'includes/navbar.php'; ?>

21
includes/hreflang.php Normal file
View file

@ -0,0 +1,21 @@
<?php
// based on the page that called this include, we will set the hreflang
$languages = $config['locales'];
$list = [];
// for every key, rewrite it to be just the language code.
// for example, fil_PH becomes fil; taking note that we are removing _ and everything that follows
foreach ($languages as $key => $value) {
$key2 = str_replace('_', '-', $key);
$list[] = '<link rel="alternate" hreflang="' . $key2 . '" href="' . $config['app']['url'] . '/?lang=' . $key . '"/>' . PHP_EOL;
}
// dedupe $list
$list = array_unique($list);
foreach ($list as $link) {
echo $link;
}

View file

@ -9,4 +9,3 @@ if (isset($_GET['lang'])) {
$_SESSION['lang'] = $lang; $_SESSION['lang'] = $lang;
} }
$locale = loadLocale($lang); $locale = loadLocale($lang);

View file

@ -1,5 +1,6 @@
<?php <?php
require 'includes/globals.php'; require 'includes/globals.php';
$title = $locale['home'];
require 'includes/header.php'; ?> require 'includes/header.php'; ?>
<section style="background-color: #eee;"> <section style="background-color: #eee;">
<div class="container py-5"> <div class="container py-5">

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Search Results", "searchResults" => "Search Results",
"searchResultsFor" => "Search Results for", "searchResultsFor" => "Search Results for",
"searchResultsFound" => "Search Results Found", "searchResultsFound" => "Search Results Found",
"tracklist" => "Tracklist",
"lastupdated" => "Last Updated",
"duration" => "Duration",
"hour" => "hour",
"hours" => "hours",
"minute" => "minute",
"minutes" => "minutes",
"second" => "second",
"seconds" => "seconds",
"by" => "by",
"added" => "Added",
"recorded" => "Recorded",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "نتائج البحث", "searchResults" => "نتائج البحث",
"searchResultsFor" => "نتائج البحث عن", "searchResultsFor" => "نتائج البحث عن",
"searchResultsFound" => "تم العثور على نتائج البحث", "searchResultsFound" => "تم العثور على نتائج البحث",
"tracklist" => "قائمة التتبع",
"lastupdated" => "آخر تحديث",
"duration" => "المدة",
"hour" => "ساعة",
"hours" => "ساعات",
"minute" => "دقيقة",
"minutes" => "دقائق",
"second" => "ثانية",
"seconds" => "ثواني",
"by" => "بواسطة",
"added" => "أضيف",
"recorded" => "مسجلة",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Search Results", "searchResults" => "Search Results",
"searchResultsFor" => "Search Results for", "searchResultsFor" => "Search Results for",
"searchResultsFound" => "Search Results Found", "searchResultsFound" => "Search Results Found",
"tracklist" => "Tracklist",
"lastupdated" => "Last Updated",
"duration" => "Duration",
"hour" => "hour",
"hours" => "hours",
"minute" => "minute",
"minutes" => "minutes",
"second" => "second",
"seconds" => "seconds",
"by" => "by",
"added" => "Added",
"recorded" => "Recorded",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Výsledky hledání", "searchResults" => "Výsledky hledání",
"searchResultsFor" => "Výsledky hledání pro", "searchResultsFor" => "Výsledky hledání pro",
"searchResultsFound" => "Nalezeny výsledky hledání", "searchResultsFound" => "Nalezeny výsledky hledání",
"tracklist" => "Seznam stop",
"lastupdated" => "Naposledy aktualizováno",
"duration" => "Doba trvání",
"hour" => "hodina",
"hours" => "hodiny",
"minute" => "minuta",
"minutes" => "minuty",
"second" => "sekunda",
"seconds" => "sekundy",
"by" => "od",
"added" => "Přidáno",
"recorded" => "Zaznamenáno",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Søge Resultater", "searchResults" => "Søge Resultater",
"searchResultsFor" => "Søgeresultater for", "searchResultsFor" => "Søgeresultater for",
"searchResultsFound" => "Søgeresultater Fundet", "searchResultsFound" => "Søgeresultater Fundet",
"tracklist" => "Sporliste",
"lastupdated" => "Sidst Opdateret",
"duration" => "Varighed",
"hour" => "time",
"hours" => "timer",
"minute" => "minut",
"minutes" => "minutter",
"second" => "sekund",
"seconds" => "sekunder",
"by" => "af",
"added" => "Tilføjet",
"recorded" => "Optaget",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Suchergebnisse", "searchResults" => "Suchergebnisse",
"searchResultsFor" => "Suchergebnisse für", "searchResultsFor" => "Suchergebnisse für",
"searchResultsFound" => "Suchergebnisse gefunden", "searchResultsFound" => "Suchergebnisse gefunden",
"tracklist" => "Trackliste",
"lastupdated" => "Zuletzt aktualisiert",
"duration" => "Dauer",
"hour" => "std",
"hours" => "std",
"minute" => "minute",
"minutes" => "minuten",
"second" => "sekunde",
"seconds" => "Sekunden",
"by" => "von",
"added" => "Hinzugefügt",
"recorded" => "Aufgenommen",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Αποτελέσματα Αναζήτησης", "searchResults" => "Αποτελέσματα Αναζήτησης",
"searchResultsFor" => "Αποτελέσματα αναζήτησης για", "searchResultsFor" => "Αποτελέσματα αναζήτησης για",
"searchResultsFound" => "Βρέθηκαν Αποτελέσματα Αναζήτησης", "searchResultsFound" => "Βρέθηκαν Αποτελέσματα Αναζήτησης",
"tracklist" => "Ανίχνευση",
"lastupdated" => "Τελευταία Ενημέρωση",
"duration" => "Διάρκεια",
"hour" => "ώρα",
"hours" => "ώρες",
"minute" => "λεπτό",
"minutes" => "λεπτά",
"second" => "δευτερόλεπτο",
"seconds" => "δευτερόλεπτα",
"by" => "από",
"added" => "Προστέθηκε",
"recorded" => "Ηχογραφήθηκε",
]; ];

View file

@ -35,4 +35,23 @@ return [
"searchResultsFound" => "Search Results Found", "searchResultsFound" => "Search Results Found",
"tracklist" => "Tracklist", "tracklist" => "Tracklist",
"lastupdated" => "Last Updated", "lastupdated" => "Last Updated",
"duration" => "Duration",
"hour" => "hour",
"hours" => "hours",
"minute" => "minute",
"minutes" => "minutes",
"second" => "second",
"seconds" => "seconds",
"by" => "by",
"added" => "Added",
"recorded" => "Recorded",
"audioNotSupported" => "Your browser does not support the audio element.",
"downloads" => "Downloads",
"download" => "Download",
"downloadMix" => "Download Mix",
"plays" => "Plays",
"play" => "Play",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Resultados de búsqueda", "searchResults" => "Resultados de búsqueda",
"searchResultsFor" => "Resultados de búsqueda para", "searchResultsFor" => "Resultados de búsqueda para",
"searchResultsFound" => "Resultados de búsqueda encontrados", "searchResultsFound" => "Resultados de búsqueda encontrados",
"tracklist" => "Lista de seguimiento",
"lastupdated" => "Última actualización",
"duration" => "Duración",
"hour" => "hora",
"hours" => "horas",
"minute" => "minuto",
"minutes" => "minutos",
"second" => "segundo",
"seconds" => "segundos",
"by" => "por",
"added" => "Añadido",
"recorded" => "Registrado",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Hakutulokset", "searchResults" => "Hakutulokset",
"searchResultsFor" => "Hae tuloksia", "searchResultsFor" => "Hae tuloksia",
"searchResultsFound" => "Hakutulokset Löydetty", "searchResultsFound" => "Hakutulokset Löydetty",
"tracklist" => "Kappalelilista",
"lastupdated" => "Viimeksi Päivitetty",
"duration" => "Kesto",
"hour" => "tunti",
"hours" => "tuntia",
"minute" => "minuutti",
"minutes" => "minuuttia",
"second" => "sekunti",
"seconds" => "sekuntia",
"by" => "mennessä",
"added" => "Lisätty",
"recorded" => "Tallennettu",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Mga Resulta ng Paghahanap", "searchResults" => "Mga Resulta ng Paghahanap",
"searchResultsFor" => "Mga resulta ng paghahanap para sa", "searchResultsFor" => "Mga resulta ng paghahanap para sa",
"searchResultsFound" => "Natagpuan ang mga Resulta ng Paghahanap", "searchResultsFound" => "Natagpuan ang mga Resulta ng Paghahanap",
"tracklist" => "Tracklist",
"lastupdated" => "Last Updated",
"duration" => "Duration",
"hour" => "hour",
"hours" => "hours",
"minute" => "minute",
"minutes" => "minutes",
"second" => "second",
"seconds" => "seconds",
"by" => "by",
"added" => "Added",
"recorded" => "Recorded",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Résultats de recherche", "searchResults" => "Résultats de recherche",
"searchResultsFor" => "Résultats de recherche pour", "searchResultsFor" => "Résultats de recherche pour",
"searchResultsFound" => "Résultats de recherche trouvés", "searchResultsFound" => "Résultats de recherche trouvés",
"tracklist" => "Liste de suivi",
"lastupdated" => "Dernière mise à jour",
"duration" => "Durée",
"hour" => "heure",
"hours" => "heures",
"minute" => "minute",
"minutes" => "minutes",
"second" => "seconde",
"seconds" => "secondes",
"by" => "par",
"added" => "Ajouté",
"recorded" => "Enregistré",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Search Results", "searchResults" => "Search Results",
"searchResultsFor" => "Search Results for", "searchResultsFor" => "Search Results for",
"searchResultsFound" => "Search Results Found", "searchResultsFound" => "Search Results Found",
"tracklist" => "Tracklist",
"lastupdated" => "Last Updated",
"duration" => "Duration",
"hour" => "hour",
"hours" => "hours",
"minute" => "minute",
"minutes" => "minutes",
"second" => "second",
"seconds" => "seconds",
"by" => "by",
"added" => "Added",
"recorded" => "Recorded",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Search Results", "searchResults" => "Search Results",
"searchResultsFor" => "Search Results for", "searchResultsFor" => "Search Results for",
"searchResultsFound" => "Search Results Found", "searchResultsFound" => "Search Results Found",
"tracklist" => "Tracklist",
"lastupdated" => "Last Updated",
"duration" => "Duration",
"hour" => "hour",
"hours" => "hours",
"minute" => "minute",
"minutes" => "minutes",
"second" => "second",
"seconds" => "seconds",
"by" => "by",
"added" => "Added",
"recorded" => "Recorded",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Risultati Della Ricerca", "searchResults" => "Risultati Della Ricerca",
"searchResultsFor" => "Risultati della ricerca per", "searchResultsFor" => "Risultati della ricerca per",
"searchResultsFound" => "Risultati Di Ricerca Trovati", "searchResultsFound" => "Risultati Di Ricerca Trovati",
"tracklist" => "Tracklist",
"lastupdated" => "Ultimo Aggiornamento",
"duration" => "Durata",
"hour" => "ora",
"hours" => "ore",
"minute" => "minuto",
"minutes" => "minuti",
"second" => "secondo",
"seconds" => "secondi",
"by" => "di",
"added" => "Aggiunto",
"recorded" => "Registrato",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "検索結果", "searchResults" => "検索結果",
"searchResultsFor" => "検索結果", "searchResultsFor" => "検索結果",
"searchResultsFound" => "検索結果が見つかりました", "searchResultsFound" => "検索結果が見つかりました",
"tracklist" => "トラックリスト",
"lastupdated" => "最終更新",
"duration" => "期間",
"hour" => "",
"hours" => "時間",
"minute" => "",
"minutes" => "",
"second" => "",
"seconds" => "",
"by" => "作成者:",
"added" => "追加しました",
"recorded" => "記録済み",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Search Results", "searchResults" => "Search Results",
"searchResultsFor" => "Search Results for", "searchResultsFor" => "Search Results for",
"searchResultsFound" => "Search Results Found", "searchResultsFound" => "Search Results Found",
"tracklist" => "Tracklist",
"lastupdated" => "Last Updated",
"duration" => "Duration",
"hour" => "hour",
"hours" => "hours",
"minute" => "minute",
"minutes" => "minutes",
"second" => "second",
"seconds" => "seconds",
"by" => "by",
"added" => "Added",
"recorded" => "Recorded",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Zoek resultaten", "searchResults" => "Zoek resultaten",
"searchResultsFor" => "Zoekresultaten voor", "searchResultsFor" => "Zoekresultaten voor",
"searchResultsFound" => "Zoekresultaten gevonden", "searchResultsFound" => "Zoekresultaten gevonden",
"tracklist" => "Tracklist",
"lastupdated" => "Laatst bijgewerkt",
"duration" => "Duur",
"hour" => "uur",
"hours" => "Uren",
"minute" => "minuut",
"minutes" => "minuten",
"second" => "seconde",
"seconds" => "seconden",
"by" => "door",
"added" => "Toegevoegd",
"recorded" => "Opgenomen",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Resultat av søket", "searchResults" => "Resultat av søket",
"searchResultsFor" => "Søkeresultater for", "searchResultsFor" => "Søkeresultater for",
"searchResultsFound" => "Søkeresultater funnet", "searchResultsFound" => "Søkeresultater funnet",
"tracklist" => "Turliste",
"lastupdated" => "Sist oppdatert",
"duration" => "Varighet",
"hour" => "time",
"hours" => "timer",
"minute" => "minutt",
"minutes" => "minutter",
"second" => "sekund",
"seconds" => "sekunder",
"by" => "av",
"added" => "Lagt",
"recorded" => "Tømt",
]; ];

View file

@ -16,8 +16,8 @@ return [
'djs' => 'DJ-y', 'djs' => 'DJ-y',
"djNotFound" => "Nie można załadować DJ; DJ nie został znaleziony lub ten DJ jest prywatny.", "djNotFound" => "Nie można załadować DJ; DJ nie został znaleziony lub ten DJ jest prywatny.",
"notfound" => "Strona nie znaleziona", "notfound" => "Strona nie znaleziona",
"genre" => "Rodzaj", "genre" => "Gatunek",
"genres" => "Genres", "genres" => "Gatunki",
"genreNotFound" => "Nie można załadować gatunku; albo gatunek nie został znaleziony, był pusty lub ten gatunek jest prywatny.", "genreNotFound" => "Nie można załadować gatunku; albo gatunek nie został znaleziony, był pusty lub ten gatunek jest prywatny.",
"mix-count" => "Liczba mieszanek", "mix-count" => "Liczba mieszanek",
"mixes" => "Mieszanki", "mixes" => "Mieszanki",
@ -33,5 +33,18 @@ return [
"searchResults" => "Wyniki wyszukiwania", "searchResults" => "Wyniki wyszukiwania",
"searchResultsFor" => "Wyniki wyszukiwania dla", "searchResultsFor" => "Wyniki wyszukiwania dla",
"searchResultsFound" => "Znaleziono wyniki wyszukiwania", "searchResultsFound" => "Znaleziono wyniki wyszukiwania",
"tracklist" => "Lista ścieżek",
"lastupdated" => "Ostatnia aktualizacja",
"duration" => "Czas trwania",
"hour" => "godzina",
"hours" => "godziny",
"minute" => "minuta",
"minutes" => "minuty",
"second" => "sekunda",
"seconds" => "sekundy",
"by" => "przez",
"added" => "Dodano",
"recorded" => "Zapisane",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Resultados da Pesquisa", "searchResults" => "Resultados da Pesquisa",
"searchResultsFor" => "Resultados da Pesquisa para", "searchResultsFor" => "Resultados da Pesquisa para",
"searchResultsFound" => "Resultados da Pesquisa Encontrados", "searchResultsFound" => "Resultados da Pesquisa Encontrados",
"tracklist" => "Acompanhamento",
"lastupdated" => "Última atualização",
"duration" => "Duração",
"hour" => "hora",
"hours" => "horas",
"minute" => "minuto",
"minutes" => "Minutos",
"second" => "segundo",
"seconds" => "segundos",
"by" => "Por",
"added" => "Adicionado",
"recorded" => "Gravado",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Resultados da Pesquisa", "searchResults" => "Resultados da Pesquisa",
"searchResultsFor" => "Resultados da Pesquisa para", "searchResultsFor" => "Resultados da Pesquisa para",
"searchResultsFound" => "Resultados da Pesquisa Encontrados", "searchResultsFound" => "Resultados da Pesquisa Encontrados",
"tracklist" => "Acompanhamento",
"lastupdated" => "Última atualização",
"duration" => "Duração",
"hour" => "hora",
"hours" => "horas",
"minute" => "minuto",
"minutes" => "Minutos",
"second" => "segundo",
"seconds" => "segundos",
"by" => "Por",
"added" => "Adicionado",
"recorded" => "Gravado",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Rezultatele căutării", "searchResults" => "Rezultatele căutării",
"searchResultsFor" => "Rezultate căutare pentru", "searchResultsFor" => "Rezultate căutare pentru",
"searchResultsFound" => "Rezultate Căutare găsite", "searchResultsFound" => "Rezultate Căutare găsite",
"tracklist" => "Lista de urmărire",
"lastupdated" => "Ultima actualizare",
"duration" => "Durată",
"hour" => "oră",
"hours" => "ore",
"minute" => "minut",
"minutes" => "minute",
"second" => "secundă",
"seconds" => "secunde",
"by" => "de",
"added" => "Adăugat",
"recorded" => "Înregistrat",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Результаты поиска", "searchResults" => "Результаты поиска",
"searchResultsFor" => "Результаты поиска для", "searchResultsFor" => "Результаты поиска для",
"searchResultsFound" => "Найдены результаты поиска", "searchResultsFound" => "Найдены результаты поиска",
"tracklist" => "Список треков",
"lastupdated" => "Последнее обновление",
"duration" => "Продолжительность",
"hour" => "час",
"hours" => "часов",
"minute" => "минута",
"minutes" => "минуты",
"second" => "секунда",
"seconds" => "секунд",
"by" => "от",
"added" => "Добавлено",
"recorded" => "Записанные",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Search Results", "searchResults" => "Search Results",
"searchResultsFor" => "Search Results for", "searchResultsFor" => "Search Results for",
"searchResultsFound" => "Search Results Found", "searchResultsFound" => "Search Results Found",
"tracklist" => "Tracklist",
"lastupdated" => "Last Updated",
"duration" => "Duration",
"hour" => "hour",
"hours" => "hours",
"minute" => "minute",
"minutes" => "minutes",
"second" => "second",
"seconds" => "seconds",
"by" => "by",
"added" => "Added",
"recorded" => "Recorded",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Sök resultat", "searchResults" => "Sök resultat",
"searchResultsFor" => "Sökresultat för", "searchResultsFor" => "Sökresultat för",
"searchResultsFound" => "Sökresultat hittades", "searchResultsFound" => "Sökresultat hittades",
"tracklist" => "Spårlista",
"lastupdated" => "Senast uppdaterad",
"duration" => "Varaktighet",
"hour" => "timme",
"hours" => "timmar",
"minute" => "minut",
"minutes" => "minuter",
"second" => "sekund",
"seconds" => "sekunder",
"by" => "av",
"added" => "Tillagd",
"recorded" => "Inspelat",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Search Results", "searchResults" => "Search Results",
"searchResultsFor" => "Search Results for", "searchResultsFor" => "Search Results for",
"searchResultsFound" => "Search Results Found", "searchResultsFound" => "Search Results Found",
"tracklist" => "Tracklist",
"lastupdated" => "Last Updated",
"duration" => "Duration",
"hour" => "hour",
"hours" => "hours",
"minute" => "minute",
"minutes" => "minutes",
"second" => "second",
"seconds" => "seconds",
"by" => "by",
"added" => "Added",
"recorded" => "Recorded",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Результати пошуку", "searchResults" => "Результати пошуку",
"searchResultsFor" => "Результати пошуку для", "searchResultsFor" => "Результати пошуку для",
"searchResultsFound" => "Результати пошуку знайдено", "searchResultsFound" => "Результати пошуку знайдено",
"tracklist" => "Список треків",
"lastupdated" => "Востаннє оновлено",
"duration" => "Тривалість",
"hour" => "година",
"hours" => "годин",
"minute" => "хвилина",
"minutes" => "хвилин",
"second" => "секунда",
"seconds" => "секунди",
"by" => "за",
"added" => "Додано",
"recorded" => "Записано",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Search Results", "searchResults" => "Search Results",
"searchResultsFor" => "Search Results for", "searchResultsFor" => "Search Results for",
"searchResultsFound" => "Search Results Found", "searchResultsFound" => "Search Results Found",
"tracklist" => "Tracklist",
"lastupdated" => "Last Updated",
"duration" => "Duration",
"hour" => "hour",
"hours" => "hours",
"minute" => "minute",
"minutes" => "minutes",
"second" => "second",
"seconds" => "seconds",
"by" => "by",
"added" => "Added",
"recorded" => "Recorded",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "搜索结果", "searchResults" => "搜索结果",
"searchResultsFor" => "搜索结果", "searchResultsFor" => "搜索结果",
"searchResultsFound" => "找到搜索结果", "searchResultsFound" => "找到搜索结果",
"tracklist" => "曲目列表",
"lastupdated" => "最后更新",
"duration" => "期限",
"hour" => "小时",
"hours" => "小时",
"minute" => "分钟",
"minutes" => "分钟",
"second" => "",
"seconds" => "",
"by" => "",
"added" => "已添加",
"recorded" => "已记录",
]; ];

View file

@ -33,5 +33,18 @@ return [
"searchResults" => "Search Results", "searchResults" => "Search Results",
"searchResultsFor" => "Search Results for", "searchResultsFor" => "Search Results for",
"searchResultsFound" => "Search Results Found", "searchResultsFound" => "Search Results Found",
"tracklist" => "Tracklist",
"lastupdated" => "Last Updated",
"duration" => "Duration",
"hour" => "hour",
"hours" => "hours",
"minute" => "minute",
"minutes" => "minutes",
"second" => "second",
"seconds" => "seconds",
"by" => "by",
"added" => "Added",
"recorded" => "Recorded",
]; ];

403
mix.php
View file

@ -3,6 +3,7 @@
require 'includes/globals.php'; require 'includes/globals.php';
require_once 'classes/Database.php'; require_once 'classes/Database.php';
require_once 'classes/Mix.php'; require_once 'classes/Mix.php';
require_once 'classes/Mixshow.php';
$db = new Database($config); $db = new Database($config);
$mixFound = false; $mixFound = false;
@ -10,127 +11,331 @@ if (isset($_GET['mix']) && $_GET['mix'] != "") {
$mix = new Mix($_GET['mix'], $db); $mix = new Mix($_GET['mix'], $db);
if ($mix->get_name() != "") { if ($mix->get_name() != "") {
$mixFound = true; $mixFound = true;
$title = $mix->get_name();
} else {
$title = $locale['notfound'];
} }
} else {
$title = $locale['notfound'];
} }
require 'includes/header.php'; ?> require 'includes/header.php'; ?>
<section style="background-color: #eee;"> <section style="background-color: #eee;">
<div class="container py-5"> <div class="container py-5">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<nav aria-label="breadcrumb" class="bg-body-tertiary rounded-3 p-3 mb-4"> <nav aria-label="breadcrumb" class="bg-body-tertiary rounded-3 p-3 mb-4">
<ol class="breadcrumb mb-0"> <ol class="breadcrumb mb-0">
<li class="breadcrumb-item"><a href="/"><?php echo $locale['home']; ?></a></li> <li class="breadcrumb-item"><a href="/"><?php echo $locale['home']; ?></a></li>
<li class="breadcrumb-item"><a href="/mixes.php"><?php echo $locale['mixes']; ?></a></li> <li class="breadcrumb-item"><a href="/mixes.php"><?php echo $locale['mixes']; ?></a></li>
<li class="breadcrumb-item active" <li class="breadcrumb-item active"
aria-current="page"><?php aria-current="page"><?php
if ($mix && $mix->get_name() != "") { if (isset($mix) && $mix->get_name() != "") {
echo $mix->get_name(); echo $mix->get_name();
} else { } else {
echo $locale['notfound']; 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 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>";
} }
?></li> ?>
</ol> </p>
</nav> </div>
</div> </div>
</div> <div class="card mb-4">
<div class="card-body text-center">
<?php
if ($mix->is_download_only()) {
echo "<a href='" . $mix->get_url() . "' class='btn btn-primary'>" . $locale['download'] . "</a>";
} else {
echo "<audio controls controlsList='nodownload'>";
$url = $mix->get_url();
// if $url starts with /djs/, cut that.
if (substr($url, 0, 4) == "/djs") {
$url = substr($url, 4);
}
echo "<source src='https://cdn.utahsdjs.com" . $url . "' type='audio/mpeg'>";
echo $locale['audioNotSupported'];
echo "</audio>";
<?php if ($mixFound): ?> }
<div class="row">
<div class="col-lg-4"> ?>
<div class="card mb-4"> </div>
<div class="card-body 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> </div>
</div> <div class="col-lg-8">
<div class="col-lg-8"> <div class="card mb-4">
<div class="card mb-4"> <div class="card-body">
<div class="card-body"> <div class="row">
<div class="row"> <div class="col-sm-3">
<div class="col-sm-3"> <p class="mb-0"><?php echo $locale['mixname'] ?></p>
<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> </div>
<div class="col-sm-9"> <hr>
<p class="text-muted mb-0"><?php echo $mix->get_name(); ?></p> <div class="row">
</div> <div class="col-sm-3">
</div> <p class="mb-0"><?php echo $locale['djs'] ?></p>
<hr> </div>
<div class="row"> <div class="col-sm-9">
<div class="col-sm-3"> <p class="text-muted mb-0">
<p class="mb-0"><?php echo $locale['djs'] ?></p> <?php
</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 // loop through the $mix['djs'] array and output them in comma separated format
$djs = $mix->get_djs(); $djs = $mix->get_djs();
$djCount = count($djs); $djCount = count($djs);
$i = 0; $i = 0;
foreach ($djs as $dj) { foreach ($djs as $dj) {
echo "<a href='/dj.php?dj="; echo "<a href='/dj.php?dj=";
echo $dj->get_slug(); echo $dj->get_slug();
echo "'>" . $dj->get_name() . "</a>"; echo "'>" . $dj->get_name() . "</a>";
if ($i < $djCount - 1) { if ($i < $djCount - 1) {
echo ", "; echo ", ";
}
$i++;
} }
$i++;
}
?>
?> </p>
</div>
</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;
require_once 'classes/Genre.php';
foreach ($genres as $genre) {
$genre = new Genre($genre, $db);
echo "<a href='/genre.php?genre=";
echo $genre->get_slug();
echo "'>" . $genre->get_name() . "</a>";
if ($i < $genreCount - 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->get_name();
$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> </div>
</div>
<?php <?php
if ($mix->get_tracklist() != []) { if ($mix->get_tracklist() != []) {
echo "<div class='card mb-4'>"; echo "<div class='card mb-4'>";
echo "<div class='card-body'>"; echo "<div class='card-body'>";
echo "<p class='mb-4'><span class='text-primary font-italic me-1'>" . $locale['tracklist'] . "</span></p>"; 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'>"; echo "<ul class='list-group list-group-flush rounded-3'>";
$tracklist = $mix->get_tracklist(); $tracklist = $mix->get_tracklist();
foreach ($tracklist as $track) { foreach ($tracklist as $track) {
echo "<li class='list-group-item d-flex justify-content-between align-items-center'>"; echo "<li class='list-group-item d-flex justify-content-between align-items-center'>";
echo $track; echo $track;
echo "</li>"; echo "</li>";
}
echo "</ul>";
echo "</div>";
echo "</div>";
} }
echo "</ul>";
echo "</div>";
echo "</div>";
}
?> ?>
</div>
</div>
</div>
<?php else: ?>
<div class="row">
<div class="col">
<div class="alert alert-danger" role="alert">
<?php echo $locale['djNotFound']; ?>
</div> </div>
</div> </div>
</div> </div>
<?php endif; <?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>
</div>
</section>
<?php require 'includes/footer.php'; ?> <?php require 'includes/footer.php'; ?>