diff --git a/css/zoostyle.css b/css/zoostyle.css index af3df26f3..cd63f7c2e 100644 --- a/css/zoostyle.css +++ b/css/zoostyle.css @@ -327,6 +327,20 @@ P.zktitle A { } /* general */ +.playlistHdr { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 11pt; + font-weight: bold; + color: white; + background-color: #2530A7; + line-height: 24px; +} +.playlistHdr > div { + font-size: 11pt; + float: right; + font-size: 10px; +} + TH { font-family: verdana, arial, helvetica, sans-serif; font-size: 11pt; @@ -458,18 +472,52 @@ A.calLink { color: #000000; background-color: #cccccc; } + +/* up/down & edit links for playlist edits */ +.songManager { + top: 8px; + height: 20px; + width: 24px; + position: relative; + font-size:12px; +} + +.songManager a { + position: absolute; + line-height: 1.4; + background-repeat: no-repeat; + width: 10px; + height: 4px; +} .songUp, .sortUp { + top: 0px; background-position: center; background-repeat: no-repeat; background-image: URL('../img/arrow_up.gif'); } .songDown, .sortDown { + top: 8px; background-position: center; background-repeat: no-repeat; background-image: URL('../img/arrow_down.gif'); } +.songEdit { + top: -2px; + left: 12px; + font-size:14px; +} + +.songLabel { + font-size:10px; +} .albumReview { background-image: URL('../img/rinfo.gif'); + width:11px; + height:11px; +} +.songDivider hr { + height: 0px; + background-color: gray; } .editorUp { top: 0px; diff --git a/db/zkdbSchema.sql b/db/zkdbSchema.sql index 4ab302e53..cfbacda75 100644 --- a/db/zkdbSchema.sql +++ b/db/zkdbSchema.sql @@ -353,7 +353,6 @@ CREATE TABLE IF NOT EXISTS `tracknames` ( -- -- Table structure for table `tracks` --- CREATE TABLE IF NOT EXISTS `tracks` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -363,6 +362,7 @@ CREATE TABLE IF NOT EXISTS `tracks` ( `track` varchar(80) DEFAULT NULL, `album` varchar(80) DEFAULT NULL, `label` varchar(80) DEFAULT NULL, + `created` timestamp DEFAULT NULL, PRIMARY KEY (`id`), KEY `list` (`list`), KEY `tag` (`tag`), diff --git a/engine/impl/Library.php b/engine/impl/Library.php index c4985d7b8..848050ed6 100644 --- a/engine/impl/Library.php +++ b/engine/impl/Library.php @@ -246,7 +246,7 @@ public function markAlbumsReviewed(&$albums, $loggedIn = 0) { $chain = []; $tags = []; $queryset = ""; - for($i = 0; $i < sizeof($albums); $i++) { + for($i = 0; $albums != null && $i < sizeof($albums); $i++) { $tag = array_key_exists("tag", $albums[$i])?$albums[$i]["tag"]:0; if($tag) { if(array_key_exists($tag, $tags)) diff --git a/engine/impl/Playlist.php b/engine/impl/Playlist.php index 747eca0ce..c079dde9f 100644 --- a/engine/impl/Playlist.php +++ b/engine/impl/Playlist.php @@ -24,6 +24,8 @@ namespace ZK\Engine; +use \Datetime; +use \DateTimeZone; use ZK\Engine\ILibrary; @@ -162,7 +164,7 @@ public function updatePlaylist($playlist, $date, $time, $description, $airname) } public function getTrack($id) { - $query = "SELECT tag, artist, track, album, label, id FROM tracks " . + $query = "SELECT created, tag, artist, track, album, label, id FROM tracks " . "WHERE id = ?"; $stmt = $this->prepare($query); $stmt->bindValue(1, (int)$id, \PDO::PARAM_INT); @@ -170,7 +172,7 @@ public function getTrack($id) { } public function getTracks($playlist, $desc = 0) { - $query = "SELECT tag, artist, track, album, label, id FROM tracks " . + $query = "SELECT tag, artist, track, album, label, id, created FROM tracks " . "WHERE list = ? ORDER BY id"; if($desc) $query .= " DESC"; @@ -178,23 +180,59 @@ public function getTracks($playlist, $desc = 0) { $stmt->bindValue(1, (int)$playlist, \PDO::PARAM_INT); return $this->execute($stmt); } - - public function insertTrack($playlist, $tag, $artist, $track, $album, $label) { + + // return true if "now" is within the show start/end time & date. + // NOTE: this routine must be tolerant of improperly formatted dates. + public function isWithinShow($listRow) { + $TIME_FORMAT = "Y-m-d Gi"; // eg, 2019-01-01 1234 + $retVal = false; + + try { + $timeAr = explode("-", $listRow[2]); + if (count($timeAr) == 2) { + $timeStr1 = $listRow[1] . " " . $timeAr[0]; + $start = DateTime::createFromFormat($TIME_FORMAT, $timeStr1); + $endStr = $timeAr[1] == "0000" ? "2359" : $timeAr[1]; + $timeStr2 = $listRow[1] . " " . $endStr; + $end = DateTime::createFromFormat($TIME_FORMAT, $timeStr2); + + if (isset($start) && isset($end)) { + $now = new DateTime("now"); + $retVal = (($now > $start) && ($now < $end)); + } + } + } catch (Throwable $t) { + ; + } + return $retVal; + } + + public function insertTrack($playlistId, $tag, $artist, $track, $album, $label) { + $row = Engine::api(IPlaylist::class)->getPlaylist($playlistId, 1); + + // log time iff 'now' is within playlist start/end time. + $doTimestamp = self::isWithinShow($row); + $timeName = $doTimestamp ? "created, " : ""; + $timeValue = $doTimestamp ? "NOW(), " : ""; + // Insert tag? - $noTag = ($tag == 0) || ($tag == ""); + $haveTag = ($tag != 0) && ($tag != ""); + $tagName = $haveTag ? ", tag" : ""; + $tagValue = $haveTag ? ", ?" : ""; - $query = "INSERT INTO tracks " . - "(list, artist, track, album, label" . ($noTag?")":", tag)") . - " VALUES (?, ?, ?, ?, ?" . - ($noTag?")":", ?)"); + $names = "(" . $timeName . "list, artist, track, album, label " . $tagName . ")"; + $values = " VALUES (" . $timeValue . "?, ?, ?, ?, ?" . $tagValue . ");"; + + $query = "INSERT INTO tracks " . ($names) . ($values); $stmt = $this->prepare($query); - $stmt->bindValue(1, (int)$playlist, \PDO::PARAM_INT); + $stmt->bindValue(1, (int)$playlistId, \PDO::PARAM_INT); $stmt->bindValue(2, $artist); $stmt->bindValue(3, $track); $stmt->bindValue(4, $album); $stmt->bindValue(5, $label); - if(!$noTag) + if($haveTag) $stmt->bindValue(6, $tag); + return $stmt->execute(); } diff --git a/ui/Playlists.php b/ui/Playlists.php index 5fb20eab8..6de7d1ea1 100644 --- a/ui/Playlists.php +++ b/ui/Playlists.php @@ -24,6 +24,7 @@ namespace ZK\UI; + use ZK\Engine\Engine; use ZK\Engine\IDJ; use ZK\Engine\ILibrary; @@ -122,6 +123,24 @@ private function composeTime($fromTime, $toTime) { return $fromTime . "-" . $toTime; } + public static function showStartTime($timeRange) { + $retVal = "??"; + $timeAr = explode("-", $timeRange); + if (count($timeAr) == 2) + $retVal = self::hourToAMPM($timeAr[0]); + + return $retVal; + } + + public static function showEndTime($timeRange) { + $retVal = "??"; + $timeAr = explode("-", $timeRange); + if (count($timeAr) == 2) + $retVal = self::hourToAMPM($timeAr[1]); + + return $retVal; + } + public static function hourToAMPM($hour, $full=0) { $h = (int)floor($hour/100); $m = (int)$hour % 100; @@ -147,6 +166,22 @@ public static function timeToAMPM($time) { } else return strtolower(htmlentities($time)); } + + public static function timestampToDate($time) { + if ($time == null || $time == '') { + return ""; + } else { + return date('D M d, Y ', strtotime($time)); + } + } + + public static function timestampToAMPM($time) { + if ($time == null || $time == '') { + return ""; + } else { + return date('h:ia', strtotime($time)); + } + } public static function timeToZulu($time) { if(strlen($time) == 9 && $time[4] == '-') { @@ -237,6 +272,7 @@ private function emitEditList($editlist) { list($year, $month, $day) = explode("-", $date); if(strlen($fromtime) && strlen($totime)) $time = $this->composeTime($fromtime, $totime); + if(checkdate($month, $day, $year) && ($time != "") && ($description != "")) { // Success - Run the query @@ -456,6 +492,17 @@ public function emitEditListSelNormal() { UI::setFocus("playlist"); } + private function makeEditDiv($row, $playlist) { + $sessionId = $this->session->getSessionID(); + $href = "?session=" . $sessionId . "&playlist=" . $playlist . "&id=" . + $row["id"] . "&action=" . $this->action . "&"; + $editLink = "✏"; + $upLink = ""; + $downLink = ""; + $retVal = "