db = $db; $this->loadDJs = $loadDJs; if (ctype_digit((string)$value)) { $this->id = (int)$value; $loaded = $this->loadById(); } else { $this->slug = $value; $loaded = $this->loadBySlug(); } if (!$loaded) { throw new Exception("Mix not found."); } } /** * Loads mix data by its ID. */ private function loadById(): bool { $mix = $this->getMixById(); if ($mix && !empty($mix['title'])) { return $this->buildMix($mix); } return false; } /** * Loads mix data by its slug. */ private function loadBySlug(): bool { $mix = $this->getMixBySlug(); if ($mix && !empty($mix['title'])) { return $this->buildMix($mix); } return false; } /** * Retrieve mix data by ID. */ private function getMixById(): ?array { // If the current user is admin, show all mixes; // Otherwise, only return mixes with pending = 0. $isAdmin = isset($_SESSION['user']) && isset($_SESSION['user']['role']) && $_SESSION['user']['role'] === 'admin'; $query = $isAdmin ? "SELECT * FROM mix WHERE id = ?" : "SELECT * FROM mix WHERE id = ? AND pending = 0"; $stmt = $this->db->prepare($query); $stmt->bind_param("i", $this->id); $stmt->execute(); $result = $stmt->get_result(); $mix = $result->fetch_assoc(); $stmt->close(); return $mix ?: null; } /** * Retrieve mix data by slug. */ private function getMixBySlug(): ?array { $isAdmin = isset($_SESSION['user']) && isset($_SESSION['user']['role']) && $_SESSION['user']['role'] === 'admin'; $query = $isAdmin ? "SELECT * FROM mix WHERE slug = ?" : "SELECT * FROM mix WHERE slug = ? AND pending = 0"; $stmt = $this->db->prepare($query); $stmt->bind_param("s", $this->slug); $stmt->execute(); $result = $stmt->get_result(); $mix = $result->fetch_assoc(); $stmt->close(); return $mix ?: null; } /** * Build the mix object from database data. */ private function buildMix(array $mix): bool { $this->id = (int)$mix['id']; $this->name = $mix['title'] ?? ""; $this->slug = $mix['slug'] ?? ""; $this->description = $mix['description'] ?? ""; $this->cover = $this->legacyFix($mix['cover'] ?? ""); $this->url = $this->legacyFix($mix['url'] ?? ""); $this->seconds = (int)($mix['seconds'] ?? 0); $this->duration = $this->configureDuration(); $this->download_only = (bool)($mix['mediaplayer'] ?? true); $this->recorded = $mix['recorded'] ?? null; $this->created = $mix['created'] ?? null; $this->updated = $mix['lastupdated'] ?? null; $this->enabled = (bool)($mix['pending'] ?? false); if ($this->loadDJs) { require_once 'DJ.php'; $this->djs[] = new DJ($mix['dj1'], $this->db); if (!empty($mix['dj2'])) { $this->djs[] = new DJ($mix['dj2'], $this->db); } if (!empty($mix['dj3'])) { $this->djs[] = new DJ($mix['dj3'], $this->db); } $this->djs = array_filter($this->djs); } $this->loadMixMeta(); $this->tracklist = $this->evaluateTracklist(); return true; } /** * Fix legacy URL paths. */ private function legacyFix(string $item): string { if (str_starts_with($item, "/djs/")) { return "https://cdn.utahsdjs.com" . substr($item, 4); } return $item; } /** * Configure a formatted duration based on seconds. */ private function configureDuration(): array { $seconds = $this->seconds; $hours = floor($seconds / 3600); $minutes = floor(($seconds / 60) % 60); $secs = $seconds % 60; $time = ($hours > 0) ? sprintf("%02d:%02d:%02d", $hours, $minutes, $secs) : sprintf("%02d:%02d", $minutes, $secs); return [ 'h' => $hours, 'm' => $minutes, 's' => $secs, 't' => $time, 'S' => $this->seconds ]; } /** * Load mix meta data. */ private function loadMixMeta(): 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 $entry) { switch ($entry['attribute']) { case "genre": $this->genres[] = $entry['value']; break; case "related": $this->related_mixes[] = $entry['value']; break; case "playcount": $this->playcount = (int)$entry['value']; break; case "downloads": $this->downloads = (int)$entry['value']; break; case "tracklist": $this->tracklist = $entry['value']; break; case "mixshow": $this->mixshow[] = $entry['value']; break; default: // Handle additional meta attributes if needed. break; } } } /** * Evaluate the tracklist data. */ private function evaluateTracklist() { if (empty($this->tracklist)) { return []; } if (is_array($this->tracklist)) { return $this->tracklist; } return explode("\n", (string)$this->tracklist); } // Getter methods for mix properties. public function getId(): int { return $this->id; } public function getName(): string { return $this->name; } public function getSlug(): string { return $this->slug; } public function getDescription(): string { return $this->description; } public function getCover(): string { return $this->cover; } public function getUrl(): string { return $this->url; } public function getSeconds(): int { return $this->seconds; } public function isDownloadOnly(): bool { return $this->download_only; } public function getDJs(): array { return $this->djs; } public function getGenres(): array { return $this->genres; } public function getRecorded(): ?string { return $this->recorded; } public function getDownloads(): int { return $this->downloads; } public function getCreated(): ?string { return $this->created; } public function getUpdated(): ?string { return $this->updated; } public function getPlaycount(): int { return $this->playcount; } public function getTracklist(): array { return $this->evaluateTracklist(); } public function getRelatedMixes(): array { return $this->related_mixes; } public function getDuration(): array { return $this->duration; } public function getMixshow(): array { return $this->mixshow; } public function getDownloadUrl(): string { return "https://beta.utahsdjs.com/mix/{$this->slug}/download"; } public function getPageUrl(): string { return "https://beta.utahsdjs.com/mix/{$this->slug}"; } }