diff --git a/Dockerfile b/Dockerfile index 01cc4375a4d2c72844b0b78cfaf622fbc2dfd7a9..46e3adb512f4baeacd924678f36849aee3735115 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,4 +6,4 @@ RUN apt-get install -y libpq-dev \ RUN a2enmod rewrite \ && service apache2 restart RUN apt install -y ffmpeg -#COPY src/web .htaccess /var/www/html/ \ No newline at end of file +COPY src/web /var/www/html/ \ No newline at end of file diff --git a/Dockerfile-obj b/Dockerfile-obj index 4928d4b7c0c8332d6a215a20f74dd56e6b3e1c56..a70de058320f1f4ff6985e9290d2e73a6942efb7 100644 --- a/Dockerfile-obj +++ b/Dockerfile-obj @@ -3,4 +3,4 @@ RUN apt update \ && apt install vim -y RUN a2enmod rewrite \ && service apache2 restart -#COPY src/obj-storage .htaccess /var/www/html/ \ No newline at end of file +COPY src/obj-storage /var/www/html/ \ No newline at end of file diff --git a/README.md b/README.md index 71b0b15c09c1d776142d5afef3f4d9b307239b9f..3b168bfd22acb42acbe011e282ccf0cb19a797d4 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,7 @@ Aplikasi web ini merupakan platform sharing music. # Cara Menjalankan server 1. Masuk ke folder utama hasil git clone. -2. Jalankan command berikut: docker compose up --build -d . -3. Akses pada localhost:8008. +2. Jalankan command berikut: chmod +x ./scripts/build-image.sh && ./scripts/build-image.sh # Screenshot diff --git a/docker-compose.yml b/docker-compose.yml index a1e826a47bc1f67b49d1c02324cfc36bb6e54052..c8c65897e266d945a22746ce6aa655ed6115fad6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,8 +11,6 @@ services: DB_USERNAME: "web" DB_PASS: "web" OBJ_STORAGE_PASS: "$2y$10$SVu1w2aJ3pn9JJApJdjXpO.sa7HZCRnlnn6kv5Yq.0n6gp8Pj0Cy2" - volumes: - - ./src/web:/var/www/html/:ro networks: - all-bridge depends_on: @@ -36,12 +34,12 @@ services: context: . dockerfile: Dockerfile-obj restart: always + container_name: object-storage environment: OBJ_STORAGE_PASS: "$2y$10$SVu1w2aJ3pn9JJApJdjXpO.sa7HZCRnlnn6kv5Yq.0n6gp8Pj0Cy2" OBJ_LOCATION: "/opt/obj_storage" volumes: - object-storage:/opt/obj_storage:rw - - ./src/obj-storage:/var/www/html/:ro networks: - all-bridge depends_on: diff --git a/scripts/build-image.sh b/scripts/build-image.sh old mode 100644 new mode 100755 index ce096bac1ad2e7c6eec731197a2b126c245fa237..9d7fac7ff479cab6c09c13e9cbe5c297fd8e24fb --- a/scripts/build-image.sh +++ b/scripts/build-image.sh @@ -1 +1,3 @@ -docker build -t tubes-1:latest . \ No newline at end of file +docker compose up --build -d \ + && docker container exec object-storage chown www-data /opt/obj_storage \ + && docker container exec -u www-data object-storage chmod 770 /opt/obj_storage \ No newline at end of file diff --git a/src/obj-storage/.htaccess b/src/obj-storage/.htaccess index f49abc9843dd44a98ffc2461b40c377d1b6ddf9e..5bab97b6ec99446d43f7750b1da1e4be328a2a3b 100644 --- a/src/obj-storage/.htaccess +++ b/src/obj-storage/.htaccess @@ -2,6 +2,9 @@ AddType text/css .css AddType text/javascript .js AddType image/svg+xml svg svgz AddEncoding gzip svgz +php_value memory_limit 256M +php_value upload_max_filesize 128M +php_value post_max_size 130M RewriteEngine On RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.gif|robots\.txt)$ [NC] diff --git a/src/web/.htaccess b/src/web/.htaccess index f49abc9843dd44a98ffc2461b40c377d1b6ddf9e..5bab97b6ec99446d43f7750b1da1e4be328a2a3b 100644 --- a/src/web/.htaccess +++ b/src/web/.htaccess @@ -2,6 +2,9 @@ AddType text/css .css AddType text/javascript .js AddType image/svg+xml svg svgz AddEncoding gzip svgz +php_value memory_limit 256M +php_value upload_max_filesize 128M +php_value post_max_size 130M RewriteEngine On RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.gif|robots\.txt)$ [NC] diff --git a/src/web/music/album.php b/src/web/music/album.php index 81f85efce364a91534d3f57a0b8ecb0fb1cd5c45..421d7cbeb9678481a4d42da223c2603e498e63f8 100644 --- a/src/web/music/album.php +++ b/src/web/music/album.php @@ -4,6 +4,11 @@ function addAlbum(string $accountId, string $albumName, string $year): int { $fileName = $_FILES['file']['name']; $fileName = str_replace(' ', '', $fileName); + if($_FILES['file']['size'] > 15485760) { + header('Location: /album/add?err=2', true, 303); + exit(); + } + // upload the file $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, 'object-storage:80/object'); diff --git a/src/web/music/music.php b/src/web/music/music.php index b4888f9e1c8a2d512e4a29c2262813feee38537b..8c199eb4e5c93cb29da82e311aac68d98c34fe18 100644 --- a/src/web/music/music.php +++ b/src/web/music/music.php @@ -4,6 +4,11 @@ function getDuration($filename): int { $dur = shell_exec("ffmpeg -i $filename 2>&1 | grep Duration | cut -d ' ' -f 4 | sed s/,//"); $dur = explode(':', $dur); + if (!isset($dur[0]) || !isset($dur[1]) || !isset($dur[2])) { + header('Location: /music/add?err=2', true, 303); + exit(); + } + return (int) $dur[0] * 3600 + (int) $dur[1] * 60 + (int) $dur[2]; } @@ -15,6 +20,11 @@ function addMusic(string $accountId, string $title, string $genre, string $year, return 450; } + if($_FILES['file']['size'] > 120485760) { + header('Location: /music/add?err=2', true, 303); + exit(); + } + // upload the file $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, 'object-storage:80/object'); diff --git a/src/web/presentation/home/css/home.css b/src/web/presentation/home/css/home.css index ab00717bec6eb0b92358c5ed5d291c0658435e45..93784d52bf848bb5c74b8145cca9bfe41a350a9f 100644 --- a/src/web/presentation/home/css/home.css +++ b/src/web/presentation/home/css/home.css @@ -43,6 +43,7 @@ justify-content: space-evenly; background-color: rgb(206, 206, 206); border-radius: 5px; + cursor: pointer; } .album img { diff --git a/src/web/presentation/home/home.php b/src/web/presentation/home/home.php index 87eb832c3ed4cf6ea441ff7ab293ddd470dd17f7..db2c29408a4f17477fb327919773215a2a767293 100644 --- a/src/web/presentation/home/home.php +++ b/src/web/presentation/home/home.php @@ -2,6 +2,7 @@ require_once 'db/db-executor.php'; require_once 'auth/authenticator.php'; +require_once 'util/album-finder.php'; $errMsg = ''; diff --git a/src/web/presentation/home/home.view.php b/src/web/presentation/home/home.view.php index 55def81c0b6cb5f0288190bb79b98dddc07e6854..ea3de69fce336728043acdffe653b1ee67bbfca5 100644 --- a/src/web/presentation/home/home.view.php +++ b/src/web/presentation/home/home.view.php @@ -3,6 +3,7 @@ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <script src="/presentation/home/js/home.js" defer></script> <link rel="stylesheet" type="text/css" href="/presentation/home/css/home.css"> <link rel="stylesheet" type="text/css" href="/presentation/template/css/sidebar.css"> <link rel="stylesheet" type="text/css" href="/presentation/template/css/navbar.css"> diff --git a/src/web/presentation/home/js/home.js b/src/web/presentation/home/js/home.js index 7a8af873d78b1c57f80e33677221d38e58146163..dde5f74592d2e62061667ae9953a52ec01c740c2 100644 --- a/src/web/presentation/home/js/home.js +++ b/src/web/presentation/home/js/home.js @@ -3,9 +3,8 @@ const albums = document.querySelectorAll(".album"); albums.forEach((album) => { album.addEventListener("click", async (e) => { e.preventDefault(); - console.log(album.id); - // Redirect to album page + // Redirect window.location.href = `/album?id=${album.id}`; }); }); diff --git a/src/web/presentation/music/add/album.view.php b/src/web/presentation/music/add/album.view.php index c3e77a09f0c29f2684651424bdbcde8011bcdf06..d213895515b24baf97fdae3e569e6ffa39472e68 100644 --- a/src/web/presentation/music/add/album.view.php +++ b/src/web/presentation/music/add/album.view.php @@ -45,8 +45,8 @@ <form id="form" method="POST" enctype="multipart/form-data" onsubmit="return validate()"> <input type="text" name="title" class="input" id="input-title" placeholder="Album Title (Max. 255 characters)"> <input type="text" name="year" class="input" id="input-year" placeholder="Year"> - <label for="input-file" id="input-label">Select album cover</label> - <input type="file" name="file" id="input-file" placeholder="file"> + <label for="input-file" id="input-label">Select album cover (Max. 15 MB)</label> + <input type="file" name="file" id="input-file" placeholder="file" accept="image/jpeg, image/png"> <div id="submit-d"> <input type="submit" id="submit-b" value="Save"> </div> diff --git a/src/web/presentation/music/add/js/album.js b/src/web/presentation/music/add/js/album.js index cb98e3900114a2ee83df7700c89bfa9e88614e91..dde8c8d76a78de8a8b2cf2cfb7d089a944a2f1cf 100644 --- a/src/web/presentation/music/add/js/album.js +++ b/src/web/presentation/music/add/js/album.js @@ -22,6 +22,12 @@ function validate() { valid = false; } + const fileSize = document.forms["form"]["input-file"].files[0].size / 1024 / 1024; + if (fileSize > 15) { + errMsg = "File size exceeds 15 MB limit"; + valid = false; + } + if (!valid) { document.getElementById('err-msg').textContent = errMsg; } diff --git a/src/web/presentation/music/add/js/music.js b/src/web/presentation/music/add/js/music.js index f8ca953d917464ed4ef0cf4269cebcef48e08bbf..3ef624048d9558897fa8b3443c17140e80c261c8 100644 --- a/src/web/presentation/music/add/js/music.js +++ b/src/web/presentation/music/add/js/music.js @@ -35,6 +35,12 @@ function validate() { valid = false; } + const fileSize = document.forms["form"]["input-file"].files[0].size / 1024 / 1024; + if (fileSize > 120) { + errMsg = "File size exceeds 120 MB limit"; + valid = false; + } + if (!valid) { document.getElementById('err-msg').textContent = errMsg; } diff --git a/src/web/presentation/music/add/music.view.php b/src/web/presentation/music/add/music.view.php index 56d1c7dac7939f4d8e2bf000dc1a2051b1e05c2c..fcede11afa7a188b8a017d63e36729a05ba024f5 100644 --- a/src/web/presentation/music/add/music.view.php +++ b/src/web/presentation/music/add/music.view.php @@ -30,7 +30,7 @@ echo 'Please fill all the fields.'; break; case 2: - echo 'Invalid data.'; + echo 'Invalid data, please recheck all the data including the file.'; break; case 3: echo 'You already have a music with the same file name.'; @@ -50,8 +50,8 @@ <input type="text" name="album" class="input" id="input-album" placeholder="Album id"> <input type="text" name="genre" class="input" id="input-genre" placeholder="Genre (Max. 255 characters)"> <input type="text" name="year" class="input" id="input-year" placeholder="Year"> - <label for="input-file" id="input-label">Select music file</label> - <input type="file" name="file" id="input-file" placeholder="file"> + <label for="input-file" id="input-label">Select music file (Max. 120 MB)</label> + <input type="file" name="file" id="input-file" placeholder="file" accept="audio/mpeg"> <div id="submit-d"> <input type="submit" id="submit-b" value="Save"> </div> diff --git a/src/web/presentation/music/edit/css/editAlbum.css b/src/web/presentation/music/edit/css/editAlbum.css index cd8d7a7a085c931a3d9a095255fd95651f5fb204..949fe2370803f542b793a71360165180f1e9f0d4 100644 --- a/src/web/presentation/music/edit/css/editAlbum.css +++ b/src/web/presentation/music/edit/css/editAlbum.css @@ -1,3 +1,11 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: Roboto, serif; + z-index: 1; +} + html { height: 100%; width: 100%; @@ -9,23 +17,21 @@ body { width: 100%; } -/*.success-msg {*/ -/* margin: 10px 0;*/ -/* padding: 10px;*/ -/* border-radius: 3px;*/ -/* color: #270;*/ -/* background-color: #DFF2BF;*/ -/*}*/ +.main-wrapper { + padding: 0; + margin-left: 250px; +} #title { - margin: 36px !important; + padding-top: 10vh; font-size: 64px; font-weight: 300; text-align: center; } #form-d { - height: 50%; + height: 450px; + text-align: center } #form { @@ -54,8 +60,8 @@ body { .input { display: block; - width: 20%; - height: 10%; + width: 300px; + height: 50px; border: 1px solid #d3d3d3; margin: auto auto; padding-left: 1%; @@ -86,8 +92,8 @@ body { #submit-b { margin-top: 36px; text-align: center; - width: 15%; - height: 50%; + width: 256px; + height: 50px; background-color: #da0f47; border: none; color: white; diff --git a/src/web/presentation/music/edit/css/editMusic.css b/src/web/presentation/music/edit/css/editMusic.css index 62621e929b75a18fb088b2424f821634cc92ff55..3af8b75ade8194223cb8d877218c5e652faa17b1 100644 --- a/src/web/presentation/music/edit/css/editMusic.css +++ b/src/web/presentation/music/edit/css/editMusic.css @@ -1,3 +1,11 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: Roboto, serif; + z-index: 1; +} + html { height: 100%; width: 100%; @@ -9,15 +17,21 @@ body { width: 100%; } +.main-wrapper { + padding: 0; + margin-left: 250px; +} + #title { - margin: 36px !important; + padding-top: 10vh; font-size: 64px; font-weight: 300; text-align: center; } #form-d { - height: 50%; + height: 450px; + text-align: center } #form { @@ -46,8 +60,8 @@ body { .input { display: block; - width: 20%; - height: 10%; + width: 300px; + height: 50px; border: 1px solid #d3d3d3; margin: auto auto; padding-left: 1%; @@ -86,8 +100,8 @@ body { #submit-b { margin-top: 36px; text-align: center; - width: 15%; - height: 50%; + width: 256px; + height: 50px; background-color: #da0f47; border: none; color: white; diff --git a/src/web/presentation/music/edit/editAlbum.view.php b/src/web/presentation/music/edit/editAlbum.view.php index fe1b9ee0cee99f5442dc066e0cce78027155da74..f0cfdde65736e26c53679f1609d974fbcec080dc 100644 --- a/src/web/presentation/music/edit/editAlbum.view.php +++ b/src/web/presentation/music/edit/editAlbum.view.php @@ -34,45 +34,49 @@ if (is_numeric($id)) { <!DOCTYPE html> <html lang="en"> -<script src="/presentation/music/edit/js/editAlbum.js" defer></script> <head> <meta charset="UTF-8"> <title>Edit Album</title> + <script src="/presentation/music/edit/js/editAlbum.js" defer></script> <link rel="stylesheet" href="/presentation/music/edit/css/editAlbum.css"> + <link rel="stylesheet" type="text/css" href="/presentation/template/css/sidebar.css"> + <link rel="stylesheet" type="text/css" href="/presentation/template/css/navbar.css"> <link rel="preconnect" href="https://fonts.googleapis.com%22%3E/"> <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet"> </head> <body> -<p id="title">Edit Album</p> -<div class="img-container"> - <img src="<?php if ($exists) echo getAlbumImage(); else echo '/presentation/music/edit/img/defalbum.jpg' ?>" alt="Album"> -</div> -<!--<div class="success-msg">--> -<!-- <i class="fa fa-check"></i>--> -<!-- Album saved successfully--> -<!--</div>--> -<div class="fields" id="form-d"> - <form id="form" method="post" enctype="multipart/form-data"> - <input type="text" class="input" id="input-title" name="name" placeholder="Album Title" value="<?php echo $name ?>"> - <input type="text" class="input" id="input-artist" name="artist" placeholder="Artist" value="<?php echo $artist ?>"> - <input type="text" class="input" id="input-year" name="year" placeholder="Year" value="<?php echo $year ?>"> - <input type="hidden" name="id" value="<?php echo $id ?>"> - <div id="file-sub"> - <label id="input-label">Select album cover</label> - <input type="file" name="file" id="input-file" accept="image/jpeg, image/png"> - <button type="button" id="file-r" hidden="hidden">Cancel</button> - </div> - <div id="submit-d"> - <input type="submit" id="submit-b" value="Save"> - </div> - <div class="aux-d" id="cancel-d"> - <a href="#" id="cancel-b">Cancel</a> +<div class="wrapper"> + <?php require 'presentation/template/sidebar.php' ?> + <div class="main-wrapper"> + <?php require 'presentation/template/navbar.php' ?> + <p id="title">Edit Album</p> + <div class="img-container"> + <img src="<?php if ($exists) echo getAlbumImage(); else echo '/presentation/music/edit/img/defalbum.jpg' ?>" alt="Album"> </div> - <div class="aux-d" id="delete-d"> - <a href="<?php echo "javascript:deleteAlbum($id)" ?>" id="delete-b">Delete</a> + <div class="fields" id="form-d"> + <form id="form" method="post" enctype="multipart/form-data"> + <input type="text" class="input" id="input-title" name="name" placeholder="Album Title" value="<?php echo $name ?>"> + <input type="text" class="input" id="input-artist" name="artist" placeholder="Artist" value="<?php echo $artist ?>"> + <input type="text" class="input" id="input-year" name="year" placeholder="Year" value="<?php echo $year ?>"> + <input type="hidden" name="id" value="<?php echo $id ?>"> + <div id="file-sub"> + <label id="input-label">Select album cover</label> + <input type="file" name="file" id="input-file" accept="image/jpeg, image/png"> + <button type="button" id="file-r" hidden="hidden">Cancel</button> + </div> + <div id="submit-d"> + <input type="submit" id="submit-b" value="Save"> + </div> + <div class="aux-d" id="cancel-d"> + <a href="javascript:history.back()" id="cancel-b">Cancel</a> + </div> + <div class="aux-d" id="delete-d"> + <a href="<?php echo "javascript:deleteAlbum($id)" ?>" id="delete-b">Delete</a> + </div> + </form> </div> - </form> + </div> </div> </body> </html> \ No newline at end of file diff --git a/src/web/presentation/music/edit/editMusic.view.php b/src/web/presentation/music/edit/editMusic.view.php index a1c3e81edd395e83f57816be819b31dc2779a912..db72787c5c8780f49474661131b4973d24eaa445 100644 --- a/src/web/presentation/music/edit/editMusic.view.php +++ b/src/web/presentation/music/edit/editMusic.view.php @@ -40,41 +40,49 @@ if (is_numeric($id)) { <!DOCTYPE html> <html lang="en"> -<script src="/presentation/music/edit/js/editMusic.js" defer></script> - <head> - <meta charset="UTF-8"> - <title>Edit Music</title> - <link rel="stylesheet" type="text/css" href="/presentation/music/edit/css/editMusic.css"> - <link rel="preconnect" href="https://fonts.googleapis.com%22%3E/"> - <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin> - <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet"> - </head> - <body> - <p id="title">Edit Music</p> - <div class="img-container"> - <img src="<?php if ($exists) echo getAlbumImage(); else echo '/presentation/music/edit/img/defalbum.jpg' ?>" alt="Album"> - </div> - <div class="fields" id="form-d"> - <form method="post" id="form"> - <?php +<head> + <meta charset="UTF-8"> + <title>Edit Music</title> + <script src="/presentation/music/edit/js/editMusic.js" defer></script> + <link rel="stylesheet" type="text/css" href="/presentation/music/edit/css/editMusic.css"> + <link rel="stylesheet" type="text/css" href="/presentation/template/css/sidebar.css"> + <link rel="stylesheet" type="text/css" href="/presentation/template/css/navbar.css"> + <link rel="preconnect" href="https://fonts.googleapis.com%22%3E/"> + <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin> + <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet"> +</head> +<body> +<div class="wrapper"> + <?php require 'presentation/template/sidebar.php' ?> + <div class="main-wrapper"> + <?php require 'presentation/template/navbar.php' ?> + <p id="title">Edit Music</p> + <div class="img-container"> + <img src="<?php if ($exists) echo getAlbumImage(); else echo '/presentation/music/edit/img/defalbum.jpg' ?>" alt="Album"> + </div> + <div class="fields" id="form-d"> + <form method="post" id="form"> + <?php - echo "<input type=\"text\" class=\"input\" id=\"input-title\" name=\"title\" placeholder=\"Title\" value=\"$title\">"; - echo "<input type=\"text\" class=\"input\" id=\"input-artist\" name=\"artist\" placeholder=\"Artist\" value=\"$artist\">"; - echo "<input type=\"text\" class=\"input\" id=\"input-album\" name=\"album\" placeholder=\"Album\" value=\"$album\">"; - echo "<input type=\"text\" class=\"input\" id=\"input-genre\" name=\"genre\" placeholder=\"Genre\" value=\"$genre\">"; - echo "<input type=\"text\" class=\"input\" id=\"input-year\" name=\"year\" placeholder=\"Year\" value=\"$year\">"; - echo "<input type=\"hidden\" id=\"input-id\" name=\"id\" value=\"$id\">"; - ?> - <div id="submit-d"> - <input type="submit" id="submit-b" value="Save"> - </div> - <div class="aux-d" id="cancel-d"> - <a href="#" id="cancel-b">Cancel</a> - </div> - <div class="aux-d" id="delete-d"> - <a href="<?php echo "javascript:deleteMusic('test', $id)" ?>" id="delete-b">Delete</a> - </div> - </form> + echo "<input type=\"text\" class=\"input\" id=\"input-title\" name=\"title\" placeholder=\"Title\" value=\"$title\">"; + echo "<input type=\"text\" class=\"input\" id=\"input-artist\" name=\"artist\" placeholder=\"Artist\" value=\"$artist\">"; + echo "<input type=\"text\" class=\"input\" id=\"input-album\" name=\"album\" placeholder=\"Album\" value=\"$album\">"; + echo "<input type=\"text\" class=\"input\" id=\"input-genre\" name=\"genre\" placeholder=\"Genre\" value=\"$genre\">"; + echo "<input type=\"text\" class=\"input\" id=\"input-year\" name=\"year\" placeholder=\"Year\" value=\"$year\">"; + echo "<input type=\"hidden\" id=\"input-id\" name=\"id\" value=\"$id\">"; + ?> + <div id="submit-d"> + <input type="submit" id="submit-b" value="Save"> + </div> + <div class="aux-d" id="cancel-d"> + <a href="javascript:history.back()" id="cancel-b">Cancel</a> + </div> + <div class="aux-d" id="delete-d"> + <a href="<?php echo "javascript:deleteMusic('test', $id)" ?>" id="delete-b">Delete</a> + </div> + </form> + </div> </div> +</div> </body> </html> diff --git a/src/web/presentation/music/info/albumInfo.view.php b/src/web/presentation/music/info/albumInfo.view.php index 48bc322ef2706693b4e144e77675ee8d7046c7dc..526929d8f4fffd40eca06e87dde97a04aae29c6c 100644 --- a/src/web/presentation/music/info/albumInfo.view.php +++ b/src/web/presentation/music/info/albumInfo.view.php @@ -21,42 +21,85 @@ function populateFields($id): void { $year = $result[0]['year']; } +$id = $_GET['id'] ?? null; +if (is_numeric($id)) { + populateFields($id); +} + ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> - <title>Artist - Album Title</title> + <title><?php echo $artist . ' - ' . $name ?></title> + <script src="/presentation/music/info/js/albumInfo.js" defer></script> <link rel="stylesheet" href="/presentation/music/info/css/albumInfo.css"> + <link rel="stylesheet" type="text/css" href="/presentation/template/css/sidebar.css"> + <link rel="stylesheet" type="text/css" href="/presentation/template/css/navbar.css"> <link rel="preconnect" href="https://fonts.googleapis.com%22%3E/"> <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet"> </head> <body> -<script src="/presentation/music/info/js/albumInfo.js" defer></script> -<audio id="hidden-audio" src=""></audio> -<div class="img-container"> - <img src="<?php echo getAlbumImage() ?>" alt="Album"> -</div> - <div id="album-info"> - <?php - $id = $_GET['id'] ?? null; - if (is_numeric($id)) { - populateFields($id); - } - ?> - <p id="artist-title"><?php echo $artist.' - '.$name ?></p> - <div class="more-info"> - <p id="year"><?php echo $year ?></p> +<div class="wrapper"> + <?php require 'presentation/template/sidebar.php' ?> + <div class="main-wrapper"> + <?php require 'presentation/template/navbar.php' ?> + <div class="img-container"> + <img src="<?php echo getAlbumImage() ?>" alt="Album"> + </div> + <?php if (authorizeAdmin($_COOKIE['token']) != null) {?> + <div id="edit-b"> + <button id="edit-button">Edit</button> + </div> + <style> + .img-container { + margin-bottom: 10px !important; + } + + #edit-b { + display: flex; + justify-content: center; + } + + #edit-button { + width: 100px; + height: 30px; + border: none; + border-radius: 5px; + background-color: #da0f47; + color: white; + font-size: 15px; + font-weight: 500; + cursor: pointer; + } + </style> + <script> + document.getElementById("edit-button").addEventListener("click", () => { + window.location.href = "/album/edit?id=<?php echo $id ?>"; + }); + </script> + <?php } ?> + <div id="album-info"> + <p id="artist-title"><?php echo $artist.' - '.$name ?></p> + <div class="more-info"> + <p id="year"><?php echo $year ?></p> + </div> + </div> + <div id="music-list-d"> + <ol id="music-list"> + <?php + populateList($id); + ?> + </ol> + </div> + <div id="audio-d"> + <audio id="audio" controls hidden="hidden"> + <source src="" type="audio/mp3"> + </audio> </div> </div> - <div id="music-list-d"> - <ol id="music-list"> - <?php - populateList($id); - ?> - </ol> - </div> +</div> </body> </html> \ No newline at end of file diff --git a/src/web/presentation/music/info/css/albumInfo.css b/src/web/presentation/music/info/css/albumInfo.css index 67c4c5eb6e1071efc68c461cd53b6e8df27ec2e4..c6e24ac75ff37a2f9f3c7123d528f58e33bc4c2f 100644 --- a/src/web/presentation/music/info/css/albumInfo.css +++ b/src/web/presentation/music/info/css/albumInfo.css @@ -1,8 +1,29 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: Roboto, serif; + z-index: 1; +} + html { + height: 100%; + width: 100%; font-family: Roboto, serif; } +body { + height: 100%; + width: 100%; +} + +.main-wrapper { + padding: 0; + margin-left: 250px; +} + .img-container { + padding-top: 10vh; width: 100%; text-align: center; margin-bottom: 36px; @@ -19,13 +40,12 @@ html { } #album-info { - margin: auto; text-align: center; } #artist-title { font-size: 36px; - margin-bottom: 0; + margin-bottom: 8px; } #music-list-d { @@ -33,9 +53,13 @@ html { width: 100%; } +#year { + margin-bottom: 16px; +} + #music-list { margin: auto; - width: 640px; + width: 80vh; padding-left: 0; } @@ -81,4 +105,15 @@ html { flex-direction: row; justify-content: space-between; margin-right: 8px; +} + +#audio-d { + position: fixed; + bottom: 0; + margin-top: 16px; + width: calc(100% - 250px); +} + +#audio { + width: 100% } \ No newline at end of file diff --git a/src/web/presentation/music/info/css/musicInfo.css b/src/web/presentation/music/info/css/musicInfo.css index 58bf1621913309039a79b5be93fc18aaf3e93333..c824832d355aad55a598f2a28e7368b8df2afa15 100644 --- a/src/web/presentation/music/info/css/musicInfo.css +++ b/src/web/presentation/music/info/css/musicInfo.css @@ -1,8 +1,29 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: Roboto, serif; + z-index: 1; +} + html { + height: 100%; + width: 100%; font-family: Roboto, serif; } +body { + height: 100%; + width: 100%; +} + +.main-wrapper { + padding: 0; + margin-left: 250px; +} + .img-container { + padding-top: 10vh; width: 100%; text-align: center; margin-bottom: 36px; @@ -19,26 +40,22 @@ html { } #music-info { - margin: auto; text-align: center; } #artist-title { font-size: 36px; - margin-bottom: 0; } #album { color: #da0f47 !important; font-size: 16px; - margin-top: 0; text-decoration: none; } #album:hover { color: #da0f47 !important; font-size: 16px; - margin-top: 0; text-decoration: underline; } @@ -70,7 +87,7 @@ html { #play-b { text-align: center; - width: 15%; + width: 256px; height: 40px; background-color: #da0f47; border: none; diff --git a/src/web/presentation/music/info/js/albumInfo.js b/src/web/presentation/music/info/js/albumInfo.js index 05cd95a9777ff1a09c202b8d240fcccf71e0fe9c..9e603a24c3c837c0f28a3c9646b541276462b267 100644 --- a/src/web/presentation/music/info/js/albumInfo.js +++ b/src/web/presentation/music/info/js/albumInfo.js @@ -1,4 +1,6 @@ const list = document.querySelector('#music-list').getElementsByTagName('li'); +// const audioPlayer = document.createElement('audio'); +const audioPlayer = document.querySelector('#audio'); for (let item of list) { item.addEventListener('click', (e) => { @@ -18,8 +20,8 @@ for (let item of list) { xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { let audio = JSON.parse(xhr.responseText); - let audioPlayer = document.querySelector('#hidden-audio'); audioPlayer.src = audio.data; + audioPlayer.hidden = false; audioPlayer.play(); } } diff --git a/src/web/presentation/music/info/musicInfo.view.php b/src/web/presentation/music/info/musicInfo.view.php index b497d86c3f1e996cd8f6f69f69e0bde2c66df5d8..917c20b419ef2be9199d25c3ef4658d2c268d6b9 100644 --- a/src/web/presentation/music/info/musicInfo.view.php +++ b/src/web/presentation/music/info/musicInfo.view.php @@ -21,8 +21,13 @@ function populateFields($id): void { $title = $result[0]['title']; $artist = getAccountName($result[0]['owner_account_id']); $album = getAlbumName($result[0]['album_id']); - $genre = $result[0]['genre']; - $year = $result[0]['year']; + $genre = $result[0]['genre'] ?? 'Unknown'; + $year = $result[0]['year'] ?? 'Unknown'; +} + +$id = $_GET['id'] ?? null; +if (is_numeric($id)) { + populateFields($id); } ?> @@ -31,39 +36,41 @@ function populateFields($id): void { <html lang="en"> <head> <meta charset="UTF-8"> - <title>Artist - Title</title> + <title><?php echo $artist . ' - ' . $title ?></title> <link rel="stylesheet" href="/presentation/music/info/css/musicInfo.css"> + <link rel="stylesheet" type="text/css" href="/presentation/template/css/sidebar.css"> + <link rel="stylesheet" type="text/css" href="/presentation/template/css/navbar.css"> <link rel="preconnect" href="https://fonts.googleapis.com%22%3E/"> <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet"> </head> <body> -<div class="img-container"> - <img src="<?php echo getAlbumImage() ?>" alt="Album"> -</div> -<div id="music-info"> - <?php - $id = $_GET['id'] ?? null; - if (is_numeric($id)) { - populateFields($id); - } - ?> - <p id="artist-title"><?php echo $artist.' - '.$title ?></p> - <a href="#" id="album"><?php echo $album ?></a> - <div id="more-info-container"> - <div class="more-info"> - <p id="genre"><?php echo $genre ?></p> - </div> - <div class="more-info" id="dot-d"> - <p id="dot">•</p> +<div class="wrapper"> + <?php require 'presentation/template/sidebar.php' ?> + <div class="main-wrapper"> + <?php require 'presentation/template/navbar.php' ?> + <div class="img-container"> + <img src="<?php echo getAlbumImage() ?>" alt="Album"> </div> - <div class="more-info"> - <p id="year"><?php echo $year ?></p> + <div id="music-info"> + <p id="artist-title"><?php echo $artist.' - '.$title ?></p> + <a href="#" id="album"><?php echo $album ?></a> + <div id="more-info-container"> + <div class="more-info"> + <p id="genre"><?php echo $genre ?></p> + </div> + <div class="more-info" id="dot-d"> + <p id="dot">•</p> + </div> + <div class="more-info"> + <p id="year"><?php echo $year ?></p> + </div> + </div> + <div id="play-d"> + <button id="play-b">Play</button> + </div> </div> </div> - <div id="play-d"> - <button id="play-b">Play</button> - </div> </div> </body> </html> \ No newline at end of file diff --git a/src/web/presentation/music/list/albumList.php b/src/web/presentation/music/list/albumList.php index d6c5f1ddde4b88a6cba27b87b70677eba3c0d010..aa1b1e8956530880ec318fbc5ad3e1a59889ed80 100644 --- a/src/web/presentation/music/list/albumList.php +++ b/src/web/presentation/music/list/albumList.php @@ -2,6 +2,7 @@ require_once 'db/db-executor.php'; require_once 'auth/authenticator.php'; +require_once 'util/album-finder.php'; $errMsg = ''; diff --git a/src/web/presentation/music/list/css/albumList.css b/src/web/presentation/music/list/css/albumList.css index e245f4b1bcdd7c1a76aaece41e59e652839fe273..b7cb5908f9db4dbb15049d3d6bf8cfa19eff887c 100644 --- a/src/web/presentation/music/list/css/albumList.css +++ b/src/web/presentation/music/list/css/albumList.css @@ -43,6 +43,7 @@ justify-content: space-evenly; background-color: rgb(206, 206, 206); border-radius: 5px; + cursor: pointer; } .album img { diff --git a/src/web/presentation/music/list/js/albumList.js b/src/web/presentation/music/list/js/albumList.js index 505d772c4b684369a897c725ecd35207e5b55355..44ed477d7bf6caeb70e5e50f1757600faf74cfa9 100644 --- a/src/web/presentation/music/list/js/albumList.js +++ b/src/web/presentation/music/list/js/albumList.js @@ -10,16 +10,11 @@ const pageText = document.querySelector("#pagination-text"); const songsResult = document.querySelector(".album-wrapper"); const pagination = document.querySelector(".pagination"); -// Sorting +const albums = document.querySelectorAll(".album"); + const sortInput = document.querySelector(".sort-select"); -console.log(sortInput.value); const orderInput = document.querySelector(".order-select"); -console.log(orderInput.value); const creatorInput = document.querySelector(".creator-select"); -console.log(creatorInput.value); - -let currentPage = 1; -let limit = 6; const debounce = (func, delay) => { let timer; @@ -31,6 +26,10 @@ const debounce = (func, delay) => { }; }; +let currentPage = 1; +let limit = 6; + + prevButton && prevButton.addEventListener("click", async () => { @@ -184,7 +183,6 @@ const newData = (data) => { } }; -const albums = document.querySelectorAll(".album"); albums.forEach((album) => { album.addEventListener("click", async (e) => { e.preventDefault(); diff --git a/src/web/presentation/template/sidebar.php b/src/web/presentation/template/sidebar.php index 2fa6593410d91e14e94b20f5c6bc3a71344b65cc..02fa81cedff067122cf772e3a4acdeaabc9f061b 100644 --- a/src/web/presentation/template/sidebar.php +++ b/src/web/presentation/template/sidebar.php @@ -5,7 +5,7 @@ require_once 'auth/authenticator.php'; require_once 'auth/authorizer.php'; $accountId = authenticateToken($_COOKIE['token']) ; -$isAdmin = (authorizeAdmin($_COOKIE['token']) != null ? true : false); +$isAdmin = authorizeAdmin($_COOKIE['token']) != null; if ($_SERVER["REQUEST_METHOD"] == "GET") { $username = execSelect('SELECT username FROM account WHERE account_id = :accountId', ['accountId' => $accountId])[0]['username']; diff --git a/src/web/util/album-finder.php b/src/web/util/album-finder.php index be1bde048c3a1c60875768bcd99f103606b2cd3e..422d8ae8f291f6a9b950a9e701d8b0fedb737084 100644 --- a/src/web/util/album-finder.php +++ b/src/web/util/album-finder.php @@ -6,7 +6,6 @@ function getAlbumName(mixed $album_id) { } function getAlbumImage(): string { - $accountId = 1; $image = '/presentation/music/edit/img/defalbum.jpg'; if (!isset($_GET['id'])) { @@ -14,7 +13,42 @@ function getAlbumImage(): string { } // get album cover filename from db - $q_result = execSelect("SELECT album_cover_filename FROM album WHERE album_id = :id", ['id' => $_GET['id']]); + $q_result = execSelect("SELECT owner_account_id, album_cover_filename FROM album WHERE album_id = :id", ['id' => $_GET['id']]); + $accountId = $q_result[0]['owner_account_id']; + + if (count($q_result) != 0) { + $filename = $q_result[0]['album_cover_filename']; + + // prepare curl request + $url = 'object-storage:80/object'; + + $data = http_build_query(array( + 'owner' => $accountId, // account id, + 'fileType' => 'album-cover', + 'fileName' => $filename + )); + $getUrl = $url.'?'.$data; + + $curl = curl_init($getUrl); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + $result = curl_exec($curl); + + if (!curl_errno($curl) && curl_getinfo($curl, CURLINFO_HTTP_CODE) == 200) { + $contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE); + $image = 'data:'.$contentType.';base64,'.base64_encode($result); + } + curl_close($curl); + } + + return $image; +} + +function getAlbumImageByID($id): string { + $image = '/presentation/music/edit/img/defalbum.jpg'; + + // get album cover filename from db + $q_result = execSelect("SELECT owner_account_id, album_cover_filename FROM album WHERE album_id = :id", ['id' => $id]); + $accountId = $q_result[0]['owner_account_id']; if (count($q_result) != 0) { $filename = $q_result[0]['album_cover_filename'];