Talk:ShushiBeats
From Laboratório MM 5
Relatório SushiBeats
Ana Lapa | Daniel Vieira | José Azevedo
1. Introdução
1.1. Objectivo do documento
1.2. Visão geral do projecto
2. Base de dados desenvolvida
3. Implementação
3.1. Descrição das principais funcionalidades da aplicação Web
3.2. Mapa de páginas
3.2.1. Server Behaviours utilizados
3.2.2. Recordsets/Queries utilizados
3.2.3 Parâmetros passados entre páginas
4. Integração (e.g. Flash, AJAX Frameworks, etc)
5. Desenvolvimentos Futuros
6. Conclusões
7. Referências bibliográficas
1. Introdução
No presente documento será exposto todo o processo de realização do projecto Sushi Beats, desde o momento da escolha do tema, passando pelo processo de implementação, e finalizando com conclusões do grupo relativamente ao que está e ao que poderá ser realizado. Contextualizando, o projecto Sushi Beats nasceu de uma paixão que o grupo partilha: a música, mais concretamente o género Drum and Bass. Desde o início do projecto o objectivo final centrou-se na criação de um serviço Web 2.0 que se direccionasse exclusivamente para o público que partilhasse do gosto pelo género de música mencionado. Sendo assim propôs-se criar um local virtual, com algumas directrizes de redes sociais existentes como o FaceBook e My Space, para criar um espaço de partilha de música e de tudo o que possa estar relacionado, desde eventos a fotografias e vídeos dos mesmos (os quais podem ser realizados os uploads pelos utilizadores)e novos sons que os artistas registados no site possam ter partilhado para a comunidade.
Numa visão geral o Sushi Beats será um serviço Web 2.0 dedicado ao Drum and Bass e ao público que tiver interesse pela música e em discutir, informar-se e socializar virtualmente com outras pessoas que partilhem dos mesmos gostos. Para tal os utilizadores da Web 2.0 poderão visitar o site, ter uma pequena amostra deste e, caso estejam interessados, registar-se para acederem a todo o site.
Endereço: xxxxx Dados de acesso: xxxxx
1.1. Objectivos do documento
O presente documento visa apresentar o relatório do projecto Sushibeats, realizado no âmbito da disciplina de Laboratório Multimédia IV. No final, espera ter-se apresentado: (i)objectivos do presente documento; (ii)a visão geral do projecto; (iii)a base de dados desenvolvida; (iv) o processo de implementação; (v) os desenvolvimentos futuros; e (vi) as devidas conclusões. Este documento tem como função auxiliar o entendimento do projecto SushiBeats através de uma explicação teórica da criação do projecto, explicação, essa, conjugada com excertos de código, demonstrando como se define o mapa de páginas e a lógica do processo de criação do projecto. Com a explicação teórica, pretende-se, então, desmistificar quaisquer dúvidas que o projecto em si, possa criar.
Base de dados
A base de dados do projecto Sushi Beats tem como entidades essenciais: • Música(não implementado) • Utilizadores • Tipo_utilizadores • Amigos(não implementado) • Eventos • Comentarios (não implementado) • Wall_Posts(não funcional) • Photos (não implementado) • Videos (não implementado) • Notícias
A base de dados MySQL foi criada a partir da lógica de um site de uma rede social Web 2.0. Foi criada com o intuito de ser completa e desde o seu desenvolvimento sabíamos não ser possível implementar tudo.
Implementação
Descrição das principais funcionalidades Páginas implementadas index.php about.php (página com os diferentes FAQS) addevent.php (página onde se encontra a adição de eventos) events.php (página dos eventos) fotosgal.php (página de update de perfil) profile.php (página de perfil de utilizador) top.php (topo do site sem login efectuado) topin.php (topo do site com login efectuado)
Server Behaviors, Recordsets e Queries
Index.php: Check new username: Código por defeito do dreamweaver, não está funcional. // *** Redirect if username exists $MM_flag="MM_insert"; if (isset($_POST[$MM_flag])) {
$MM_dupKeyRedirect="index.php?action=register&result=false&error=3";
$loginUsername = $_POST['username'];
$LoginRS__query = sprintf("SELECT username FROM utilizadores WHERE username=%s", GetSQLValueString($loginUsername, "text"));
mysql_select_db($database_dbsushi, $dbsushi);
$LoginRS=mysql_query($LoginRS__query, $dbsushi) or die(mysql_error());
$loginFoundUser = mysql_num_rows($LoginRS);
//if there is a row in the database, the username was found - can not add the requested username
if($loginFoundUser){
$MM_qsChar = "?";
//append the username to the redirect page
if (substr_count($MM_dupKeyRedirect,"?") >=1) $MM_qsChar = "&";
$MM_dupKeyRedirect = $MM_dupKeyRedirect . $MM_qsChar ."requsername=".$loginUsername;
header ("Location: $MM_dupKeyRedirect");
exit;
}
} Recordset (utilizadores): Query para o recordset da tabela utilizadores. Seleciona todas os items da tabela e executa a query, guardando o resultado na variável $row_utilizadores. mysql_select_db($database_dbsushi, $dbsushi); $query_utilizadores = "SELECT * FROM utilizadores"; $utilizadores = mysql_query($query_utilizadores, $dbsushi) or die(mysql_error()); $row_utilizadores = mysql_fetch_assoc($utilizadores); $totalRows_utilizadores = mysql_num_rows($utilizadores); Insert record(link from top.php): Behavior para fazer o registo do utilizador. É executada a query INSERT dos parâmetros recebidos pelo formulário de registo para a tabela utilizadores. De referir que a password tem encriptação md5. if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "register")) {
$insertSQL = sprintf("INSERT INTO utilizadores (username, password, activo, data_registo, nome, email, idade, tipo_utilizador_id) VALUES (%s, md5(%s), %s, %s, %s, %s, %s, %s)",
GetSQLValueString($_POST['username'], "text"),
GetSQLValueString($_POST['password'], "text"),
GetSQLValueString($_POST['activo'], "int"),
GetSQLValueString($_POST['data_registo'], "date"),
GetSQLValueString($_POST['nome'], "text"),
GetSQLValueString($_POST['email'], "text"),
GetSQLValueString($_POST['idade'], "text"),
GetSQLValueString($_POST['tipo_utilizador_id'], "int"));
mysql_select_db($database_dbsushi, $dbsushi); $Result1 = mysql_query($insertSQL, $dbsushi) or die(mysql_error());
$insertGoTo = "index.php?action=register&result=true";
if (isset($_SERVER['QUERY_STRING'])) {
$insertGoTo .= (strpos($insertGoTo, '?')) ? "&" : "?";
$insertGoTo .= $_SERVER['QUERY_STRING'];
}
header(sprintf("Location: %s", $insertGoTo));
} Update record(form from fotogal.php): Behavior para fazer a query de UPDATE da tabela utilizadores. if ((isset($_POST["MM_update"])) && ($_POST["MM_update"] == "update")) {
$updateSQL = sprintf("UPDATE utilizadores SET nome=%s, email=%s, idade=%s WHERE username='$_SESSION[MM_Username]'",
GetSQLValueString($_POST['nome'], "text"),
GetSQLValueString($_POST['email'], "text"),
GetSQLValueString($_POST['idade'], "text"),
GetSQLValueString($_POST['username'], "text"));
mysql_select_db($database_dbsushi, $dbsushi); $Result1 = mysql_query($updateSQL, $dbsushi) or die(mysql_error());
$updateGoTo = "index.php?action=profile";
if (isset($_SERVER['QUERY_STRING'])) {
$updateGoTo .= (strpos($updateGoTo, '?')) ? "&" : "?";
$updateGoTo .= $_SERVER['QUERY_STRING'];
}
header(sprintf("Location: %s", $updateGoTo));
} Login user(link from top.php): Behavior para o login de utilizador. É executada uma query SELECT do username, password e tipo utilizador. São guardadas as variáveis do username e password pelo comando $_SESSION. O item “activo” varia para 1 através da query UPDATE, de forma a diferenciar um utilizador autenticado de um não autenticado. N página é verificado se está autenticado “perguntando” se $_SESSION tem informação guardada. if (isset($_POST['username1'])) {
$loginUsername=$_POST['username1'];
$password=$_POST['password1'];
$MM_fldUserAuthorization = "tipo_utilizador_id";
$MM_redirectLoginSuccess = "index.php?action=login&result=true";
$MM_redirectLoginFailed = "index.php?action=login&result=false&error=1";
$MM_redirecttoReferrer = false;
mysql_select_db($database_dbsushi, $dbsushi);
$LoginRS__query=sprintf("SELECT username, password, tipo_utilizador_id FROM utilizadores WHERE username=%s AND password=md5(%s)",
GetSQLValueString($loginUsername, "text"), GetSQLValueString($password, "text"));
$LoginRS = mysql_query($LoginRS__query, $dbsushi) or die(mysql_error());
$loginFoundUser = mysql_num_rows($LoginRS);
if ($loginFoundUser) {
$loginStrGroup = mysql_result($LoginRS,0,'tipo_utilizador_id');
//declare two session variables and assign them
$_SESSION['MM_Username'] = $loginUsername;
$_SESSION['MM_UserGroup'] = $loginStrGroup;
if (isset($_SESSION['PrevUrl']) && false) {
$MM_redirectLoginSuccess = $_SESSION['PrevUrl'];
}
header("Location: " . $MM_redirectLoginSuccess );
}
else {
header("Location: ". $MM_redirectLoginFailed );
}
$query_activo = sprintf("UPDATE utilizadores SET activo='1' WHERE username = '$_SESSION[MM_Username]'");
$do_query = mysql_query($query_activo,$dbsushi); } Data do registo (dynamic text field): Data de registo por recurso ao commando “date”.
<input type="hidden" name="data_registo" value="<?php echo date('Y-n-d H:i:s'); ?>" />
Log out(link from topin.php): É verificado se o utilizador está autenticado e é feito o log out. As variáveis $_SESSION de username e password são apagadas, e através da query UPDATE o item “activo” fica a 0. // ** Logout the current user. ** $logoutAction = $_SERVER['PHP_SELF']."?doLogout=true"; if ((isset($_SERVER['QUERY_STRING'])) && ($_SERVER['QUERY_STRING'] != "")){
$logoutAction .="&". htmlentities($_SERVER['QUERY_STRING']);
}
if ((isset($_GET['doLogout'])) &&($_GET['doLogout']=="true")){ //marcar utilizador como activo $query_activo = sprintf("UPDATE utilizadores SET activo='0' WHERE username = '$_SESSION[MM_Username]'"); $do_query = mysql_query($query_activo,$dbsushi);
//to fully log out a visitor we need to clear the session varialbles $_SESSION['MM_Username'] = NULL; $_SESSION['MM_UserGroup'] = NULL; $_SESSION['PrevUrl'] = NULL; unset($_SESSION['MM_Username']); unset($_SESSION['MM_UserGroup']); unset($_SESSION['PrevUrl']);
$logoutGoTo = "index.php?action=logout&result=true";
if ($logoutGoTo) {
header("Location: $logoutGoTo");
exit;
}}
Profile.php: Recordset(utilizadores): Recordset criado sem apoio dos behaviors do dreamweaver, por forma a receber os items da tabela “utilizadores”, filtrados por id. Este método é utilizado também na página de update profile, mas recorrendo ao filtro “username” em vez de “id”. $colname_utilizadores = "-1"; if (isset($_GET['id'])) {
$colname_utilizadores = $_GET['id'];
} mysql_select_db($database_dbsushi, $dbsushi); $query_utilizadores = sprintf("SELECT * FROM utilizadores WHERE user_id = %s", GetSQLValueString($colname_utilizadores, "int")); $utilizadores = mysql_query($query_utilizadores, $dbsushi) or die(mysql_error());
while ($row = mysql_fetch_assoc($utilizadores)) {
$user_id = $row["userid"]; $foto_perfil = $row["fotoperfil"];
$username = $row["username"]; $nome = $row["nome"]; $email = $row["email"]; $idade = $row["idade"]; Recordset (wall_posts): Recordset da tabela “wall_posts”. mysql_select_db($database_dbsushi, $dbsushi); $query_wallposts = "SELECT * FROM wall_posts"; $wallposts = mysql_query($query_wallposts, $dbsushi) or die(mysql_error()); $row_wallposts = mysql_fetch_assoc($wallposts); $totalRows_wallposts = mysql_num_rows($wallposts); Insert wall_post: Tentativa de INSERT da tabela wall_posts o conteúdo inserido no formulário que se pode encontrar na mesma página. A query/código não está funcional. if(isset($_POST['message_wall'])){ $message = strip_tags($_POST['message_wall']); $sql = sprintf("INSERT INTO wall_posts (wall_post_content) VALUES('$message')"); $Result1 = mysql_query($sql, $dbsushi) or die(mysql_error());
echo $message; } Fotogal.php: Update photo: Query UPDATE para guardar o nome da foto de perfil na base de dados. O código utilizado nesta página foi adaptado da fonte: http://www.reconn.us/content/view/30/51/ $query_fotoperfil = sprintf("UPDATE utilizadores SET fotoperfil='$image_name' WHERE username='$_SESSION[MM_Username]'"); $fazer_query = mysql_query($query_fotoperfil,$dbsushi);
echo "File Uploaded Successfully!
";News.php: Recordset (noticias): Record set para a tabela notícias. mysql_select_db($database_dbsushi, $dbsushi); $query_noticias = "SELECT * FROM noticias"; $noticias = mysql_query($query_noticias, $dbsushi) or die(mysql_error()); $row_noticias = mysql_fetch_assoc($noticias); $totalRows_noticias = mysql_num_rows($noticias);
Events.php: Restrict acess to page: Restrição para que apenas utilizadores autenticados possam aceder à página de eventos. <?php if (!isset($_SESSION)) {
session_start();
} $MM_authorizedUsers = ""; $MM_donotCheckaccess = "true";
// *** Restrict Access To Page: Grant or deny access to this page function isAuthorized($strUsers, $strGroups, $UserName, $UserGroup) {
// For security, start by assuming the visitor is NOT authorized. $isValid = False;
// When a visitor has logged into this site, the Session variable MM_Username set equal to their username.
// Therefore, we know that a user is NOT logged in if that Session variable is blank.
if (!empty($UserName)) {
// Besides being logged in, you may restrict access to only certain users based on an ID established when they login.
// Parse the strings into arrays.
$arrUsers = Explode(",", $strUsers);
$arrGroups = Explode(",", $strGroups);
if (in_array($UserName, $arrUsers)) {
$isValid = true;
}
// Or, you may restrict access to only certain users based on their username.
if (in_array($UserGroup, $arrGroups)) {
$isValid = true;
}
if (($strUsers == "") && true) {
$isValid = true;
}
}
return $isValid;
}
$MM_restrictGoTo = "index.php?error=login"; if (!((isset($_SESSION['MM_Username'])) && (isAuthorized("",$MM_authorizedUsers, $_SESSION['MM_Username'], $_SESSION['MM_UserGroup'])))) {
$MM_qsChar = "?"; $MM_referrer = $_SERVER['PHP_SELF']; if (strpos($MM_restrictGoTo, "?")) $MM_qsChar = "&"; if (isset($QUERY_STRING) && strlen($QUERY_STRING) > 0) $MM_referrer .= "?" . $QUERY_STRING; $MM_restrictGoTo = $MM_restrictGoTo. $MM_qsChar . "accesscheck=" . urlencode($MM_referrer);echo "
exit;
} Recordset(events): Recordset para a tabela eventos. Na query SELECT os elementos são ordenados por ordem descendente. mysql_select_db($database_dbsushi, $dbsushi); $query_Recordset1 = "SELECT * FROM eventos ORDER BY evento_id DESC"; $query_limit_Recordset1 = sprintf("%s LIMIT %d, %d", $query_Recordset1, $startRow_Recordset1, $maxRows_Recordset1); $Recordset1 = mysql_query($query_limit_Recordset1, $dbsushi) or die(mysql_error()); $row_Recordset1 = mysql_fetch_assoc($Recordset1); Repeat Region: Repeat region dos eventos. Outra repeat region é utilizada na página <?php do { ?>
<?php } while ($row_Recordset1 = mysql_fetch_assoc($Recordset1)); ?>
Parâmetros passados entre páginas
Através destes parâmetros é possível filtrar o que pretendemos que a página mostre. Poderá ser filtrado o user_id do utilizador para serem apresentados os seus dados na página de perfil, por exemplo, ou ainda o parâmetro “page” que permite mostrar as respectivas páginas no index.php através do comando “include”. Temos ainda o parâmetro “action” para filtrar as acções que o utilizador realizou, o login, logout e registo no site. Estes parâmetros são passados por URL e recebidos na página php pelo comando $_GET. Action: ‘profile’; ‘login’;’logout’;’register’ Result: ‘true’;’false’ Id: ‘user_id’ Page:’myphotos’;’events’;’newsdetail’;’about’;’addevent’
Desenvolvimentos Futuros
Devido a certas complicações com a implementação de certas funcionalidades de CSS e HTML, o grupo acabou por perder tempo precioso para a implementação da parte que re-almente dizia respeito à disciplina de LAB5. Assim, muitas das funcionalidades que tínhamos planeado incluir neste projecto não foram implementadas e algumas das que conseguimos não funcionam a cem por cento.
Algumas das funcionalidades que gostaríamos de ver implementadas em desenvolvimentos futuros: Suporte para upload e partilha de galerias de fotos (o site já tem o upload de fotos mas apenas para uma e apenas para ser usada como “avatar” virtual do utillizador);
Suporte para upload e partilha de músicas e vídeos; Um “wall post”, ou seja, uma página em que os utilizadores podessem fazer o post de co-mentários, sites, imagens, músicas, vídeos e eventos relacionados com o drum and bass. Conclusão O aparecimento do conceito de Web 2.0 tem vindo a modificar gradualmente os standards dos serviços que se baseiam fundamentalmente na interacção com o utilizador. É graças a este contributo que o sucesso desta nova geração de plataformas web tem sido tão explosivo. Quando partímos para a fase de implementação da ideia que escolhemos para o projecto, considerámos como objectivo final a criação de um portal social para um público muito específico, que funcionasse correctamente e de modo fluído. Cedo nos apercebemos que seria um trabalho demasiado complexo para a meta temporal estabelecida. Contudo, procurámos implementar o maior número de funcionalidades totalmente funcionais que considerámos ser mais importantes para o objectivo do site. Tentámos também fazer com que a navegação fosse fácil e intuitiva para todos os novos utilizadores, de acordo com as regras de usabilidade.
Bibliografia Programação com PHP 5.3 – Carlos Serrão e Joaquim Marques, editora FCA- Editora de Informática
Locais na Web http://php.net/ http://www.fca.pt/ http://www.queness.com/post/77/simple-jquery-modal-window-tutorial/ (janela modal utilizada no login e registo) http://woork.blogspot.com/2009/05/how-to-implement-post-to-wall-facebook.html/ (wall_post da página de perfil) http://www.gmarwaha.com/blog/2007/08/23/lavalamp-for-jquery-lovers/ (menu do site incluído em top.php e topin.php) http://dev.mysql.com/ (recurso utilizado para consulta de querys)