Add new views and styles for music application

- Created new CSS files for styling the application, including home.css and style.css.
- Implemented 403 and 404 error views with appropriate messages and navigation.
- Developed a dump view to display deleted elements with restoration options.
- Enhanced home view to include music search functionality and display results.
- Added listplay view for managing music playlists, including creation and deletion options.
- Implemented loadmusic view for uploading new music with necessary fields.
- Created login and register views for user authentication.
- Developed sound view to display individual music tracks with playback controls and options for liking and deleting.
- Updated menu view to include navigation links based on user authentication status.
This commit is contained in:
2026-01-05 17:20:17 -04:00
parent 24f62ca4c2
commit a8624fc847
33 changed files with 1370 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
<?php
class Connection{
protected $lastID;
function __construct(){
$this->param = include 'param.php';
}
private function getConnection(){
$param = include 'param.php';
return mysqli_connect($param['host'], $param['username'], $param['password'], $param['dbname']);
}
protected function tableExists(string $table){
$tables = $this->getData("SHOW TABLES");
foreach($tables as $tableName){
if(strtolower($tableName[0]) == strtolower($table)){
return true;
}
}
return false;
}
protected function execNoQuery($sql){
$link = $this->getConnection();
if(mysqli_query($link, $sql)){
$this->lastID = mysqli_insert_id($link);
mysqli_close($link);
}else{
echo mysqli_error($link) . '<br><br>';
}
}
private function execQuery($sql){
$link = $this->getConnection();
$query = mysqli_query($link, $sql);
if(mysqli_close($link)){
return $query;
}else{
return null;
}
}
protected function getValue($tableName, $nameParam1, $nameParam2, $valueSearh){
$sql = "SELECT $nameParam1 FROM $tableName WHERE $nameParam2='$valueSearh'";
$result = $this->execQuery($sql);
return mysqli_fetch_array($result)[$nameParam1];
}
protected function getData($sql, $idColumn=null){
$result = $this->execQuery($sql);
$data = [];
$cont = 0;
while($row = mysqli_fetch_array($result)){
if($idColumn == null){
$data[$cont] = $row;
$cont++;
}else{
$data[$row[$idColumn]] = $row;
}
}
return $data;
}
}

View File

@@ -0,0 +1,9 @@
<?php
return [
"dbname" => "musicdb",
"username" => "root",
"password" => "",
"host" => "localhost"
];

View File

@@ -0,0 +1,120 @@
<?php
class Html
{
private $title;
private $icon;
private $html;
private $head;
private $body;
private $style;
private $script;
private $meta;
private $content;
public function __construct()
{
$this->title = [];
$this->icon = [];
$this->html = [];
$this->head = [];
$this->body = [];
$this->style = [];
$this->script = [];
$this->meta = [];
$this->content = '';
// Cargando meta
$this->loadMeta(['http-equiv' => 'Content-Type', 'content' => 'text/html;charset=UTF-8']);
$this->loadMeta(['name' => 'viewport', 'content' => 'width=device-width, initial-scale=1, shrink-to-fit=no']);
$this->loadMeta(['name' => 'description', 'content' => 'Escucha tu musica favorita donde y cuando quieras.']);
$this->loadMeta(['name' => 'author', 'content' => 'Creado por RMB']);
}
public function setTitle(string $title)
{
$this->title = [
'start' => '<title>',
'text' => $title,
'end' => '</title>'
];
}
public function setIconPage(string $url)
{
$this->icon = [
'start' => '<link',
0 => ' ',
1 => "rel='",
'rel' => 'icon',
2 => "' ",
3 => "href='",
'href' => $url,
4 => "' ",
5 => "type='",
'type' => 'image/png',
'end' => "'>"
];
}
public function loadMeta(array $meta)
{
$acum = '<meta ';
foreach ($meta as $index => $value) {
$acum .= "$index='$value' ";
}
$acum = trim($acum) . '>';
array_push($this->meta, $acum);
}
public function loadScripts(array $urls)
{
foreach ($urls as $url) {
array_push($this->script, "<script src='$url'></script>");
}
}
public function loadStyles(array $urls)
{
foreach ($urls as $url) {
array_push($this->style, "<link rel='stylesheet' href='$url' type='text/css'>");
}
}
public function loadHTML(string $html)
{
$this->content = $html;
}
public function output()
{
$this->head = [
'meta' => implode($this->meta),
'title' => implode($this->title),
'icon' => implode($this->icon),
'style' => implode($this->style)
];
$this->body = [
'content' => $this->content,
'script' => implode($this->script)
];
$this->html = [
'head' => implode($this->head),
'body' => implode($this->body)
];
echo implode($this->html);
}
public function getTitle()
{
return isset($this->title['text']) ? $this->title['text'] : '';
}
public function getIconPage(string $atribute = 'href')
{
return isset($this->icon[$atribute]) ? $this->icon[$atribute] : '';
}
}

View File

@@ -0,0 +1,36 @@
<?php
class ListMusic extends Connection{
private $table = 'listmusic';
public function __construct()
{
if(!parent::tableExists($this->table)){
parent::execNoQuery("CREATE TABLE $this->table(
idListMusic INTEGER(10) PRIMARY KEY AUTO_INCREMENT,
idMusic INTEGER(10) NOT NULL,
idList INTEGER(10) NOT NULL,
dateListMusic TIMESTAMP DEFAULT NOW(),
deleteListMusic BOOLEAN DEFAULT FALSE
)");
}
}
protected function newMusicToList(array $data){
parent::execNoQuery("INSERT INTO $this->table(idMusic,idList) VALUES({$data['idMusic']}, {$data['idList']})");
}
protected function existsMusicInList(int $idMusic, int $idList){
$result = parent::getData("SELECT * FROM $this->table WHERE idMusic=$idMusic AND idList=$idList");
return !empty($result);
}
protected function getList(int $idList){
$Music = new Music();
$musics = parent::getData("SELECT * FROM $this->table WHERE idList=$idList AND NOT deleteListMusic");
foreach($musics as $index => $music){
$musics[$index]['music'] = $Music->getMusic($music['idMusic']);
}
return $musics;
}
}

