Time to do an update.
This commit is contained in:
parent
70c8a87e15
commit
0b0697bb42
22 changed files with 4352 additions and 268 deletions
2
admin/index.php
Normal file
2
admin/index.php
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?php
|
||||
|
|
@ -10,7 +10,7 @@ class Genre
|
|||
private $count = 0;
|
||||
private $name = "";
|
||||
private $slug = "";
|
||||
private $db = "";
|
||||
private $db;
|
||||
private $mixes = [];
|
||||
|
||||
public function __construct($value, $db)
|
||||
|
|
218
classes/HeaderMeta.php
Normal file
218
classes/HeaderMeta.php
Normal file
|
@ -0,0 +1,218 @@
|
|||
<?php
|
||||
|
||||
namespace DJMixHosting;
|
||||
|
||||
use DJMixHosting\Genre;
|
||||
|
||||
class HeaderMeta
|
||||
{
|
||||
|
||||
private $config;
|
||||
private $title = "";
|
||||
private $description = "";
|
||||
private $url = "";
|
||||
private $image = "";
|
||||
private $type = "";
|
||||
private $duration_seconds = "";
|
||||
private $musician = "";
|
||||
private $audio = "";
|
||||
private $keywords = "";
|
||||
private $canonical = "";
|
||||
private $robot = "";
|
||||
private $noindex = "";
|
||||
|
||||
public function __construct($object, $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
// detect if it is DJMixHosting\Mix, DJMixHosting\Genre, DJMixHosting\Mixshow, or DJMixHosting\DJ in $object
|
||||
if ($object instanceof Mix) {
|
||||
$djs = $object->get_djs();
|
||||
$djList = "";
|
||||
foreach ($djs as $dj) {
|
||||
$djList .= $dj->getName() . ", ";
|
||||
}
|
||||
$djList = rtrim($djList, ", ");
|
||||
|
||||
$genres = $object->get_genres();
|
||||
$genreNames = "";
|
||||
|
||||
$genreList = rtrim($genreNames, ", ");
|
||||
|
||||
|
||||
$this->set_ogTitle($object->get_name());
|
||||
$this->set_ogDescription($object->get_description());
|
||||
$this->set_ogUrl($object->get_page_url());
|
||||
$this->set_ogImage($object->get_cover());
|
||||
$this->set_ogType("music.song");
|
||||
$this->set_ogDurationSeconds($object->get_seconds());
|
||||
$this->set_ogMusician($djList);
|
||||
$this->set_ogAudio($object->get_download_url());
|
||||
$this->set_ogKeywords($genreList);
|
||||
$this->set_ogCanonical($object->get_page_url());
|
||||
$this->set_ogRobot("index, follow");
|
||||
$this->set_ogNoindex("");
|
||||
}
|
||||
}
|
||||
|
||||
private function set_ogTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
private function set_ogDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
private function set_ogUrl($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
private function set_ogImage($image)
|
||||
{
|
||||
$this->image = $image;
|
||||
}
|
||||
|
||||
private function set_ogType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
private function set_ogDurationSeconds($duration_seconds)
|
||||
{
|
||||
$this->duration_seconds = $duration_seconds;
|
||||
}
|
||||
|
||||
private function set_ogMusician($musician)
|
||||
{
|
||||
$this->musician = $musician;
|
||||
}
|
||||
|
||||
private function set_ogAudio($audio)
|
||||
{
|
||||
$this->audio = $audio;
|
||||
}
|
||||
|
||||
private function set_ogKeywords($keywords)
|
||||
{
|
||||
$this->keywords = $keywords;
|
||||
}
|
||||
|
||||
private function set_ogCanonical($canonical)
|
||||
{
|
||||
$this->canonical = $canonical;
|
||||
}
|
||||
|
||||
private function set_ogRobot($robot)
|
||||
{
|
||||
$this->robot = $robot;
|
||||
}
|
||||
|
||||
private function set_ogNoindex($noindex)
|
||||
{
|
||||
$this->noindex = $noindex;
|
||||
}
|
||||
|
||||
public function mixMetaOutput()
|
||||
{
|
||||
global $config;
|
||||
$output = $this->buildMeta("og:title", $this->get_ogTitle());
|
||||
$output .= $this->buildMeta("og:type", $this->get_ogType());
|
||||
$output .= $this->buildMeta("og:url", $this->get_ogUrl());
|
||||
$output .= $this->buildMeta("og:image", $this->get_ogImage());
|
||||
$output .= $this->buildMeta("og:description", $this->get_ogDescription());
|
||||
$output .= $this->buildMeta("og:locale", "en_US");
|
||||
$output .= $this->buildMeta("og:site_name", $config['app']['name']);
|
||||
$output .= $this->buildMeta("music:duration", $this->get_ogDurationSeconds());
|
||||
$output .= $this->buildMeta("music:musician", $this->get_ogMusician());
|
||||
$output .= $this->buildMetaName("description", $this->get_ogDescription());
|
||||
$output .= $this->buildMeta("og:audio", $this->get_ogAudio());
|
||||
$output .= $this->buildMetaName("keywords", $this->get_ogKeywords());
|
||||
$output .= $this->buildMeta("canonical", $this->get_ogCanonical());
|
||||
$output .= $this->buildMetaName("robots", $this->get_ogRobot());
|
||||
$output .= $this->buildMetaName("robots", $this->get_ogNoindex());
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
private function buildMeta($property, $content)
|
||||
{
|
||||
if ($content == "" || $content == null) {
|
||||
return "";
|
||||
} else {
|
||||
return "<meta property=\"$property\" content=\"$content\"/>".PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_ogTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function get_ogType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function get_ogUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function get_ogImage()
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
public function get_ogDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function get_ogDurationSeconds()
|
||||
{
|
||||
return $this->duration_seconds;
|
||||
}
|
||||
|
||||
public function get_ogMusician()
|
||||
{
|
||||
return $this->musician;
|
||||
}
|
||||
|
||||
private function buildMetaName($name, $content)
|
||||
{
|
||||
if ($content == "" || $content == null) {
|
||||
return "";
|
||||
} else {
|
||||
return "<meta name=\"$name\" content=\"$content\"/>" . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_ogAudio()
|
||||
{
|
||||
return $this->audio;
|
||||
}
|
||||
|
||||
public function get_ogKeywords()
|
||||
{
|
||||
return $this->keywords;
|
||||
}
|
||||
|
||||
public function get_ogCanonical()
|
||||
{
|
||||
return $this->canonical;
|
||||
}
|
||||
|
||||
public function get_ogRobot()
|
||||
{
|
||||
return $this->robot;
|
||||
}
|
||||
|
||||
public function get_ogNoindex()
|
||||
{
|
||||
return $this->noindex;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -317,4 +317,14 @@ class Mix
|
|||
return $this->mixshow;
|
||||
}
|
||||
|
||||
public function get_download_url()
|
||||
{
|
||||
return "https://beta.utahsdjs.com/mix/" . "$this->slug" . "/download";
|
||||
}
|
||||
|
||||
public function get_page_url()
|
||||
{
|
||||
return "https://beta.utahsdjs.com/mix/" . "$this->slug";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
36
classes/RSS.php
Normal file
36
classes/RSS.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace DJMixHosting;
|
||||
|
||||
class RSS
|
||||
{
|
||||
|
||||
private $db;
|
||||
private string $header = '<?xml version="1.0" encoding="UTF-8" ?>';
|
||||
private string $rss = '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
|
||||
xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
|
||||
xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0">';
|
||||
|
||||
|
||||
private function itemMix($mix)
|
||||
{
|
||||
$output = new Mix($mix, $this->db);
|
||||
|
||||
if ($output->get_recorded() != "") {
|
||||
$pubdate = date('D, d M Y H:i:s O', strtotime($output->get_recorded()));
|
||||
} elseif ($output->get_created() != "") {
|
||||
$pubdate = date('D, d M Y H:i:s O', strtotime($output->get_created()));
|
||||
} else {
|
||||
$pubdate = date('D, d M Y H:i:s O', strtotime('2008-01-01 12:00:00'));
|
||||
}
|
||||
|
||||
echo '<item>';
|
||||
echo '<title>' . $output->get_name() . '</title>';
|
||||
echo '<description>' . $output->get_description() . '</description>';
|
||||
echo '<link>' . $output->get_url() . '</link>';
|
||||
echo '<guid>' . $output->get_slug() . '</guid>';
|
||||
echo '<pubDate>' . $pubdate . '</pubDate>';
|
||||
echo '</item>';
|
||||
}
|
||||
|
||||
}
|
|
@ -27,6 +27,9 @@ Class User{
|
|||
* @throws RandomException
|
||||
*/
|
||||
public function newUser($username, $password, $email){
|
||||
if ($this->check_existing_user($username, $email)){
|
||||
throw new RandomException("User already exists");
|
||||
}
|
||||
$this->username = $username;
|
||||
$this->email = $email;
|
||||
$password2 = password_hash($password, PASSWORD_DEFAULT);
|
||||
|
@ -48,5 +51,19 @@ Class User{
|
|||
|
||||
}
|
||||
|
||||
private function check_existing_user($username, $email){
|
||||
$stmt = $this->db->prepare("SELECT * FROM users WHERE username = ? OR email = ?");
|
||||
$stmt->bind_param("ss", $username, $email);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$user = $result->fetch_assoc();
|
||||
$stmt->close();
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function login(mixed $username, mixed $password)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1 +1,6 @@
|
|||
{}
|
||||
"files": [
|
||||
{
|
||||
"source": "locale/en-us/messages.php",
|
||||
"translation": "locale/%locale%/messages.php"
|
||||
}
|
||||
]
|
105
dj.php
105
dj.php
|
@ -64,20 +64,14 @@ require_once 'includes/header.php';
|
|||
}
|
||||
|
||||
?>
|
||||
<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->getSocials() != []) {
|
||||
?>
|
||||
<div class="card mb-4 mb-lg-0">
|
||||
<div class="card mb-4">
|
||||
<div class="card-body p-0 ">
|
||||
<ul class="list-group list-group-flush rounded-3">
|
||||
<?php
|
||||
|
@ -89,8 +83,33 @@ require_once 'includes/header.php';
|
|||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-body bg-body-secondary text-center">
|
||||
<?php
|
||||
if ($dj->getClaimed()) {
|
||||
?>
|
||||
<button type="button"
|
||||
class="btn w-100 mb-2 btn btn-secondary w-100 mb-2"><?php echo $locale['message']; ?>
|
||||
</button><?php
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<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>
|
||||
<button type="button" id="rss" class="btn btn-secondary w-100 mb-2">
|
||||
<?php echo $locale['rss']; ?>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-8">
|
||||
<div class="card mb-4">
|
||||
<div class="card-body bg-body-secondary">
|
||||
|
@ -117,6 +136,17 @@ require_once 'includes/header.php';
|
|||
<div class="card-body bg-body-secondary">
|
||||
<?php
|
||||
$mixes = $dj->getDJMixes();
|
||||
if (!empty($mixes)) {
|
||||
// Add header row for the table-like layout
|
||||
echo '<div class="row font-weight-bold mb-2">';
|
||||
echo '<div class="col-md text-truncate">' . $locale['mixName'] . '</div>';
|
||||
echo '<div class="col-md">' . $locale['genres'] . '</div>';
|
||||
echo '<div class="col-md">' . $locale['duration'] . '</div>';
|
||||
echo '<div class="col-md">' . $locale['year'] . '</div>';
|
||||
echo '</div>';
|
||||
echo '<hr class="my-2">'; // Optional horizontal rule for separation
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
|
||||
foreach ($mixes as $mix) {
|
||||
|
@ -165,7 +195,7 @@ require_once 'includes/header.php';
|
|||
echo '<p class="mb-0">';
|
||||
// date format should just be year
|
||||
$date = $output->get_recorded();
|
||||
if ($date == "") {
|
||||
if (is_null($date) || empty(trim($date))) {
|
||||
$date = $output->get_created();
|
||||
}
|
||||
echo date('Y', strtotime($date));
|
||||
|
@ -188,6 +218,61 @@ require_once 'includes/header.php';
|
|||
</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/dj/' . $_GET['dj'];
|
||||
$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-info w-100 mb-2" onclick="hideModal()">Share to
|
||||
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();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php else: ?>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
<?php
|
||||
|
||||
function loadLocale($lang = 'en-us') {
|
||||
function loadLocale($lang = 'en-us')
|
||||
{
|
||||
$file = __DIR__ . '/../locale/' . $lang . '/messages.php';
|
||||
if (file_exists($file)) {
|
||||
return require_once $file;
|
||||
} else {
|
||||
// Fallback to English if the specified language file does not exist
|
||||
return require_once __DIR__ . '/../locale/en-us/messages.php';
|
||||
return require_once __DIR__ . '/../locale/en-us/messages.php';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
233
genre.php
233
genre.php
|
@ -17,10 +17,10 @@ if (isset($_GET['genre']) && $_GET['genre'] != "") {
|
|||
if ($genre->get_name() != "") {
|
||||
$genreRequested = true;
|
||||
$genreFound = true;
|
||||
$title = $genre->get_name();
|
||||
}
|
||||
}
|
||||
|
||||
$title = $genre->get_name();
|
||||
|
||||
require_once 'includes/header.php';
|
||||
?>
|
||||
|
@ -45,104 +45,167 @@ require_once 'includes/header.php';
|
|||
</div>
|
||||
</div>
|
||||
<?php if ($genreFound): ?>
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<div class="card mb-4">
|
||||
<div class="card-body bg-body-secondary 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>
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<div class="card mb-4">
|
||||
<div class="card-body bg-body-secondary 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>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-body bg-body-secondary text-center ">
|
||||
<a type="button" id="followBtn" class="w-100 mb-2 btn btn-secondary">
|
||||
<?php echo $locale['follow']; ?>
|
||||
</a>
|
||||
<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>
|
||||
|
||||
</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['genre']; ?></p>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<p class="text-muted mb-0"><?php echo $genre->get_name(); ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<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>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<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['genre']; ?></p>
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
<p class="text-muted mb-0"><?php echo $genre->get_name(); ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<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>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="card mb-4">
|
||||
<div class="card-body bg-body-secondary">
|
||||
<?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/' . $output->get_slug() . '">';
|
||||
echo $output->get_name();
|
||||
echo '</a>';
|
||||
echo ' ‐ ';
|
||||
$djs = $output->get_djs();
|
||||
$djCount = 0;
|
||||
foreach ($djs as $dj) {
|
||||
echo '<a href="/dj/' . $dj->getSlug() . '">';
|
||||
echo $dj->getName();
|
||||
echo '</a>';
|
||||
$djCount++;
|
||||
if ($djCount < count($djs)) {
|
||||
echo ', ';
|
||||
}
|
||||
}
|
||||
echo '</p>';
|
||||
echo ' </div>';
|
||||
$count++;
|
||||
if ($count < count($mixes)) {
|
||||
echo '<hr>';
|
||||
}
|
||||
|
||||
<?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/' . $output->get_slug() . '">';
|
||||
echo $output->get_name();
|
||||
echo '</a>';
|
||||
echo ' ‐ ';
|
||||
$djs = $output->get_djs();
|
||||
$djCount = 0;
|
||||
foreach ($djs as $dj) {
|
||||
echo '<a href="/dj/' . $dj->getSlug() . '">';
|
||||
echo $dj->getName();
|
||||
echo '</a>';
|
||||
$djCount++;
|
||||
if ($djCount < count($djs)) {
|
||||
echo ', ';
|
||||
}
|
||||
}
|
||||
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>
|
||||
<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/genre/' . $_GET['genre'];
|
||||
$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-info w-100 mb-2" onclick="hideModal()">Share to
|
||||
Twitter</a>
|
||||
<a href="https://www.instagram.com/" target="_blank" class="btn btn-danger w-100"
|
||||
onclick="hideModal()">Share to Instagram</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;
|
||||
</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();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<?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>
|
||||
|
|
|
@ -17,6 +17,8 @@ $djsPages = ["/djs", "/djs/", "/djs.php"];
|
|||
|
||||
$genrePages = ["/genres", "/genres/", "/genres.php"];
|
||||
|
||||
$mixPages = ["/mix", "/mix/", "/mix.php"];
|
||||
|
||||
$specialStyle = array_merge($mixshowsPages, $djsPages, $genrePages);
|
||||
|
||||
|
||||
|
|
21
includes/header-meta.php
Normal file
21
includes/header-meta.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
|
||||
require_once 'includes/globals.php';
|
||||
require_once 'vendor/autoload.php';
|
||||
|
||||
use DJMixHosting\HeaderMeta;
|
||||
|
||||
$mixPages = ["/mix/", "/mix.php"];
|
||||
$page = $_SERVER['SCRIPT_NAME'];
|
||||
// the $mixPages has a list of pages, but the request or script name might be /mix/content or /mix.php?mix=content...
|
||||
// so we need to check if the script name contains any of the pages in the $mixPages array
|
||||
if (isset($mix)) {
|
||||
if (str_contains($page, $mixPages[0])) {
|
||||
|
||||
$headerMeta = new HeaderMeta($mix, $config);
|
||||
$meta = $headerMeta->mixMetaOutput();
|
||||
echo $meta;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,78 +1,146 @@
|
|||
<?php require_once 'includes/header-security.php'; ?>
|
||||
<!doctype html >
|
||||
<html lang="<?php echo $lang ?>" <?php
|
||||
<!doctype html >
|
||||
<html lang="<?php echo $lang ?>" <?php
|
||||
// dark mode checker
|
||||
if (isset($_SESSION['darkmode']) && $_SESSION['darkmode'] == 'true') {
|
||||
echo 'data-bs-theme="dark"';
|
||||
} ?>
|
||||
<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 name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title><?php
|
||||
$pageTitle = "";
|
||||
if (isset($title)) {
|
||||
$pageTitle .= $title . " | ";
|
||||
}
|
||||
$pageTitle .= $config['app']['name'];
|
||||
|
||||
|
||||
echo $pageTitle; ?></title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/css/bootstrap.min.css"
|
||||
integrity="sha512-jnSuA4Ss2PkkikSOLtYs8BlYIeeIK1h99ty4YfvRPAlzr377vr3CXDb7sb7eEEBYjDtcYj+AjBH3FLv5uSJuXg=="
|
||||
crossorigin="anonymous" referrerpolicy="no-referrer"/>
|
||||
<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 require_once 'includes/hreflang.php';
|
||||
|
||||
if (isset($specialStyle) && in_array($_SERVER['SCRIPT_NAME'], $specialStyle)) { ?>
|
||||
<style>
|
||||
.card {
|
||||
height: 160px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
<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 name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title><?php
|
||||
$pageTitle = "";
|
||||
if (isset($title)) {
|
||||
$pageTitle .= $title . " | ";
|
||||
}
|
||||
$pageTitle .= $config['app']['name'];
|
||||
|
||||
.card-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
echo $pageTitle; ?></title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/css/bootstrap.min.css"
|
||||
integrity="sha512-jnSuA4Ss2PkkikSOLtYs8BlYIeeIK1h99ty4YfvRPAlzr377vr3CXDb7sb7eEEBYjDtcYj+AjBH3FLv5uSJuXg=="
|
||||
crossorigin="anonymous" referrerpolicy="no-referrer"/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"
|
||||
integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg=="
|
||||
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">
|
||||
|
||||
.card-text {
|
||||
flex-grow: 1;
|
||||
}
|
||||
<?php require_once 'includes/hreflang.php';
|
||||
|
||||
.btn {
|
||||
margin-top: auto;
|
||||
}
|
||||
// if the script_name starts with /mix/, display this style
|
||||
// it has to check the beginning, not just as part of the array
|
||||
// because the page can be /mix/1 or /mix/2
|
||||
if (str_starts_with($_SERVER['SCRIPT_NAME'], '/mix/')) {
|
||||
?>
|
||||
<style>
|
||||
#audio-player {
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
<?php } ?>
|
||||
</head>
|
||||
<body class="bg-body">
|
||||
.player-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
#play-pause-btn {
|
||||
background-color: #0d6efd; /* Bootstrap primary color */
|
||||
border: none;
|
||||
color: white;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#play-pause-btn:hover {
|
||||
background-color: #0b5ed7;
|
||||
}
|
||||
|
||||
#seek-bar {
|
||||
flex-grow: 1;
|
||||
height: 4px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#time-display {
|
||||
font-size: 14px;
|
||||
color: #6c757d; /* Bootstrap secondary text color */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<?php }
|
||||
|
||||
if (isset($specialStyle) && in_array($_SERVER['SCRIPT_NAME'], $specialStyle)) {
|
||||
// this style is for the buttons on the list pages so the buttons look better only on mixpages, djs, genres
|
||||
// not mixes, because it's not a list like that
|
||||
?>
|
||||
|
||||
<style>
|
||||
.card {
|
||||
height: 160px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.card-text {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
<?php }
|
||||
|
||||
require_once 'header-meta.php'; ?>
|
||||
</head>
|
||||
<body class="bg-body">
|
||||
<?php
|
||||
if (isset($config['seo']['google']) && $config['seo']['google']) {
|
||||
echo get_google_tag_manager_body($config['seo']['gtm']['key']);
|
||||
|
|
|
@ -14,8 +14,8 @@ foreach ($languages as $key => $value) {
|
|||
}
|
||||
|
||||
// dedupe $list
|
||||
$list = array_unique($list);
|
||||
$list = array_unique($list);
|
||||
|
||||
foreach ($list as $link) {
|
||||
echo $link;
|
||||
}
|
||||
foreach ($list as $link) {
|
||||
echo $link;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
$lang = $_SESSION['lang'] ?? $config['app']['locale'];
|
||||
|
||||
if (!isset($_SESSION['lang'])) {
|
||||
$_SESSION['lang'] = $lang;
|
||||
}
|
||||
|
@ -8,4 +9,5 @@ if (isset($_GET['lang'])) {
|
|||
$lang = $_GET['lang'];
|
||||
$_SESSION['lang'] = $lang;
|
||||
}
|
||||
|
||||
$locale = loadLocale($lang);
|
||||
|
|
|
@ -78,12 +78,11 @@ $current_lang = $_SESSION['lang'] ?? $config['app']['locale'];
|
|||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<?php
|
||||
if (isset($_SESSION['user'])) {
|
||||
echo '<a class="nav-link" href="/profile.php">' . $locale['userProfile'] . '</a>';
|
||||
echo '<a class="nav-link" href="/profile">' . $locale['userProfile'] . '</a>';
|
||||
} else {
|
||||
echo '<a class="nav-link" href="/login.php">' . $locale['login'] . '</a>';
|
||||
echo '<a class="nav-link" href="/login">' . $locale['login'] . '</a>';
|
||||
}
|
||||
?>
|
||||
<form class="d-flex" role="search">
|
||||
|
@ -114,7 +113,7 @@ $current_lang = $_SESSION['lang'] ?? $config['app']['locale'];
|
|||
function updateDarkModeOnServer(value) {
|
||||
// Create a new AJAX request
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', 'settings.php', true);
|
||||
xhr.open('POST', '/settings.php', true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
// Define what happens on successful data submission
|
||||
|
|
|
@ -61,8 +61,11 @@ return [
|
|||
"share" => "Share",
|
||||
"sahrethismix" => "Share this mix",
|
||||
"sharethismixshow" => "Share this mixshow",
|
||||
|
||||
|
||||
|
||||
"rss" => "RSS",
|
||||
"year" => "Year",
|
||||
"sharetotwitter" => "Share to X (formerly Twitter)",
|
||||
"sharetofb" => "Share to Facebook",
|
||||
"sharetoig" => "Share to Instagram",
|
||||
"copyurl" => "Copy URL",
|
||||
|
||||
];
|
283
mix.php
283
mix.php
|
@ -9,7 +9,6 @@ use DJMixHosting\Mix;
|
|||
use DJMixHosting\Mixshow;
|
||||
use DJMixHosting\Playcount;
|
||||
|
||||
|
||||
$db = new Database($config);
|
||||
$mixFound = false;
|
||||
if (isset($_GET['mix']) && $_GET['mix'] != "") {
|
||||
|
@ -32,8 +31,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
|
|||
$playcount->updatePlaycount();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
require_once 'includes/header.php'; ?>
|
||||
<section>
|
||||
<div class="container py-5">
|
||||
|
@ -42,7 +39,7 @@ require_once 'includes/header.php'; ?>
|
|||
<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="/mixes.php"><?php echo $locale['mixes']; ?></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() != "") {
|
||||
|
@ -81,11 +78,21 @@ require_once 'includes/header.php'; ?>
|
|||
if ($mix->is_download_only()) {
|
||||
echo "<a href='/mix/" . $mix->get_slug() . "/download" . "' class='btn btn-primary'>" . $locale['download'] . "</a>";
|
||||
} else {
|
||||
echo "<audio controls controlsList='nodownload'>";
|
||||
$url = $mix->get_url();
|
||||
echo "<source src='" . $url . "' type='audio/mpeg'>";
|
||||
echo $locale['audioNotSupported'];
|
||||
echo "</audio>";
|
||||
?>
|
||||
<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
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -93,9 +100,12 @@ require_once 'includes/header.php'; ?>
|
|||
</div>
|
||||
</div>
|
||||
<div class="card mb-4">
|
||||
<div class="card-body bg-body-secondary text-center">
|
||||
<a href="#" class="btn btn-secondary w-100 mb-2"
|
||||
id="shareBtn"><?php echo $locale['share']; ?></a>
|
||||
<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
|
||||
|
||||
|
@ -375,61 +385,194 @@ require_once 'includes/header.php'; ?>
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="shareModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<span class="close">×</span>
|
||||
<h2><?php echo $locale['share']; ?></h2>
|
||||
<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 urlencode('https://utahsdjs.com/mix/' . $_GET['mix']); ?>"
|
||||
target="_blank" class="btn btn-primary w-100 mb-2">Share to Facebook</a>
|
||||
<a href="https://twitter.com/intent/tweet?url=<?php echo urlencode('https://utahsdjs.com/mix/' . $_GET['mix']); ?>"
|
||||
target="_blank" class="btn btn-info w-100 mb-2">Share to X (Twitter)</a>
|
||||
<a href="https://www.instagram.com/" target="_blank" class="btn btn-danger w-100">Share to Instagram</a>
|
||||
<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>
|
||||
// Get the modal
|
||||
var modal = document.getElementById("shareModal");
|
||||
|
||||
// Get the button that opens the modal
|
||||
var btn = document.getElementById("shareBtn");
|
||||
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';
|
||||
|
||||
// Get the <span> element that closes the modal
|
||||
var span = document.getElementsByClassName("close")[0];
|
||||
|
||||
// Get the copy link button
|
||||
var copyLinkBtn = document.getElementById("copyLinkBtn");
|
||||
|
||||
// Get the URL to be copied
|
||||
var urlToCopy = window.location.href;
|
||||
|
||||
// When the user clicks the button, open the modal
|
||||
btn.onclick = function () {
|
||||
modal.style.display = "block";
|
||||
}
|
||||
|
||||
// When the user clicks on <span> (x), close the modal
|
||||
span.onclick = function () {
|
||||
modal.style.display = "none";
|
||||
}
|
||||
|
||||
// When the user clicks anywhere outside of the modal, close it
|
||||
window.onclick = function (event) {
|
||||
if (event.target == modal) {
|
||||
modal.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
// When the user clicks the copy link button, copy the URL to the clipboard
|
||||
copyLinkBtn.onclick = function () {
|
||||
navigator.clipboard.writeText(urlToCopy).then(function () {
|
||||
alert('URL copied to clipboard');
|
||||
}, function (err) {
|
||||
alert('Failed to copy URL: ', err);
|
||||
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">
|
||||
|
@ -446,27 +589,5 @@ require_once 'includes/header.php'; ?>
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
// 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>
|
||||
|
||||
<?php require_once 'includes/footer.php'; ?>
|
76
mixshow.php
76
mixshow.php
|
@ -1,7 +1,6 @@
|
|||
<?php
|
||||
|
||||
require_once 'includes/globals.php';
|
||||
|
||||
require_once 'vendor/autoload.php';
|
||||
|
||||
use DJMixHosting\Database;
|
||||
|
@ -52,17 +51,19 @@ require_once 'includes/header.php';
|
|||
<img src="<?php echo $mixshow->get_cover(); ?>"
|
||||
alt="avatar"
|
||||
class="rounded-circle img-fluid" style="width: 150px;">
|
||||
<h5 class="my-3"><?php echo $mixshow->get_name();
|
||||
?></h5>
|
||||
<?php
|
||||
<h5 class="my-3"><?php echo $mixshow->get_name(); ?></h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-4">
|
||||
<div class="card-body bg-body-secondary text-center ">
|
||||
<a type="button" id="followBtn" class="w-100 mb-2 btn btn-secondary">
|
||||
<?php echo $locale['follow']; ?>
|
||||
</a>
|
||||
<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>
|
||||
|
||||
|
||||
?>
|
||||
<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>
|
||||
|
@ -163,6 +164,59 @@ require_once 'includes/header.php';
|
|||
</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/mixshow/' . $_GET['mixshow'];
|
||||
$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-info w-100 mb-2" onclick="hideModal()">Share to 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();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<?php else: ?>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
|
3371
privacy.php
Normal file
3371
privacy.php
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,2 +1,8 @@
|
|||
User-agent: *
|
||||
Crawl-delay: 10
|
||||
|
||||
Disallow: /*?*mix=
|
||||
Disallow: /*?*lang=
|
||||
Disallow: /*?*mixshow=
|
||||
Disallow: /*?*genre=
|
||||
Disallow: /*?*dj=
|
||||
|
|
2
rss.php
Normal file
2
rss.php
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?php
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue