Дизайн комментариев.
Идем в файл api/index.php
<?php
require_once("DB.php");
require_once("Mail.php");
$db = new
DB("127.0.0.1", "SocialNetwork", "root",
"");
// 'REQUEST_METHOD'
- Какой метод был использован для запроса
страницы; к примеру 'GET', 'HEAD', 'POST', 'PUT'.
if
($_SERVER['REQUEST_METHOD'] == "GET") {
if ($_GET['url']
== "auth") {
//
} else if
($_GET['url'] == "users") {
//
} else if
($_GET['url'] == "comments" &&
isset($_GET['postid'])) {
//
комментарии
$output =
"";
$comments =
$db->query('SELECT comments.comment, users.username FROM comments,
users WHERE post_id = :postid AND comments.user_id = users.id',
array(':postid'=>$_GET['postid']));
$output .=
"[";
foreach($comments
as $comment) {
$output
.= "{";
$output
.= '"Comment": "'.$comment['comment'].'",';
$output
.= '"CommentedBy": "'.$comment['username'].'"';
$output
.= "},";
//echo
$comment['comment']." ~ ".$comment['username']."<hr
/>";
}
$output =
substr($output, 0, strlen($output)-1);
$output .=
"]";
echo
$output;
} else if
($_GET['url'] == "posts") {
$token =
$_COOKIE['SNID'];
$userid =
$db->query('SELECT user_id FROM login_tokens WHERE token=:token',
array(':token'=>sha1($token)))[0]['user_id'];
$followingposts
= $db->query('SELECT posts.id, posts.body, posts.posted_at,
posts.likes, users.`username` FROM users, posts, followers
WHERE
posts.user_id = followers.user_id
AND users.id
= posts.user_id
AND
follower_id = :userid
ORDER BY
posts.likes DESC;', array(':userid'=>$userid));
$response =
"[";
foreach($followingposts
as $post) {
$response
.= "{";
$response
.= '"PostId": '.$post['id'].',';
$response
.= '"PostBody": "'.$post['body'].'",';
$response
.= '"PostedBy": "'.$post['username'].'",';
$response
.= '"PostDate": "'.$post['posted_at'].'",';
$response
.= '"Likes": '.$post['likes'].'';
$response
.= "},";
}
$response =
substr($response, 0, strlen($response)-1);
$response .=
"]";
http_response_code(200);
echo
$response;
}
} else if
($_SERVER['REQUEST_METHOD'] == "POST") {
// Создание
аккаунта
if ($_GET['url']
== "users") {
$postBody =
file_get_contents("php://input");
$postBody =
json_decode($postBody);
$username =
$postBody->username;
$email =
$postBody->email;
$password =
$postBody->password;
if(!$db->query('SELECT
username FROM users WHERE username=:username',
array(':username'=>$username))) {
if(strlen($username)
>= 3 && strlen($username) <= 32) {
if(preg_match('/[a-zA-Z0-9_]+/', $username)) {
if(strlen($password) >= 6 &&
strlen($password) <= 60) {
if(filter_var($email, FILTER_VALIDATE_EMAIL)) {
if(!$db->query('SELECT email FROM users WHERE
email=:email', array(':email'=>$email))) {
$db->query('INSERT INTO users VALUES (:id,
:username, :password, :email, \'0\', \'\')', array(':id'=>null,
':username'=>$username, ':password'=>password_hash($password,
PASSWORD_BCRYPT), ':email'=>$email));
Mail::sendMail('Welcome to our Social Network!',
'Your account has been created!', $email);
echo
'{ "Success": "User created!" }';
http_response_code(200);
}
else {
echo
'{ "Error": "Email in use!" }';
http_response_code(409);
}
}
else {
echo
'{ "Error": "Invalid Email!" }';
http_response_code(409);
}
}
else {
echo
'{ "Error": "Invalid Password!" }';
http_response_code(409);
}
}
else {
echo
'{ "Error": "Invalid username!" }';
http_response_code(409);
}
} else {
echo
'{ "Error": "Invalid username!" }';
http_response_code(409);
}
} else {
echo '{
"Error": "User exists!" }';
http_response_code(409);
// 409 Conflict («конфликт»)
}
}
// Логин
if ($_GET['url']
== "auth") {
$postBody =
file_get_contents("php://input");
$postBody =
json_decode($postBody);
$username =
$postBody->username;
$password =
$postBody->password;
if
($db->query('SELECT username FROM users WHERE username=:username',
array(':username'=>$username))) {
//
password_verify — Проверяет, соответствует ли
пароль хешу
if
(password_verify($password, $db->query('SELECT password FROM users
WHERE username=:username',
array(':username'=>$username))[0]['password'])) {
$cstrong
= True;
$token
= bin2hex(openssl_random_pseudo_bytes(64, $cstrong));
$user_id
= $db->query('SELECT id FROM users WHERE username=:username',
array(':username'=>$username))[0]['id'];
$db->query('INSERT
INTO login_tokens VALUE (:id, :token, :user_id)', array(':id'=>null,
':token'=>sha1($token), ':user_id'=>$user_id));
echo
'{ "Token": "'.$token.'" }';
} else {
echo
'{ "Error": "Invalid username or password!" }';
http_response_code(401);
}
} else {
echo '{
"Error": "Invalid username or password!" }';
http_response_code(401);
}
} else if
($_GET['url'] == "likes") {
// Like-button.
Копируем из класса Post
$postId =
$_GET['id'];
$token =
$_COOKIE['SNID'];
$likerId =
$db->query('SELECT user_id FROM login_tokens WHERE token=:token',
array(':token'=>sha1($token)))[0]['user_id'];
if
(!$db->query('SELECT user_id FROM post_likes WHERE post_id=:postid
AND user_id=:userid', array(':postid'=>$postId,
':userid'=>$likerId))) {
$db->query('UPDATE
posts SET likes=likes+1 WHERE id=:postid',
array(':postid'=>$postId));
$db->query('INSERT
INTO post_likes VALUES (:id, :postid, :userid)', array(':id'=>null,
':postid'=>$postId, ':userid'=>$likerId));
//Notify::createNotify("",
$postId);
} else {
$db->query('UPDATE
posts SET likes=likes-1 WHERE id=:postid',
array(':postid'=>$postId));
$db->query('DELETE
FROM post_likes WHERE post_id=:postid AND user_id=:userid',
array(':postid'=>$postId, ':userid'=>$likerId));
}
echo "{";
echo
'"Likes":';
echo
$db->query('SELECT likes FROM posts WHERE id=:postid',
array(':postid'=>$postId))[0]['likes'];
echo "}";
}
} else if
($_SERVER['REQUEST_METHOD'] == "DELETE") {
if ($_GET['url']
== "auth") {
if
(isset($_GET['token'])) {
if
($db->query("SELECT token FROM login_tokens WHERE
token=:token", array(':token'=>sha1($_GET['token'])))) {
$db->query('DELETE
FROM login_tokens WHERE token=:token',
array(':token'=>sha1($_GET['token'])));
echo
'{ "Status": "Success" }';
http_response_code(200);
} else {
echo
'{ "Error": "Invalid token" }';
http_response_code(400);
}
} else {
echo '{
"Error": "Mal-formed request" }';
http_response_code(400);
}
}
}
else {
http_response_code(405);
}
?>
Посмотрим на
отображение комментариев в формате
json:
<!DOCTYPE
html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Social Network</title>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/fonts/ionicons.min.css">
<link rel="stylesheet" href="assets/css/Footer-Dark.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.1.1/aos.css">
<link rel="stylesheet" href="assets/css/Login-Form-Clean.css">
<link rel="stylesheet" href="assets/css/Navigation-Clean1.css">
<link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="assets/css/untitled.css">
</head>
<body>
<header class="hidden-sm hidden-md hidden-lg">
<div class="searchbox">
<form>
<h1 class="text-left">Social Network</h1>
<div class="searchbox"><i class="glyphicon glyphicon-search"></i>
<input class="form-control" type="text">
</div>
<div class="dropdown">
<button class="btn btn-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false" type="button">MENU <span class="caret"></span></button>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li role="presentation"><a href="#">My Profile</a></li>
<li class="divider" role="presentation"></li>
<li role="presentation"><a href="#">Timeline </a></li>
<li role="presentation"><a href="#">Messages </a></li>
<li role="presentation"><a href="#">Notifications </a></li>
<li role="presentation"><a href="#">My Account</a></li>
<li role="presentation"><a href="#">Logout </a></li>
</ul>
</div>
</form>
</div>
<hr>
</header>
<div>
<nav class="navbar navbar-default hidden-xs navigation-clean">
<div class="container">
<div class="navbar-header"><a class="navbar-brand navbar-link" href="#"><i class="icon ion-ios-navigate"></i></a>
<button class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>
</div>
<div class="collapse navbar-collapse" id="navcol-1">
<form class="navbar-form navbar-left">
<div class="searchbox"><i class="glyphicon glyphicon-search"></i>
<input class="form-control" type="text">
</div>
</form>
<ul class="nav navbar-nav hidden-md hidden-lg navbar-right">
<li role="presentation"><a href="#">My Timeline</a></li>
<li class="dropdown open"><a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true" href="#">User <span class="caret"></span></a>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li role="presentation"><a href="#">My Profile</a></li>
<li class="divider" role="presentation"></li>
<li role="presentation"><a href="#">Timeline </a></li>
<li role="presentation"><a href="#">Messages </a></li>
<li role="presentation"><a href="#">Notifications </a></li>
<li role="presentation"><a href="#">My Account</a></li>
<li role="presentation"><a href="#">Logout </a></li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav hidden-xs hidden-sm navbar-right">
<li class="active" role="presentation"><a href="#">Timeline</a></li>
<li role="presentation"><a href="#">Messages</a></li>
<li role="presentation"><a href="#">Notifications</a></li>
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" href="#">User <span class="caret"></span></a>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li role="presentation"><a href="#">My Profile</a></li>
<li class="divider" role="presentation"></li>
<li role="presentation"><a href="#">Timeline </a></li>
<li role="presentation"><a href="#">Messages </a></li>
<li role="presentation"><a href="#">Notifications </a></li>
<li role="presentation"><a href="#">My Account</a></li>
<li role="presentation"><a href="#">Logout </a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
</div>
<div class="container">
<h1>Timeline </h1>
<div class="timelineposts">
</div>
</div>
<div class="modal fade" role="dialog" tabindex="-1" style="padding-top:100px;">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Comments</h4></div>
<div class="modal-body" style="max-height: 400px; overflow-y: auto">
<p>The content of your modal.</p>
</div>
<div class="modal-footer">
<button class="btn btn-default" type="button" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="footer-dark navbar-fixed-bottom">
<footer>
<div class="container">
<p class="copyright">Social Network© 2016</p>
</div>
</footer>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-animation.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.1.1/aos.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type: "GET",
url: "api/posts",
processData: false,
contentType: "application/json",
data: '',
success: function(r) {
var posts = JSON.parse(r);
$.each(posts, function(index) {
$('.timelineposts').html(
$('.timelineposts').html() + '<blockquote><p>'+posts[index].PostBody+'</p><footer>Posted by '+posts[index].PostedBy+' on '+posts[index].PostDate+'<button class="btn btn-default" data-id="'+posts[index].PostId+'" type="button" style="color:#eb3b60;background-image:url("none");background-color:transparent;"> <i class="glyphicon glyphicon-heart" data-aos="flip-right"></i><span> '+posts[index].Likes+' Likes</span></button><button class="btn btn-default comment" type="button" data-postid="'+posts[index].PostId+'" style="color:#eb3b60;background-image:url("none");background-color:transparent;"><i class="glyphicon glyphicon-flash" style="color:#f9d616;"></i><span style="color:#f9d616;"> Comments</span></button></footer></blockquote>'
)
$('[data-postid]').click(function() {
var buttonid = $(this).attr('data-postid');
$.ajax({
type: "GET",
url: "api/comments?postid=" + $(this).attr('data-postid'),
processData: false,
contentType: "application/json",
data: '',
success: function(r) {
var res = JSON.parse(r)
showCommentsModal(res);
},
error: function(r) {
console.log(r)
}
});
});
$('[data-id]').click(function() {
var buttonid = $(this).attr('data-id');
$.ajax({
type: "POST",
url: "api/likes?id=" + $(this).attr('data-id'),
processData: false,
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Social Network</title>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/fonts/ionicons.min.css">
<link rel="stylesheet" href="assets/css/Footer-Dark.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.1.1/aos.css">
<link rel="stylesheet" href="assets/css/Login-Form-Clean.css">
<link rel="stylesheet" href="assets/css/Navigation-Clean1.css">
<link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="assets/css/untitled.css">
</head>
<body>
<header class="hidden-sm hidden-md hidden-lg">
<div class="searchbox">
<form>
<h1 class="text-left">Social Network</h1>
<div class="searchbox"><i class="glyphicon glyphicon-search"></i>
<input class="form-control" type="text">
</div>
<div class="dropdown">
<button class="btn btn-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false" type="button">MENU <span class="caret"></span></button>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li role="presentation"><a href="#">My Profile</a></li>
<li class="divider" role="presentation"></li>
<li role="presentation"><a href="#">Timeline </a></li>
<li role="presentation"><a href="#">Messages </a></li>
<li role="presentation"><a href="#">Notifications </a></li>
<li role="presentation"><a href="#">My Account</a></li>
<li role="presentation"><a href="#">Logout </a></li>
</ul>
</div>
</form>
</div>
<hr>
</header>
<div>
<nav class="navbar navbar-default hidden-xs navigation-clean">
<div class="container">
<div class="navbar-header"><a class="navbar-brand navbar-link" href="#"><i class="icon ion-ios-navigate"></i></a>
<button class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>
</div>
<div class="collapse navbar-collapse" id="navcol-1">
<form class="navbar-form navbar-left">
<div class="searchbox"><i class="glyphicon glyphicon-search"></i>
<input class="form-control" type="text">
</div>
</form>
<ul class="nav navbar-nav hidden-md hidden-lg navbar-right">
<li role="presentation"><a href="#">My Timeline</a></li>
<li class="dropdown open"><a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true" href="#">User <span class="caret"></span></a>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li role="presentation"><a href="#">My Profile</a></li>
<li class="divider" role="presentation"></li>
<li role="presentation"><a href="#">Timeline </a></li>
<li role="presentation"><a href="#">Messages </a></li>
<li role="presentation"><a href="#">Notifications </a></li>
<li role="presentation"><a href="#">My Account</a></li>
<li role="presentation"><a href="#">Logout </a></li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav hidden-xs hidden-sm navbar-right">
<li class="active" role="presentation"><a href="#">Timeline</a></li>
<li role="presentation"><a href="#">Messages</a></li>
<li role="presentation"><a href="#">Notifications</a></li>
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" href="#">User <span class="caret"></span></a>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li role="presentation"><a href="#">My Profile</a></li>
<li class="divider" role="presentation"></li>
<li role="presentation"><a href="#">Timeline </a></li>
<li role="presentation"><a href="#">Messages </a></li>
<li role="presentation"><a href="#">Notifications </a></li>
<li role="presentation"><a href="#">My Account</a></li>
<li role="presentation"><a href="#">Logout </a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
</div>
<div class="container">
<h1>Timeline </h1>
<div class="timelineposts">
</div>
</div>
<div class="modal fade" role="dialog" tabindex="-1" style="padding-top:100px;">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Comments</h4></div>
<div class="modal-body" style="max-height: 400px; overflow-y: auto">
<p>The content of your modal.</p>
</div>
<div class="modal-footer">
<button class="btn btn-default" type="button" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="footer-dark navbar-fixed-bottom">
<footer>
<div class="container">
<p class="copyright">Social Network© 2016</p>
</div>
</footer>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-animation.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.1.1/aos.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type: "GET",
url: "api/posts",
processData: false,
contentType: "application/json",
data: '',
success: function(r) {
var posts = JSON.parse(r);
$.each(posts, function(index) {
$('.timelineposts').html(
$('.timelineposts').html() + '<blockquote><p>'+posts[index].PostBody+'</p><footer>Posted by '+posts[index].PostedBy+' on '+posts[index].PostDate+'<button class="btn btn-default" data-id="'+posts[index].PostId+'" type="button" style="color:#eb3b60;background-image:url("none");background-color:transparent;"> <i class="glyphicon glyphicon-heart" data-aos="flip-right"></i><span> '+posts[index].Likes+' Likes</span></button><button class="btn btn-default comment" type="button" data-postid="'+posts[index].PostId+'" style="color:#eb3b60;background-image:url("none");background-color:transparent;"><i class="glyphicon glyphicon-flash" style="color:#f9d616;"></i><span style="color:#f9d616;"> Comments</span></button></footer></blockquote>'
)
$('[data-postid]').click(function() {
var buttonid = $(this).attr('data-postid');
$.ajax({
type: "GET",
url: "api/comments?postid=" + $(this).attr('data-postid'),
processData: false,
contentType: "application/json",
data: '',
success: function(r) {
var res = JSON.parse(r)
showCommentsModal(res);
},
error: function(r) {
console.log(r)
}
});
});
$('[data-id]').click(function() {
var buttonid = $(this).attr('data-id');
$.ajax({
type: "POST",
url: "api/likes?id=" + $(this).attr('data-id'),
processData: false,
contentType:
"application/json",
data: '',
success: function(r) {
var res = JSON.parse(r)
$("[data-id='"+buttonid+"']").html(' <i class="glyphicon glyphicon-heart" data-aos="flip-right"></i><span> '+res.Likes+' Likes</span>')
},
error: function(r) {
console.log(r)
}
});
})
})
},
error: function(r) {
console.log(r)
}
});
});
function showCommentsModal(res) {
$('.modal').modal('show')
var output = "";
for (var i = 0; i < res.length; i++) {
output += res[i].Comment;
output += " ~ ";
output += res[i].CommentedBy;
output += "<hr />";
}
$('.modal-body').html(output)
}
</script>
</body>
</html>
data: '',
success: function(r) {
var res = JSON.parse(r)
$("[data-id='"+buttonid+"']").html(' <i class="glyphicon glyphicon-heart" data-aos="flip-right"></i><span> '+res.Likes+' Likes</span>')
},
error: function(r) {
console.log(r)
}
});
})
})
},
error: function(r) {
console.log(r)
}
});
});
function showCommentsModal(res) {
$('.modal').modal('show')
var output = "";
for (var i = 0; i < res.length; i++) {
output += res[i].Comment;
output += " ~ ";
output += res[i].CommentedBy;
output += "<hr />";
}
$('.modal-body').html(output)
}
</script>
</body>
</html>
Комментариев нет:
Отправить комментарий