View File

@@ -0,0 +1,51 @@
<?php
class ListPlayer extends ListMusic{
private $table = 'listplayer';
public function __construct()
{
if(!parent::tableExists($this->table)){
parent::execNoQuery("CREATE TABLE $this->table(
idList INTEGER(10) PRIMARY KEY AUTO_INCREMENT,
listName VARCHAR(200) NOT NULL,
dateList TIMESTAMP DEFAULT NOW(),
dateListDelete TIMESTAMP DEFAULT NOW(),
idUser INTEGER(10) NOT NULL,
deleteList BOOLEAN DEFAULT FALSE
)");
}
}
public function newList(string $namelist){
parent::execNoQuery("INSERT INTO $this->table(listname,idUser) VALUES('$namelist', " . Session::getUserID() .")");
}
public function getListMusic(string $listMusic){
$lists = parent::getData("SELECT * FROM $this->table WHERE NOT deleteList AND MD5(idList)='$listMusic'");
if(!empty($lists)){
$lists[0]['musics'] = parent::getList($lists[0]['idList'], new Music());
}
return !empty($lists) ? $lists[0] : [];
}
public function addMusicToList(int $idList, int $idMusic){
if(!parent::existsMusicInList($idMusic, $idList)){
parent::newMusicToList(['idList' => $idList, 'idMusic' => $idMusic]);
}
}
public function deleteList(int $idList){
parent::execNoQuery("UPDATE $this->table SET deleteList=NOT deleteList, dateListDelete=NOW() WHERE idList=$idList AND idUser=" . Session::getUserID());
}
public function getDelete(){
return parent::getData("SELECT idList as id, listName as name, dateListDelete AS date, '$this->table' as 'origin' FROM $this->table WHERE deleteList AND idUser=" . Session::getUserID());
}
public function getListName(){
return parent::getData("SELECT * FROM $this->table WHERE NOT deleteList AND idUser=" . Session::getUserID());
}
}

View File

@@ -0,0 +1,113 @@
<?php
class Music extends Connection{
private $table = 'music';
private $tableLike = 'likeMusic';
private $tableGenner = 'genner';
private $user;
public function __construct()
{
if(!parent::tableExists($this->table)){
parent::execNoQuery("CREATE TABLE $this->table(
idMusic INTEGER(10) PRIMARY KEY AUTO_INCREMENT,
nameMusic VARCHAR(200) NOT NULL,
formatMusic VARCHAR(50) NOT NULL,
fileNameMusic VARCHAR(50) NOT NULL,
fileSizeMusic INTEGER(10) NOT NULL,
descriptionMusic VARCHAR(500),
authorMusic VARCHAR(200),
idGenner INTEGER(10) NOT NULL,
idUser INTEGER(10) NOT NULL,
dateMusic TIMESTAMP DEFAULT NOW(),
dateMusicDelete TIMESTAMP DEFAULT NOW(),
deleteMusic BOOLEAN DEFAULT FALSE
)");
}
if(!parent::tableExists($this->tableLike)){
parent::execNoQuery("CREATE TABLE $this->tableLike(
idLike INTEGER(10) PRIMARY KEY AUTO_INCREMENT,
idMusic INTEGER(10) NOT NULL,
idUser INTEGER(10) NOT NULL,
deleteLike BOOLEAN DEFAULT FALSE
)");
}
if(!parent::tableExists($this->tableGenner)){
parent::execNoQuery("CREATE TABLE $this->tableGenner(
idGenner INTEGER(10) PRIMARY KEY AUTO_INCREMENT,
gennerName VARCHAR(100) NOT NULL,
dateGenner TIMESTAMP DEFAULT NOW(),
deleteGenner BOOLEAN DEFAULT FALSE
)");
}
$this->user = new User();
}
private function __getMusic(array $musics){
foreach($musics as $index => $music){
$musics[$index]['user'] = $this->user->getUser($music['idUser']);
$musics[$index]['genner'] = parent::getData("SELECT * FROM $this->tableGenner WHERE idGenner={$music['idGenner']}")[0];
$musics[$index]['like'] = count(parent::getData("SELECT * FROM $this->tableLike WHERE idMusic={$music['idMusic']} AND idUser=" . Session::getUserID() . " AND NOT deleteLike")) == 1;
$musics[$index]['likes'] = count(parent::getData("SELECT * FROM $this->tableLike WHERE idMusic={$music['idMusic']} AND NOT deleteLike"));
}
return $musics;
}
public function getMusics(string $search=null){
$musics = parent::getData(
"SELECT * FROM $this->table WHERE NOT deleteMusic"
. (($search != null) ? " AND descriptionMusic LIKE '%$search%' OR nameMusic LIKE '%$search%' OR authorMusic LIKE '%$search%'" : ' LIMIT 10')
);
return $this->__getMusic($musics);
}
public function getMusic(int $idMusic){
return $this->__getMusic(parent::getData("SELECT * FROM $this->table WHERE idMusic=$idMusic AND NOT deleteMusic"))[0];
}
public function newMusic(array $music){
parent::execNoQuery("INSERT INTO $this->table(
nameMusic, formatMusic, fileNameMusic,
fileSizeMusic, descriptionMusic, authorMusic,
idGenner, idUser
) VALUES(
'{$music['nameMusic']}', '{$music['formatMusic']}', '{$music['fileNameMusic']}',
'{$music['fileSizeMusic']}', '{$music['descriptionMusic']}', '{$music['authorMusic']}',
{$music['idGenner']}, {$music['idUser']}
)");
}
public function getDelete(){
return parent::getData("SELECT idMusic as id, CONCAT(nameMusic, ' - ', authorMusic) as name, dateMusicDelete as date, '$this->table' as 'origin' FROM $this->table WHERE deleteMusic AND idUser=" . Session::getUserID());
}
public function deleteMusic(int $music){
parent::execNoQuery("UPDATE $this->table SET deleteMusic=NOT deleteMusic, dateMusicDelete=NOW() WHERE idMusic=$music");
}
public function like(array $like){
$data = parent::getData("SELECT * FROM $this->tableLike WHERE idMusic={$like['idMusic']} AND idUser={$like['idUser']}");
if(count($data) > 0){
parent::execNoQuery("UPDATE $this->tableLike SET deleteLike=(NOT deleteLike) WHERE idLike={$data[0]['idLike']}");
}else{
parent::execNoQuery("INSERT INTO $this->tableLike(idMusic, idUser) VALUES({$like['idMusic']}, " . Session::getUserID() . ")");
}
}
public function newGennerMusic(string $name){
parent::execNoQuery("INSERT INTO $this->tableGenner(gennerName) VALUES('$name')");
}
public function updateGenner(int $idGenner, string $name){
parent::execNoQuery("UPDATE $this->tableGenner SET gennerName='$name' WHERE idGenner=$idGenner");
}
public function getGennersMusical(){
return parent::getData("SELECT * FROM $this->tableGenner WHERE NOT deleteGenner order by gennerName", "idGenner");
}
}

View File

@@ -0,0 +1,26 @@
<?php
session_start();
class Session{
public static function Auth(){
return isset($_SESSION['LOGIN'])?$_SESSION['LOGIN']:false;
}
public static function Admin(){
return isset($_SESSION['privileges'])?$_SESSION['privileges']:false;
}
public static function getUsername(){
return isset($_SESSION['username'])?$_SESSION['username']:null;
}
public static function getUserID(){
return isset($_SESSION['idUser'])?$_SESSION['idUser']:0;
}
public static function logout(){
unset($_SESSION);
session_destroy();
}
}

View File

@@ -0,0 +1,47 @@
<?php
class User extends Connection{
private $table = 'user';
public function __construct()
{
if(!parent::tableExists($this->table)){
parent::execNoQuery("CREATE TABLE $this->table(
idUser INTEGER(10) PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL, userpassword VARCHAR(50) NOT NULL,
privileges BOOLEAN DEFAULT FALSE, date TIMESTAMP DEFAULT NOW(),
deleteUser BOOLEAN DEFAULT FALSE
)");
}
}
public function isAccess(array $login){
$data = parent::getData("SELECT * FROM $this->table
WHERE username='{$login['username']}'
AND userpassword=MD5('{$login['password']}')
AND NOT deleteUser"
);
if(count($data) == 1){
$_SESSION = $data[0];
$_SESSION['LOGIN'] = true;
}
return count($data) == 1;
}
public function newUser(array $register){
parent::execNoQuery("INSERT INTO $this->table(username,userpassword) VALUE('{$register['username']}', MD5('{$register['password']}'))");
}
public function exists(string $username){
return count(parent::getData("SELECT * FROM $this->table WHERE username='$username'")) > 0;
}
public function getUsers(){
return parent::getData("SELECT * FROM $this->table WHERE NOT deleteUser");
}
public function getUser(int $idUser){
return parent::getData("SELECT * FROM $this->table WHERE NOT deleteUser AND idUser = $idUser")[0];
}
}

123
etc/SearchFilePath.php Normal file
View File

@@ -0,0 +1,123 @@
<?php
class SearchFilePath
{
private static $file = [];
private static $absolutePath = [];
private static function __getFiles(string $dirname, array $exception = [])
{
if (empty(self::$absolutePath)) {
self::$absolutePath = explode('/', $dirname);
} else {
array_push(self::$absolutePath, $dirname);
}
$dirname = join('/', self::$absolutePath);
if (is_dir($dirname)) {
$dir = opendir($dirname);
while ($data = readdir($dir)) {
$req = false;
foreach ($exception as $ex) {
$req = in_array(strtolower($ex), explode('/', strtolower($dirname)));
if ($req) {
break;
}
}
if (!in_array($data, ['.', '..']) && !$req) {
if (is_file("$dirname/$data")) {
if (!empty(explode('.', $data)[0])) {
array_push(self::$file, "$dirname/$data");
}
} elseif (is_dir("$dirname/$data")) {
self::__getFiles($data, $exception);
array_pop(self::$absolutePath);
array_push(self::$file, "$dirname/$data");
}
}
}
}
}
private static function limitPath(string $path, string $newPath)
{
$path = explode('/', $path);
$newPath = explode('/', $newPath);
krsort($newPath);
for ($i = 0; $i < count($path); $i++) {
array_pop($newPath);
}
ksort($newPath);
array_pop($newPath);
return $newPath;
}
public static function getFiles(string $pathdir = '.', array $exceptionDirName = [])
{
self::$file = [];
self::$absolutePath = [];
self::__getFiles($pathdir, $exceptionDirName);
$path = [];
foreach (self::$file as $value) {
$limitPath = self::limitPath($pathdir, $value);
if (is_file($value)) {
$fileName = explode('/', $value);
$fileName = strtolower($fileName[count($fileName) - 1]);
$fileName = explode('.', $fileName)[0];
$acum = '';
$param = '';
$pathDir = '.';
foreach ($limitPath as $limit) {
$param .= '["' . strtoupper($limit) . '"]';
$pathDir .= '/' . strtolower($limit);
$acum = '
if(!isset($path' . $param . ')){
$path' . $param . '["FILE_DIR"] = [];
$path' . $param . '["PATH_DIR"] = "' . $pathDir . '";
}
';
eval($acum);
}
eval('
if(!isset($path' . $param . '["' . $fileName . '"])){
$path' . $param . '["FILE_DIR"]["' . $fileName . '"] = "' . $value . '";
}
array_push($path' . $param . '["FILE_DIR"], "' . $value . '");
for($i=0; $i<count($path' . $param . '["FILE_DIR"]); $i++){
if(isset($path' . $param . '["FILE_DIR"][$i])){
unset($path' . $param . '["FILE_DIR"][$i]);
}
}
');
}
}
return $path;
}
public static function getFilesFilter(string $filter = '.', string $pathDir = '.', array $exceptionFileName = [])
{
foreach ($exceptionFileName as $index => $filename) {
$exceptionFileName[$index] = strtolower($filename);
}
self::$file = [];
self::$absolutePath = [];
self::__getFiles($pathDir, []);
$files = [];
foreach (self::$file as $file) {
if (is_file($file)) {
$acum = explode('/', $file);
$fileName = $acum[count($acum) - 1];
if (strpos(strtolower(' ' . $fileName), strtolower($filter)) > 0) {
if (!in_array(strtolower($fileName), $exceptionFileName)) {
array_push($files, "./$file");
}
}
}
}
return $files;
}
}

12
etc/functions.php Normal file
View File

@@ -0,0 +1,12 @@
<?php
function getElementsDelete(array $elements){
$data = [];
foreach($elements as $element){
foreach($element as $value){
array_push($data, $value);
}
}
krsort($data);
return $data;
}

View File

@@ -0,0 +1,16 @@
<?php
if (Session::Auth()) {
if (isset($_POST['delete']) && isset($_POST['origin'])) {
switch ($_POST['origin']) {
case 'listplayer':
$listplayer->deleteList($_POST['delete']);
break;
case 'music':
$music->deleteMusic($_POST['delete']);
break;
}
}
}
header("location: ./?view=$view");

View File

@@ -0,0 +1,17 @@
<?php
if(Session::Auth()){
if(isset($_POST['idMusic'])){
$music->like(
[
'idUser' => Session::getUserID(),
'idMusic' => $_POST['idMusic']
]
);
}elseif(isset($_POST['delete'])){
$music->deleteMusic($_POST['delete']);
header("location: ./?view=$view");
}
}
?>

View File

@@ -0,0 +1,14 @@
<?php
if(Session::Auth()){
if(isset($_POST['txtListName'])){
$listplayer->newList($_POST['txtListName']);
}elseif(isset($_POST['deleteList'])){
$listplayer->deleteList($_POST['deleteList']);
}elseif(isset($_POST['idMusic']) && isset($_POST['idList'])){
$listplayer->addMusicToList($_POST['idList'], $_POST['idMusic']);
$view = "$view&listmusic=" . md5($_POST['idList']);
}
}
header("location: ./?view=$view");
?>

View File

@@ -0,0 +1,28 @@
<?php
$sound = [];
$ext = explode('.', $_FILES['fileMusic']['name']);
$ext = $ext[count($ext)-1];
$sound['nameMusic'] = $_POST['txtTitle'];
$sound['formatMusic'] = $_FILES['fileMusic']['type'];
$sound['fileNameMusic']= md5($_POST['txtTitle'] . time());
$sound['fileSizeMusic'] = $_FILES['fileMusic']['size'];
$sound['descriptionMusic'] = $_POST['txtDescription'];
$sound['authorMusic'] = $_POST['txtAuthor'];
$sound['idGenner'] = $_POST['genner'];
$sound['idUser'] = Session::getUserID();
$message = 'Archivo cargado con exito.';
$color = 'success';
if(in_array(strtoupper($ext), ['WAV', 'AIFF','AU','FLAC','MPEG-4','SHORTEN','TTA','ATRAC','APPLE', 'LOSSLESS','MP3','VORBIS','MUSEPACK','AAC','WMA','OPUS','OGG','DSD','MQA'])){
$music->newMusic($sound);
$fileName = "{$assets['SOUND']['PATH_DIR']}/{$sound['fileNameMusic']}.$ext";
move_uploaded_file($_FILES['fileMusic']['tmp_name'], $fileName);
}else{
$message = 'Formato no válido!';
$color = 'danger';
}
header("location: ./?view=$view&message=$message&action=$color");

View File

@@ -0,0 +1,11 @@
<?php
$redirect = "./?view=$view";
if (isset($_POST['username']) && isset($_POST['password'])) {
if ($user->isAccess($_POST)) {
$redirect = './';
}
}
header("location: $redirect");
?>

View File

@@ -0,0 +1,24 @@
<?php
$newUser = false;
if (isset($_POST['username']) && isset($_POST['password']) && isset($_POST['rpassword'])) {
if (!$user->exists($_POST['username'])) {
if (strpos('_' . $_POST['username'], ' ') <= 0) {
if ($_POST['password'] == $_POST['rpassword']) {
$user->newUser($_POST);
$message = 'Usuario creado con exito!';
$newUser = true;
} else {
$message = "Las claves no coinciden.";
}
} else {
$message = "El nombre de usuario <b>\"{$_POST['username']}\"</b> no debe tener espacios.";
}
} else {
$message = "El usuario <b>{$_POST['username']}</b> existe.";
}
}
header("location: ./?view=$view&newuser=$newUser&message=$message");
?>

2
script/1_jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

7
script/2_bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

99
script/home.js Normal file
View File

@@ -0,0 +1,99 @@
var onClick = {
home: {
event: null,
getMinut: (second_t) => {
let minute = 0;
let second = 0;
for(let i=0; i < second_t; i++){
second++;
if(second >= 60){
minute++;
second = 0;
}
}
return minute + ':' + second;
},
getPercent: (start, end) =>{
return Math.round(start / (end * 0.01));
},
pause: () => {
onClick.home.event.sound.className = 'fas fa-play';
$('#' + onClick.home.event.elementid)[0].pause();
},
play: (e, elementid) => {
if (onClick.home.event !== null) {
if (onClick.home.event.sound != null) {
if (onClick.home.event.sound !== e) {
onClick.home.pause();
onClick.home.event = {
sound: e,
elementid: elementid,
volume: '0.5'
};
}
}
}
if (onClick.home.event === null) {
onClick.home.event = {
sound: e,
elementid: elementid,
volume: '0.5'
};
} else if (onClick.home.event.sound === null) {
onClick.home.event.sound = e;
}
if (e.className === 'fas fa-play') {
e.className = 'fas fa-pause';
$('#' + elementid)[0].volume = onClick.home.event.volume;
$('#' + elementid)[0].play();
} else {
onClick.home.pause();
}
$('#' + elementid)[0].ontimeupdate = () => {
let percent = onClick.home.getPercent($('#' + elementid)[0].currentTime, $('#' + elementid)[0].duration);
$('#' + $(e).attr('time'))[0].innerHTML = onClick.home.getMinut($('#' + elementid)[0].currentTime) + ' / ' + onClick.home.getMinut($('#' + elementid)[0].duration);
$('#' + $(e).attr('progress'))[0].style.width = percent + '%';
}
},
stop: () => {
if (onClick.home.event != null) {
var volume = $('#' + onClick.home.event.elementid)[0].volume;
$('#' + onClick.home.event.elementid)[0].load();
$('#' + onClick.home.event.elementid)[0].volume = volume;
onClick.home.event.sound.className = 'fas fa-play';
}
},
volume: (e, elementid) => {
$('#' + elementid)[0].volume = (e.value / 100);
if (onClick.home.event === null) {
onClick.home.event = {
sound: null,
elementid: elementid,
volume: $('#' + elementid)[0].volume
};
}
onClick.home.event.volume = $('#' + elementid)[0].volume;
},
hidden: (elementid)=>{
$('#' + elementid)[0].hidden = !$('#' + elementid)[0].hidden;
},
like: (e, idMusic)=>{
$.post(
'./?view=home',
{
idMusic: idMusic
}, (data)=>{
if($(e)[0].className === 'fas fa-thumbs-up'){
$(e)[0].className = 'far fa-thumbs-up';
}else{
$(e)[0].className = 'fas fa-thumbs-up';
}
}
);
}
}
};

20
style/argon.min.css vendored Normal file

File diff suppressed because one or more lines are too long

30
style/home.css Normal file
View File

@@ -0,0 +1,30 @@
.volumeSound{
position: absolute;
transform: rotate(270deg);
width: 25%;
right: -20px;
top: -15px;
}
.cursor-pointer{
cursor: pointer;
transition: .2s;
}
.cursor-pointer:hover{
transform: scale(1.1);
}
.btn-description{
color: white;
border-radius: 12px;
border: none;
font-size: 10px;
}
.music{
color: white;
padding: 10px;
border: 1px rgba(255, 255, 255, 0.247) solid;
border-radius: 10px;
}

14
style/style.css Normal file
View File

@@ -0,0 +1,14 @@
html, body, .body{
width: 100%;
height: 100%;
margin: 0%;
padding: 0%;
font-family: Verdana, Geneva, Tahoma, sans-serif;
background-color: #212529;
user-select: none;
}
.center{
display: flex;
align-items: center;
}

8
view/403.view.php Normal file
View File

@@ -0,0 +1,8 @@
<div class="body text-center" style="background-color: #212529;">
<?php include $views['menu'] ?>
<br><br>
<h1 class="text-muted" style="font-size: 200px;">403</h1>
<h1 class="text-muted">Acceso no autorizado!</h1>
<br>
<a href="./?view=home" class="btn bg-info text-white"><i class="fas fa-arrow-left"></i> volver</a>
</div>

11
view/404.view.php Normal file
View File

@@ -0,0 +1,11 @@
<div class="body" style="background-color: #212529;">
<?php include $views['menu'] ?>
<br><br>
<center>
<img class="box-10" src="<?= $assets['IMAGE']['FILE_DIR']['404'] ?>" alt="">
<br><br>
<h1 class="text-muted">P&aacute;gina no encontrada!</h1>
<br>
<a href="./?view=home" class="btn btn-primary"><i class="fas fa-arrow-left"></i> volver</a>
</center>
</div>

42
view/dump.view.php Normal file
View File

@@ -0,0 +1,42 @@
<div class="body">
<?php include $views['menu']; ?>
<div class="container mt-5">
<h1 class="text-muted">Elementos Eliminados (<?= count($elementDelete) ?>)</h1>
<?php if(empty($elementDelete)):?>
<hr class="dropdown-divider">
<h2 class="text-muted text-center"><i>No Hay Elemento Eliminados.</i></h2>
<hr class="dropdown-divider">
<?php else:?>
<table class="table text-white">
<thead>
<tr>
<th>Nombre</th>
<th>Fecha</th>
<th>Acci&oacute;n</th>
</tr>
</thead>
<tbody>
<?php foreach ($elementDelete as $element) : ?>
<tr>
<td><?= $element['name'] ?></td>
<td><?= date('h:i A | d M Y', strtotime($element['date'])) ?></td>
<td>
<?php if (time() < (strtotime($element['date']) + 86400)) : ?>
<form action="" method="post">
<input type="hidden" name="delete" value="<?= $element['id'] ?>">
<input type="hidden" name="origin" value="<?= $element['origin'] ?>">
<button type="submit" class="btn btn-info">Restaurar</button>
</form>
<?php else:?>
<span class="text-muted"><i>No Disponible</i></span>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif;?>
<br><br>
<span class="text-muted"><i>Nota: solo dispone de 24 horas para restaurar un elemento y 1 hora para borrar una m&uacute;sica.</i></span>
</div>
</div>

62
view/home.view.php Normal file
View File

@@ -0,0 +1,62 @@
<div class="body">
<?php include $views['menu']; ?>
<div class="container-fluid mt-3">
<div class="card" style="background-color: #212529;">
<div class="card-body">
<h1 class="text-muted">Busca tu m&uacute;sica favorita</h1>
<form action="" method="get">
<div class="form-group">
<input type="text" name="search" class="form-control" placeholder="Nombre o Autor de Música a Buscar" required>
</div>
</form>
</div>
</div>
<?php if (isset($_GET['search'])) : ?>
<div class="card" style="background-color: #212529;">
<div class="card-header" style="background-color: #212529;">
<h2 class="text-muted">Resultados de Busqueda (<?= count($musics) ?>)</h2>
<hr class="dropdown-divider">
<br>
<?php foreach ($musics as $sound) : ?>
<?php include $views['sound']; ?>
<?php endforeach; ?>
</div>
<div class="card-body">
<br><br><br><br><br>
</div>
</div>
<?php endif; ?>
</div>
<?php if (!isset($_GET['search'])) : ?>
<div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<?php for ($i = 0; $i < count($assets['IMAGE']['CAROUSEL']['FILE_DIR']); $i++) : ?>
<li data-target="#carouselExampleIndicators" data-slide-to="<?= $i ?>" class="<?= $i == 0 ? 'active' : '' ?>"></li>
<?php endfor; ?>
</ol>
<div class="carousel-inner">
<?php foreach ($assets['IMAGE']['CAROUSEL']['FILE_DIR'] as $index => $path) : ?>
<div class="carousel-item <?= $index == 'bfmv' ? 'active' : '' ?>">
<img class="d-block w-100" src="<?= $path ?>">
</div>
<?php endforeach; ?>
</div>
<a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
<div class="container-fluid mt-5">
<h1 class="text-muted">LO NUEVO HASTA AHORA</h1>
<div class="dropdown-divider"></div><br>
<?php foreach($musics as $sound):?>
<?php include $views['sound'];?>
<?php endforeach;?>
</div>
<?php endif; ?>
<br><br><br><br><br>
</div>

43
view/listplay.view.php Normal file
View File

@@ -0,0 +1,43 @@
<div class="body">
<?php include $views['menu']; ?>
<div class="container-fluid mt-4">
<?php if (!isset($_GET['listmusic'])) : ?>
<h1 class="text-muted">Listas de Reproducci&oacute;n</h1>
<div class="dropdown-divider"></div>
<?php if (count($listsName) == 0) : ?>
<h3 class="text-muted text-center">No hay listas de reproducci&oacute;n disponibles.</h3>
<?php else : ?>
<?php foreach ($listsName as $listName) : ?>
<form action="" method="post" id="form_<?= $listName['listName'] ?>">
<a href="./?view=<?= $view ?>&listmusic=<?= md5($listName['idList']) ?>">
<h2 class="text-white"><i class="fas fa-plus"></i> <?= $listName['listName'] ?>
<a href="#" onclick="document.getElementById('form_<?= $listName['listName'] ?>').submit()"><i class="fas fa-trash-alt text-danger cursor-pointer"></i></a>
<input type="hidden" name="deleteList" value="<?= $listName['idList'] ?>">
</h2>
</a>
</form>
<?php endforeach; ?>
<?php endif; ?>
<div class="dropdown-divider"></div>
<button class="btn btn-primary" id="show-add-new-list" onclick="onClick.home.hidden('new-list');onClick.home.hidden('show-add-new-list');">Nueva Lista</button>
<div id="new-list" hidden>
<br>
<form action="" method="post">
<div class="form-group">
<label for="listname" class="text-white">Nombre de Lista</label><br>
<input type="text" name="txtListName" id="listname" minlength="3" required><br>
<button class="btn btn-danger" type="button" onclick="onClick.home.hidden('new-list');onClick.home.hidden('show-add-new-list');">Cancelar</button>
<button class="btn btn-primary" type="submit">Crear</button>
</div>
</form>
</div>
<?php else : ?>
<h1 class="text-muted">Lista de Reproducci&oacute;n <?=$listMusics['listName']?></h1>
<div class="dropdown-divider"></div>
<?php foreach($listMusics['musics'] as $music):?>
<?php $sound = $music['music'];?>
<?php include $views['sound'];?>
<?php endforeach;?>
<?php endif; ?>
</div>
</div>

53
view/loadmusic.view.php Normal file
View File

@@ -0,0 +1,53 @@
<div class="body">
<?php include $views['menu']; ?>
<div class="container mt-5">
<?php if (!isset($_GET['message'])) : ?>
<form action="" method="post" enctype="multipart/form-data">
<div class="card" style="background-color: #212529;">
<div class="card-header" style="background-color: #212529;">
<h1 class="text-muted"><i class="fas fa-music"></i> Nueva M&uacute;sica</h1>
</div>
<div class="card-body">
<div class="form-group">
<label for="title" class="text-white">T&iacute;tulo de la M&uacute;sica</label>
<input type="text" class="form-control" name="txtTitle" id="title" placeholder="título..." minlength="6" required>
</div>
<div class="form-group">
<label for="author" class="text-white">Nombre del Autor</label>
<input type="text" class="form-control" name="txtAuthor" id="author" placeholder="author..." minlength="6" required>
</div>
<div class="form-group">
<label for="description" class="text-white">Descripci&oacute;n de la M&uacute;sica</label>
<textarea class="form-control form-control-alternative" name="txtDescription" id="description" rows="3" placeholder="(opcional)"></textarea>
</div>
<div class="form-group">
<label for="" class="text-white">G&eacute;nero Musical</label>
<select name="genner" id="genner" class="form-control">
<?php foreach ($gennerMusical as $index => $genner) : ?>
<option value="<?= $index ?>"><?= $genner['gennerName'] ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="form-group">
<label for="fileMusic" class="text-white">Cargar el archivo musical</label>
<input type="file" name="fileMusic" id="fileMusic" class="form-control" accept=".WAV, .AIFF, .AU, .FLAC, .MPEG-4, .Shorten, .TTA, .ATRAC, .Apple Lossless, .MP3, .Vorbis, .Musepack, .AAC, .WMA, .Opus, .OGG, .DSD, .MQA" required>
</div>
</div>
<div class="card-footer text-right" style="background-color: #212529;">
<button type="submit" class="btn btn-success">Cargar</button>
</div>
</div>
</form>
<?php else:?>
<div class="card bg-<?=$_GET['action']?>">
<div class="card-body alert alert-<?=$_GET['action']?>">
<span class="display-3"><?=$_GET['message']?></span>
</div>
<div class="card-footer" style="background-color: #212529;">
<a href="./" class="btn btn-success"><i class="fas fa-arrow-left"></i> Inicio</a>
</div>
</div>
<?php endif; ?>
</div>
<br><br><br><br><br>
</div>

42
view/login.view.php Normal file
View File

@@ -0,0 +1,42 @@
<div class="body">
<?php include $views['menu'] ?>
<div class="container px-lg-9 mt-8">
<div class="card text-white px-lg-8 py-lg-5" style="background-color: #212529;">
<div class="card-header" style="background-color: #212529;">
<h2 class="text-white">Inicio de Sesión</h2>
</div>
<div class="card-body">
<?php if (isset($_POST['username'])) : ?>
<label for="" class="alert alert-danger">Usuario y/o clave inválido.</label>
<?php endif; ?>
<form action="" method="post">
<div class="form-group">
<div class="input-group input-group-alternative mb-4">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-user"></i></span>
</div>
<input class="form-control form-control-alternative" name="username" placeholder="Usuario" type="text" minlength="6" required>
</div>
</div>
<div class="form-group">
<div class="input-group input-group-alternative mb-4">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-lock"></i></span>
</div>
<input class="form-control form-control-alternative" name="password" placeholder="Contraseña" type="password" minlength="6" required>
</div>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary">Acceder</button>
</div>
</form>
</div>
<div class="card-footer" style="background-color: #212529;">
<a href="./?view=register">Registrarme</a>
</div>
</div>
</div>
<br><br><br><br><br>
</div>

4
view/logout.view.php Normal file
View File

@@ -0,0 +1,4 @@
<?php
Session::logout();
header('location: ./?view=home');
?>

59
view/menu.view.php Normal file
View File

@@ -0,0 +1,59 @@
<div class="navbar navbar-expand-lg navbar-dark" style="background-color: #212529;box-shadow: 0px 1px 15px 2px #6c757d;">
<div class="container">
<a class="navbar-brand" href="./"><?= $html->getTitle() ?></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar-default" aria-controls="navbar-default" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar-default">
<div class="navbar-collapse-header">
<div class="row">
<div class="col-6 collapse-brand">
<a href="javascript:void(0)">
<img src="<?= $html->getIconPage() ?>">
</a>
</div>
<div class="col-6 collapse-close">
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar-default" aria-controls="navbar-default" aria-expanded="false" aria-label="Toggle navigation">
<span></span>
<span></span>
</button>
</div>
</div>
</div>
<ul class="navbar-nav ml-lg-auto">
<?php if (Session::Auth()) : ?>
<li class="nav-item">
<a class="nav-link nav-link-icon" href="./?view=loadmusic">
<span><i class="fas fa-cloud-upload-alt"></i> Cargar M&uacute;sica</span>
</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link nav-link-icon" href="#" id="navbar-default_dropdown_1" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span><?=strtoupper(Session::getUsername())?></span>
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbar-default_dropdown_1" style="background-color: #212529;">
<a class="dropdown-item text-white disabled" href="#"><?=Session::Admin()?'Administrador':'Miembro'?></a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-white" href="./?view=dump">Papeler&iacute;a de Recliclaje</a>
<a class="dropdown-item text-white" href="./?view=listplay">Lista de Reproducci&oacute;n</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-white" href="./?view=logout"><i class="fas fa-sign-out-alt"></i>Cerrar Sesi&oacute;n</a>
</div>
</li>
<?php else : ?>
<li class="nav-item">
<a class="nav-link nav-link-icon" href="./?view=login">
<span><i class="fas fa-sign-in-alt"></i> Acceder</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link nav-link-icon" href="./?view=register">
<span><i class="fas fa-user-plus"></i> Registrarse</span>
</a>
</li>
<?php endif; ?>
</ul>
</div>
</div>
</div>

62
view/register.view.php Normal file
View File

@@ -0,0 +1,62 @@
<div class="body">
<?php include $views['menu'] ?>
<div class="container px-lg-9 mt-8">
<?php if (!isset($_GET['newuser'])) : ?>
<div class="card text-white px-lg-8 py-lg-5" style="background-color: #212529;">
<div class="card-header" style="background-color: #212529;">
<h2 class="text-white">Nuevo Usuario</h2>
</div>
<div class="card-body">
<?php if (isset($_GET['message'])) : ?>
<label class="alert alert-danger"><i class="fas fa-exclamation-triangle"></i> <?= $_GET['message'] ?></label>
<?php endif; ?>
<form action="" method="post">
<div class="form-group">
<div class="input-group input-group-alternative mb-4">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-user"></i></span>
</div>
<input class="form-control form-control-alternative" name="username" placeholder="Usuario" type="text" minlength="6" required>
</div>
</div>
<div class="form-group">
<div class="input-group input-group-alternative mb-4">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-lock"></i></span>
</div>
<input class="form-control form-control-alternative" name="password" placeholder="Contraseña" type="password" minlength="6" required>
</div>
</div>
<div class="form-group">
<div class="input-group input-group-alternative mb-4">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-lock"></i></span>
</div>
<input class="form-control form-control-alternative" name="rpassword" placeholder="Repetir Contraseña" type="password" minlength="6" required>
</div>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary">Crear</button>
</div>
</form>
</div>
<div class="card-footer" style="background-color: #212529;">
<a href="./?view=login">Iniciar Sesi&oacute;n</a>
</div>
</div>
<?php else : ?>
<div class="card" style="background-color: #212529;">
<div class="card-body">
<label class="alert alert-success"><?= $_GET['message'] ?></label>
</div>
<div class="card-footer" style="background-color: #212529;">
<a href="./?view=login" class="btn btn-primary">Iniciar Sesi&oacute;n</a>
</div>
</div>
<?php endif; ?>
</div>
<br><br><br><br><br>
</div>

100
view/sound.view.php Normal file
View File

@@ -0,0 +1,100 @@
<div style="width: 19rem;display: inline-block;">
<div class="card">
<div class="card-header" style="background-color: #212529;">
<div class="row">
<div class="col text-uppercase"><strong class="text-muted"><?= $sound['nameMusic'] ?></strong></div>
<div class="col text-right">
<span class="icon icon-shape rounded-circle bg-gray text-white">
<i class="fas fa-music"></i>
</span>
</div>
</div>
</div>
<div class="card-body" style="background-color: #212529;">
<audio id="sound_<?= $sound['idMusic'] ?>">
<source src="<?= $assets['SOUND']['FILE_DIR'][$sound['fileNameMusic']] ?>" type="<?= $sound['formatMusic'] ?>">
</audio>
<div class="music">
<div class="progress-wrapper">
<div class="progress-info">
<div class="progress-label">
<i class="fas fa-play" progress="progress_<?= $sound['idMusic'] ?>" time="time_<?= $sound['idMusic'] ?>" onclick="onClick.home.play(this, 'sound_<?= $sound['idMusic'] ?>')"></i>
<i class="fas fa-stop" progress="progress_<?= $sound['idMusic'] ?>" time="time_<?= $sound['idMusic'] ?>" onclick="onClick.home.stop()"></i>
</div>
<div class="progress-percentage">
<span id="time_<?= $sound['idMusic'] ?>"></span>
<i class="fas fa-volume-up" onclick="onClick.home.hidden('vol_<?= $sound['idMusic'] ?>')"></i>
<input class="volumeSound" id="vol_<?= $sound['idMusic'] ?>" type="range" onchange="onClick.home.volume(this, 'sound_<?= $sound['idMusic'] ?>')" onmousemove="onClick.home.volume(this, 'sound_<?= $sound['idMusic'] ?>')" hidden>
</div>
</div>
<div class="progress">
<div class="progress-bar bg-primary" id="progress_<?= $sound['idMusic'] ?>" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div>
</div>
</div>
</div>
<?php if (!empty($sound['descriptionMusic'])) : ?>
<div id="description_<?= $sound['idMusic'] ?>" hidden>
<div class="dropdown-divider"></div>
<span><?= $sound['descriptionMusic'] ?></span>
</div>
<?php endif; ?>
<div class="dropdown-divider"></div>
<div class="row">
<div class="col">
<h6 class="form-label text-gray" style="font-weight: normal;">G&eacute;nero: <i><span class="text-uppercase badge badge-danger"><?= $sound['genner']['gennerName'] ?></span></i></h6>
</div>
<div class="col">
<?php if (!empty($sound['descriptionMusic'])) : ?>
<button class="btn-description bg-info" onclick="onClick.home.hidden('description_<?= $sound['idMusic'] ?>')">Descripci&oacute;n</button>
<?php endif; ?>
</div>
</div>
<h6 class="form-label text-gray" style="font-weight: normal;">Publicado por: <i><span class="text-uppercase text-white"><?= $sound['user']['username'] ?></span></i></h6>
<h6 class="form-label text-gray" style="font-weight: normal;">Fecha de Pub.: <i><span class="text-uppercase text-white"><?= date('h:i A | d M Y', strtotime($sound['dateMusic'])) ?></span></i></h6>
<div class="dropdown-divider"></div>
<a href="./?view=<?= $view ?>&search=<?= $sound['authorMusic'] ?>" class="badge badge-success text-center"><?= $sound['authorMusic'] ?></a>
</div>
<div class="card-footer" style="background-color: #212529;">
<div class="row">
<?php if (Session::Auth()) : ?>
<div class="col text-success"><span class="cursor-pointer"><?= $sound['likes'] ?> <i class="<?= $sound['like'] ? 'fas' : 'far' ?> fa-thumbs-up" onclick="onClick.home.like(this, '<?= $sound['idMusic'] ?>')"></i></span></div>
<?php else : ?>
<a href="./?view=login">
<div class="col text-success"><?= $sound['likes'] ?> <i class="<?= $sound['like'] ? 'fas' : 'far' ?> fa-thumbs-up"></i></div>
</a>
<?php endif; ?>
<div class="col text-center">
<?php if (Session::Auth()) : ?>
<form action="" method="post" id="form_footer_<?= $sound['idMusic'] ?>">
<a href="<?= $assets['SOUND']['FILE_DIR'][$sound['fileNameMusic']] ?>" download="<?= $sound['nameMusic'] . '.' . (explode('.', $assets['SOUND']['FILE_DIR'][$sound['fileNameMusic']])[2]) ?>"><i class="fas fa-cloud-download-alt cursor-pointer"></i></a>
<?php if (time() <= (strtotime($sound['dateMusic']) + 3600) && $sound['idUser'] == Session::getUserID()) : ?>
<input type="hidden" name="delete" value="<?= $sound['idMusic'] ?>">
| <a href="#" onclick="document.getElementById('form_footer_<?= $sound['idMusic'] ?>').submit()"><i class="fas fa-trash-alt text-danger cursor-pointer"></i></a>
<?php endif; ?>
</form>
<?php endif; ?>
</div>
<div class="col text-right">
<?php if (Session::Auth()) : ?>
<div class="card" id="list_<?= $sound['idMusic'] ?>" style="position: absolute;bottom: 0px;right: 20px;width: 15rem;" hidden>
<div class="card-header text-center text-uppercase text-muted" style="background-color: #212529;">Mis Listas</div>
<div class="card-body text-left" style="background-color: #212529;">
<div class="dropdown-divider"></div>
<?php foreach ($listsName as $listName) : ?>
<form action="./?view=listplay" method="post" id="form_<?= $sound['idMusic'] ?>_<?= $listName['idList'] ?>">
<input type="hidden" name="idMusic" value="<?= $sound['idMusic'] ?>">
<input type="hidden" name="idList" value="<?= $listName['idList'] ?>">
<a onclick="document.getElementById('form_<?= $sound['idMusic'] ?>_<?= $listName['idList'] ?>').submit()" class="dropdown-item text-white cursor-pointer"><i class="fas fa-plus"></i> <?= $listName['listName'] ?></a>
</form>
<?php endforeach; ?>
<div class="dropdown-divider"></div>
</div>
<a href="./?view=listplay" class="btn bg-info text-white card-footer"><i class="fas fa-plus"></i> Nueva Lista</a>
</div>
<i class="fas fa-plus cursor-pointer" onclick="onClick.home.hidden('list_<?= $sound['idMusic'] ?>')"></i>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>