Web Exam help
From ICO wiki
IMAGE GALLERY
INDEX.php
<?php
require_once "config.php";
include "header.php";
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error)
die("Connection to database failed:" .
$conn->connect_error);
$conn->query("set names utf8");
?>
<h1 style="color:Purple ;font-family:Indie Flower; float:Center"><em><center>Sheela's Image#Gallery</center></em></h1>
<p>
<?php
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$statement = $conn->prepare(
"select * from Sheela_gallery_user where email = ? and " .
"password_hash = SHA1(CONCAT(password_salt, ?))");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("ss", $_POST["email"], $_POST["password"]);
$statement->execute();
$results = $statement->get_result();
$row = $results->fetch_assoc();
if (!$row)
echo "Login failed!";
$_SESSION["user"] = $row;
}
// Here we check if the user is logged in
if ($user = @$_SESSION["user"]) { // Extra lazy hack, use $user instead of $_SESSION["user"] from now on
?>
<h1>Hello <?=$user["display_name"];?></h1>
<p>
Add albums <a href="addalbum.php">here</a>.
Upload images <a href="upload.php">here</a>.
</p>
My albums:
<?php
// Here we list user's albums
$statement = $conn->prepare("select * from Sheela_gallery_album where owner_id = ?");
$statement->bind_param("i", $user["id"]);
$statement->execute();
?><ul><?php
foreach ($statement->get_result() as $row) {
?><li><a href="album.php?id=<?=$row['id']?>"><?=$row['name'];?></a>
<a href="deletealbum.php?id=<?=$row['id']?>">[Delete]</a>
</li><?php
}
?></ul>
My recent uploads:
<?php
// To show images of the user
$statement = $conn->prepare(
"select Sheela_gallery_image.id, Sheela_gallery_image.hash, Sheela_gallery_image.created " .
"from Sheela_gallery_image " .
"join Sheela_gallery_album " .
"on Sheela_gallery_album.id = Sheela_gallery_image.album_id " .
"where Sheela_gallery_album.owner_id = ? " .
"order by Sheela_gallery_image.created desc " .
"limit 2");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("i", $user["id"]);
$statement->execute();
?><ul class="thumbnails"><?php
foreach ($statement->get_result() as $row) {
?><li>
<img src="thumbnails/<?=$row['hash']?>" title="<?=$row['name'];?>"/>
uploaded <?=$row['created'] ?> <?=$row["id"]?>
<?php
$statement = $conn->prepare(
"SELECT Sheela_gallery_user.display_name " .
"FROM Sheela_gallery_likes " .
"JOIN Sheela_gallery_user ON Sheela_gallery_likes.user_id = Sheela_gallery_user.id " .
"WHERE Sheela_gallery_likes.image_id = ?");
$statement->bind_param("i", $row["id"]);
$statement->execute();
$first = true; // First user shall not have comma prefixed
foreach ($statement->get_result() as $like) {
if (!$first) {
echo ", ";
}
echo $like["display_name"];
$first = false; // All other users have their nicknames comma prefixed
}
?>
like this
</li><?php
}
?></ul><?php
} else {
?>
<form method="post">
<input type="mail" name="email"/>
<input type="password" name="password"/>
<input type="submit" value="Log in!"/>
</form>
<?php
}
?>
<a href ="registration.php">Sign up</a>
<p>
<a href="upload.php">Upload Page </a>
<?php include "footer.php" ?>
LAURI-INDEX.PHP
<?php
include "header.php";
require_once "config.php";
$SQL_IMAGES = "
select
lauri_gallery_image.id,
lauri_gallery_image.hash,
lauri_gallery_image.created
from
lauri_gallery_image
join
lauri_gallery_album
on
lauri_gallery_album.id = lauri_gallery_image.album_id
where
lauri_gallery_album.owner_id = ?
order by
lauri_gallery_image.created desc
limit 2";
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error) die("Connection to database failed:" . $conn->connect_error);
// Here we check if user is attempting to log in
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$statement = $conn->prepare(
"select * from lauri_gallery_user where email = ? and " .
"password_hash = SHA1(CONCAT(password_salt, ?))");
$statement->bind_param("ss", $_POST["email"], $_POST["password"]);
$statement->execute();
$results = $statement->get_result();
$row = $results->fetch_assoc();
if (!$row)
echo "Login failed!";
$_SESSION["user"] = $row; // Set user as logged in
}
// Here we check if the user is logged in
if ($user = @$_SESSION["user"]) { // Extra lazy hack, use $user instead of $_SESSION["user"] from now on
?>
<h1>Hello <?=$user["display_name"];?></h1>
<p>
Add albums <a href="addalbum.php">here</a>.
Upload images <a href="upload.php">here</a>.
</p>
My albums:
<?php
// Here we list user's albums
$statement = $conn->prepare("select * from lauri_gallery_album where owner_id = ?");
$statement->bind_param("i", $user["id"]);
$statement->execute();
?><ul><?php
foreach ($statement->get_result() as $row) {
?><li><a href="album.php?id=<?=$row['id']?>"><?=$row['name'];?></a>
<a href="deletealbum.php?id=<?=$row['id']?>">[Delete]</a>
</li><?php
}
?></ul>
My uploads:
<?php
// To show images of the user
$statement = $conn->prepare($SQL_IMAGES);
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("i", $user["id"]);
$statement->execute();
?><ul class="thumbnails"><?php
foreach ($statement->get_result() as $row) {
?><li>
<img src="thumbnails/<?=$row['hash']?>" title="<?=$row['name'];?>"/>
uploaded <?=$row['created'] ?>
<div id="likes_<?=$row["id"]?>">
<?php
require_once "common.php";
show_likes($row["id"]); // show_likes function is defined in common.php
?>
like this
</div>
</li><?php
}
?></ul><?php
} else {
?>
<form method="post">
<input type="mail" name="email"/>
<input type="password" name="password"/>
<input type="submit" value="Log in!"/>
</form>
<?php
}
?>
ADDALBUM.PHP
<?php
include "header.php";
require_once "config.php";
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$statement = $conn->prepare(
"insert into Sheela_gallery_album(name, owner_id) values(?,?)");
$statement->bind_param("si", $_POST["album_name"], $_SESSION["user"]["id"]);
$statement->execute();
}
?>
<form method="post">
<p>Here you can create a new album, it's basically a group of images that are to be uploaded</p>
<label>Enter album name</label>
<input type="text" name="album_name"/>
<input type="submit"/>
</form>
LAURI-ADDALBUM.PHP
<?php
include "header.php";
require_once "config.php";
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$statement = $conn->prepare(
"insert into lauri_gallery_album(name, owner_id) values(?,?)");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error); // check all the errors!
$statement->bind_param("si", $_POST["album_name"], $_SESSION["user"]["id"]);
if (!$statement->execute()) die("Execute failed (" . $conn->errno . ") " . $conn->error); // check all the errors!
header("Location: album.php?id=" . mysqli_insert_id($conn)); // This will redirect to newly created album page
}
?>
<form method="post">
<p>Here you can create a new album, it's basically a group of images that are to be uploaded</p>
<label>Enter album name</label>
<input type="text" name="album_name"/>
<input type="submit"/>
</form>
ALBUM.PHP
<?php
include "header.php";
require_once "config.php";
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error) die("Connection to database failed:" . $conn->connect_error);
?>
Back to landing page <a href="index.php">here</a>.
Upload images <a href="upload.php">here</a>
Images of album:
ss<?php
// To show images of the album
$statement = $conn->prepare(
"select Sheela_gallery_image.hash, Sheela_gallery_image.created " .
"from Sheela_gallery_image " .
"where Sheela_gallery_image.album_id = ? " .
"order by Sheela_gallery_image.created desc");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("i", $_GET["id"]);
$statement->execute();
?><ul><?php
foreach ($statement->get_result() as $row) {
?><li><img src="thumbnails/<?=$row['hash']?>"
title="<?=$row['name'];?>"/> uploaded <?=$row['created']?></li><?php
}
?></ul>
LAURI-ALBUM.PHP
<?php
include "header.php";
require_once "config.php";
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error) die("Connection to database failed:" . $conn->connect_error);
?>
Back to landing page <a href="index.php">here</a>.
Upload images <a href="upload.php">here</a>
Images of album:
<?php
// To show images of the album
$statement = $conn->prepare(
"select lauri_gallery_image.hash, lauri_gallery_image.created " .
"from lauri_gallery_image " .
"where lauri_gallery_image.album_id = ? " .
"order by lauri_gallery_image.created desc");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("i", $_GET["id"]);
$statement->execute();
?><ul><?php
foreach ($statement->get_result() as $row) {
?><li><img src="thumbnails/<?=$row['hash']?>"
title="<?=$row['name'];?>"/> uploaded <?=$row['created']?></li><?php
}
?></ul>
COMMOM.PHP
<?php
function show_likes($image_id) {
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error) die("Connection to database failed:" . $conn->connect_error);
$statement = $conn->prepare("
select id
from Sheela_gallery_like
where image_id = ? and user_id = ?");
$statement->bind_param("ii", $image_id, $_SESSION["user"]["id"]);
$statement->execute();
$result = $statement->get_result(); // Consume the results of the executed query
// Here we will check if user already likes this image
if ( $result->fetch_array() ) {
// we got a row -> user already likes this image
echo '<button onClick="unlike(' . $image_id . ');">Unlike!</button>';
} else {
// or if no rows -> user hasn't liked it yet
echo '<button onClick="like(' . $image_id . ');">Like!</button>';
}
$statement = $conn->prepare(
"SELECT Sheela_gallery_user.display_name " .
"FROM Sheela_gallery_like " .
"JOIN Sheela_gallery_user ON Sheela_gallery_like.user_id = Sheela_gallery_user.id " .
"WHERE Sheela_gallery_like.image_id = ?");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("i", $image_id);
$statement->execute();
$first = true; // First user shall not have comma prefixed
foreach ($statement->get_result() as $like) {
if (!$first) {
echo ", ";
}
echo $like["display_name"];
$first = false; // All other users have their nicknames comma prefixed
}
};
?>
LAURI-COMMON.PHP
<?php
function show_likes($image_id) {
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error) die("Connection to database failed:" . $conn->connect_error);
$statement = $conn->prepare("
select id
from lauri_gallery_like
where image_id = ? and user_id = ?");
$statement->bind_param("ii", $image_id, $_SESSION["user"]["id"]);
$statement->execute();
$result = $statement->get_result(); // Consume the results of the executed query
// Here we will check if user already likes this image
if ( $result->fetch_array() ) {
// we got a row -> user already likes this image
echo '<button onClick="unlike(' . $image_id . ');">Unlike!</button>';
} else {
// or if no rows -> user hasn't liked it yet
echo '<button onClick="like(' . $image_id . ');">Like!</button>';
}
$statement = $conn->prepare(
"SELECT lauri_gallery_user.display_name " .
"FROM lauri_gallery_like " .
"JOIN lauri_gallery_user ON lauri_gallery_like.user_id = lauri_gallery_user.id " .
"WHERE lauri_gallery_like.image_id = ?");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("i", $image_id);
$statement->execute();
$first = true; // First user shall not have comma prefixed
foreach ($statement->get_result() as $like) {
if (!$first) {
echo ", ";
}
echo $like["display_name"];
$first = false; // All other users have their nicknames comma prefixed
}
};
?>
CONFIG.PHP
<?php
// This is site specific configuration! Do not commit this to Git!
define("DB_SERVER", "localhost");
define("DB_USER", "test");
define("DB_PASS", "t3st3r123");
define("DB_NAME", "test");
define("DB_PREFIX", "Sheela_");
?>
DELETEALBUM.PHP
<?php
include "header.php";
require_once "config.php";
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
$statement = $conn->prepare(
"delete from Sheela_gallery_album where id = ?");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error); // check all the errors!
$statement->bind_param("i", $_GET["id"]);
if (!$statement->execute()) die("Execute failed (" . $conn->errno . ") " . $conn->error); // check all the errors!
header("Location: index.php");
FOOTER.PHP
</div>
<footer>
<ul>
<li>Phone: +372 1234 4567</li>
<li><a href="http://facebook.com">Visit us on Facebook!</a></li>
</ul>
</footer>
</body>
</html>
HEADER.PHP
<?php
session_set_cookie_params(0, '/~ssumathi', 'enos.itcollege.ee', 0, 1);
session_start();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="description" content="Introduction to this Image_Gallery">
<title>This goes into the titlebar</title>
<link type="text/css" rel="stylesheet" href="css/style.css"/>
<script type="text/javascript"src="js/main.js"></script>
</head>
<body>
<div id ="content">
LIKE.PHP
<?php
// like.php?image_id=123 will attempt to add like to an image for currenty logged in user
session_start();
require_once "config.php";
require_once "common.php";
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error) die("Connection to database failed:" . $conn->connect_error);
$statement = $conn->prepare("
insert into Sheela_gallery_like (image_id, user_id)
values (?, ?)");
$statement->bind_param("ii", $_GET["image_id"], $_SESSION["user"]["id"]);
$statement->execute();
show_likes($_GET["image_id"]); // This will simply return a fragment of HTML
?>
LOGOUT.PHP
<?php
session_start();
session_destroy();
unset($_SESSION["user"]);
header('Location: index.php'); // This will redirect back to index
REGISTRATION.PHP
<?php
require_once "config.php";
include "header.php";
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
$statement = $conn->prepare(
"INSERT INTO `Sheela_gallery_user` (`email`, `password_salt`, `password_hash`, `display_name`) " .
"VALUES (?, ?, ?, ?)");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$salt = substr(str_shuffle(
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
$statement->bind_param("ssss",
$_POST["email"],
$salt,
sha1($salt . $_POST["password"]),
$_POST["display_name"]);
if ($statement->execute()) {
header("Location: index.php");
} else {
if ($statement->errno == 1062) {
echo "This e-mail is already registered";
} else {
die("Execute failed: (" . $statement->errno . ") " . $statement->error);
}
}
}
?>
<form method="post"><!-- This form is submitted to the same reg.php file with POST method -->
<ul>
<li>e-mail: <input type="mail" name="email" value="<?=@$_POST['email'];?>" required/></li>
<li>password: <input type="password" name="password" pattern="[a-zA-Z0-9]{8,16}" title="Password has to be at least 8 characters" required/></li>
<li>nickname: <input type="text" name="display_name" placeholder="cute honeybunny" pattern="[a-z]{3,10}" required/></li>
</ul>
<input type="submit"/>
</form>
UPLOAD.PHP
<?php
include "header.php";
require_once "config.php";
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if (array_key_exists("uploaded_image", $_FILES)) {
if ($_FILES["uploaded_image"]["error"] == 1) die("Too big image!"); // File size check
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $_FILES["uploaded_image"]["tmp_name"]);
if (strpos($mimetype, "image/") != 0) // This is basically mimetype.startswith("image/")
die("Go away! Only images allowed!");
$checksum = sha1(file_get_contents(
$_FILES["uploaded_image"]["tmp_name"])) . "." .
pathinfo($_FILES["uploaded_image"]["name"], PATHINFO_EXTENSION);
// Keep the original image in uploads/ folder
if (!file_exists("uploads/" . $checksum)) {
copy(
$_FILES["uploaded_image"]["tmp_name"],
"uploads/" . $checksum);
}
// Generate thumbnail, this assumes you have created thumbnails/ folder and set permissions to 777
if (!file_exists("thumbnails/" . $checksum)) {
$im = new Imagick("uploads/" . $checksum);
$im->thumbnailImage(128, 0); // Width of 128px and automatically determine height based on aspect ratio
$im->writeImage("thumbnails/" . $checksum);
}
// Generate smaller version of the image
if (!file_exists("small/" . $checksum)) {
$im = new Imagick("uploads/" . $checksum);
$im->thumbnailImage(960, 0); // Width of 960px and automatically determined height
$im->writeImage("small/" . $checksum);
}
// TODO: Check that specified album is owned by the currently logged in user (SQL select query!)
// something like this, if you find a matching row the upload permission is granted:
// select * from Sheela_gallery_album where owner_id = $_SESSION["user]["id"] and id = $_POST['album_id']
// These four lines are the new stuff!
$statement = $conn->prepare("insert into `Sheela_gallery_image` (`album_id`, `name`, `hash`) values (?,?,?)");
$statement->bind_param("iss", $_POST["album_id"], $_FILES["uploaded_image"]["name"], $checksum);
$statement->execute();
?>
<p>Mimetype was: <?= $mimetype; ?></p>
<p>Original was: <a href="uploads/<?=$checksum;?>"><?=$checksum;?></a>
<p>960px was: <a href="small/<?=$checksum;?>"><?=$checksum;?></a>
<p>Thumbnail was: <a href="thumbnails/<?=$checksum;?>"><?=$checksum;?></a>
<p>Filename was: <?=$_FILES["uploaded_image"]["name"];?></p>
<p>File stored at: <?=$_FILES["uploaded_image"]["tmp_name"];?></p>
<?php
}
?>
<form method="post" enctype="multipart/form-data">
<select name="album_id">
<?php
$statement = $conn->prepare("select id, name from Sheela_gallery_album where owner_id = ?");
$statement->bind_param("i", $_SESSION["user"]["id"]);
$statement->execute();
foreach ($statement->get_result() as $row) {
?>
<option value="<?=$row['id']?>"><?=$row['name']?></option>
<?php
}
?>
</select>
Select file for upload: <input id="file" type="file" name="uploaded_image" accept="image/*">
<input type="submit"/>
</form>
UNLIKE.PHP
<?php
// unlike.php?image_id=123 will attempt to remove a like
session_start();
require_once "config.php";
require_once "common.php";
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error) die("Connection to database failed:" . $conn->connect_error);
$statement = $conn->prepare("
delete from lauri_gallery_like
where image_id = ? and user_id = ?
limit 1");
$statement->bind_param("ii", $_GET["image_id"], $_SESSION["user"]["id"]);
$statement->execute();
show_likes( $_GET["image_id"]);
?>
LAURI-MAIN.JS
function like(image_id) {
var request = new XMLHttpRequest();
request.open('GET', 'like.php?image_id=' + image_id, true);
// This is an example of callback
request.onload = function() {
// This function runs once response has been received
if (request.status >= 200 && request.status < 400) {
document.querySelector("#likes_" + image_id).innerHTML =
request.responseText;
}
};
// This will only start the request
request.send();
}
function unlike(image_id) {
var request = new XMLHttpRequest();
request.open('GET', 'unlike.php?image_id=' + image_id, true);
// This is an example of callback
request.onload = function() {
// This function runs once response has been received
if (request.status >= 200 && request.status < 400) {
document.querySelector("#likes_" + image_id).innerHTML =
request.responseText;
}
};
// This will only start the request
request.send();
}
CSS-STYLE.CSS
ul.thumbnails {
list-style: none;
}
ul#thumbnails li {
float: left;
display: block;
width: 160px;
WEB-SHOP
INDEX.PHP
<?php
require_once "config.php";
include "header.php"; // This includes <html><head></head><body>
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error)
die("Connection to database failed:" .
$conn->connect_error);
$conn->query("set names utf8"); // Support umlaut characters
if (!array_key_exists("timestamp", $_SESSION)) {
$_SESSION["timestamp"] = date('l jS \of F Y h:i:s A');
}
?>
<h1>Honest Lauri's webshop</h1>
<p>
<button id="update_cart">Update shopping cart now!</button>
<!-- We could actually move login and registration buttons to
separate nav.php file and include it here -->
<?php
if (array_key_exists("user", $_SESSION) and $_SESSION["user"]) {
// In case we put user id in the $_SESSION["user"] we need
// to perform another SQL query to get the full name of the user:
$results = $conn->query(
"SELECT * FROM lauri_users WHERE id = " . $_SESSION["user"]);
if (!$results) die("Query failed: (" . $conn->errno . ") " . $conn->error);
$row = $results->fetch_assoc();
echo "Hello " . $row["salutation"] . " ";
echo $row["first_name"] . " ";
echo $row["last_name"];
// Oh how I'd like to do just:
// print "Hello %(salutation)s %(first_name)s %(last_name)s" % $row
?> <a href="orders.php">My Orders</a> <a href="logout.php">Log out</a>
<?php
} else {
// Otherwise offer login fields and button
?>
<form action="login.php" method="post">
<input id="user" type="text" class="textboxes" name="user"/>
<input type="password" class="textboxes topsecret" name="password"/>
<input type="submit" value="Log in!"/>
</form><?php
} ?>
<button id="remove_button" data-product_id="1">Remove item</button>
<div id="shopping_cart">
This is initially empty
</div>
<a href="registration.php">Sign up!</a>. <a href="cart.php">Go to shopping cart</a>.</p>
<p class="topsecret">NSA is monitoring you since <?=$_SESSION["timestamp"];?></p>
<p>If you want any of these just call me ;)</p>
<ul>
<?php
$results = $conn->query(
"SELECT id,name,price FROM lauri_products;");
while ($row = $results->fetch_assoc()) {
?>
<li>
<a href="description.php?id=<?=$row['id']?>">
<?=$row['name']?></a>
<?=$row['price']?>EUR
</li>
<?php
}
$conn->close();
?>
</ul>
<?php include "footer.php" ?>
CART.PHP
<?php
require_once "config.php";
session_start();
//include "header.php"; // This includes <html><head></head><body>
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
$conn or die("Database connection failed:" . $conn->error);
$conn->query("set names utf8"); // Support umlaut characters
if ($_SERVER['REQUEST_METHOD'] == "POST") {
// We are updating the cart contents
$product_id = intval($_POST["id"]);
if (array_key_exists($product_id, $_SESSION["cart"])) {
$_SESSION["cart"][$product_id] += intval($_POST["count"]);
} else {
$_SESSION["cart"][$product_id] = intval($_POST["count"]);
}
if ($_SESSION["cart"][$product_id] <= 0) {
unset($_SESSION["cart"][$product_id]);
}
}
?>
<!--
<h2>Products in shopping cart</h2>
<a href="index.php">Back to product listing</a>
<a href="placeorder.php">Place order</a>
<p>
-->
<ul>
<?php
$results = $conn->query(
"SELECT id,name,price FROM lauri_products;");
$results or die("Database query failed:" . $conn->error);
while ($row = $results->fetch_assoc()) {
$product_id = $row['id'];
if (array_key_exists($product_id, $_SESSION["cart"])) {
$count = $_SESSION["cart"][$product_id];
?>
<li>
<?=$count;?> items of
<a href="description.php?id=<?=$product_id;?>">
<?=$row['name'];?></a>
<?=$row['price'];?>EUR totals in <?= $row['price'] * $count; ?> EUR
<form method="post">
<input type="hidden" name="id" value="<?=$product_id;?>"/>
<input type="hidden" name="count" value="-1"/>
<input type="submit" value="Remove"/>
</form>
</li>
<?php
}
}
$conn->close();
?>
</ul>
<?php // include "footer.php" ?>
CONFIG.PHP
<?php
// This is site specific configuration!
define("DB_SERVER", "localhost");
define("DB_USER", "test");
define("DB_PASS", "t3st3r123");
define("DB_NAME", "test");
define("DB_PREFIX", "lauri_");
?>
DESCRIPTION.PHP
<?php
require_once "config.php";
include "header.php" ?>
<a href="index.php">Back to product listing</a>
<?php
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error)
die("Connection to database failed:" .
$conn->connect_error);
$conn->query("set names utf8"); // Support umlaut characters
$statement = $conn->prepare(
"SELECT `name`, `description`, `price` FROM" .
" `lauri_products` WHERE `id` = ?");
$statement->bind_param("i", $_GET["id"]);
$statement->execute();
$results = $statement->get_result();
$row = $results->fetch_assoc();
?>
<span style="float:right;"><?=$row["price"];?>EUR</span>
<h1><?=$row["name"];?></h1>
<p>
<?=$row["description"];?>
</p>
<form method="post" action="cart.php">
<input type="hidden" name="id" value="<?=$_GET["id"];?>"/>
<input type="hidden" name="count" value="1"/>
<input type="submit" value="Add to cart"/>
</form>
<?php include "footer.php" ?>
FOOTER.PHP
</div>
<footer>
<ul>
<li>Phone: +372 5123 4567</li>
<li><a href="http://facebook.com">Visit us on Facebook!</a></li>
</ul>
</footer>
</body>
</html>
HEADER.PHP
<?php
// This will make it possible to use persistent $_SESSION at all
session_start();
if (!array_key_exists("cart", $_SESSION)) {
$_SESSION["cart"] = array();
// Here we store product it -> count mapping
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="description" content="Introduction to this guy's website">
<title>Lauri's webshop</title>
<link type="text/css" rel="stylesheet" href="css/style.css"/>
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
<script type="text/javascript" src="js/main.js"></script>
</head>
<body>
<div id="content">
LOGIN.PHP
<?php
session_start();
// This is login.php, here we check if user provided proper credentials
var_dump($_POST); // This is just to check that the data gets to server
include "config.php";
// This is copy-paste from description.php!
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error)
die("Connection to database failed:" .
$conn->connect_error);
$conn->query("set names utf8"); // Support umlaut characters
$statement = $conn->prepare(
"SELECT id, first_name FROM lauri_users
WHERE email = ? AND password = PASSWORD(?)");
// This is the easiest way to store hashed passwords
// DO NOT USE THIS IN PRODUCTION!
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("ss", $_POST["user"], $_POST["password"]); // <--
$statement->execute();
$results = $statement->get_result();
$row = $results->fetch_assoc();
if($row) {
$_SESSION["first_name"] = $row["first_name"]; // For lazy people
$_SESSION["user"] = $row["id"]; // This just stores user row number!
header('Location: index.php'); // This will redirect back to index
} else {
echo "Login failed (invalid username or password)";
}
?>
LOGOUT.PHP
<?php
session_start();
unset($_SESSION["user"]);
header('Location: index.php'); // This will redirect back to index
?>
ORDERDETAILS.PHP
<?php
require_once "config.php";
include "header.php" ?>
<a href="index.php">Back to product listing</a>
<?php
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error)
die("Connection to database failed:" .
$conn->connect_error);
$conn->query("set names utf8"); // Support umlaut characters
$statement = $conn->prepare(
"SELECT
`lauri_order_products`.`id` AS `order_product_id`,
`lauri_order_products`.`product_id` AS `product_id`,
`lauri_products`.`name` AS `product_name`,
`lauri_order_products`.`unit_price` AS `order_product_unit_price`,
`lauri_order_products`.`count` AS `order_product_count`,
`lauri_order_products`.`unit_price` * `lauri_order_products`.`count` AS `subtotal`
FROM
`lauri_order_products`
JOIN
`lauri_products`
ON
`lauri_order_products`.`product_id` = `lauri_products`.`id`
WHERE
`lauri_order_products`.`order_id` = ?
");
// This is orderdetail.php
// The SQL code above is copy-paste from wiki, PHP code above is copy-paste from description.php
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("i", $_GET["id"]); // TODO: Check that order belongs to $_SESSION["user"] !!!
$statement->execute();
$results = $statement->get_result();
?>
<h1>Order details</h1>
<ul>
<?php
while ($row = $results->fetch_assoc()) { ?>
<li>
<?= $row["product_name"]; ?>
<?= $row["order_product_count"]; ?>x
<?= $row["order_product_unit_price"]; ?>EUR
</li><?php
}
?>
ORDERS.PHP
<?php
require_once "config.php";
include "header.php" ?>
<a href="index.php">Back to product listing</a>
<?php
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error)
die("Connection to database failed:" . $conn->connect_error);
$conn->query("set names utf8");
// This is orders.php, again beginning copy-pasted from description.php
$statement = $conn->prepare("SELECT * FROM `lauri_orders` WHERE `user_id` = ?");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
// TODO: If $_SESSION["user"] is nonsense, redirect to index.php!
$statement->bind_param("i", $_SESSION["user"]);
if (!$statement->execute()) die("Failed to execute statement");
$results = $statement->get_result();
?>
<h1>Orders</h1>
<ul>
<?php
while ($row = $results->fetch_assoc()) { ?>
<li>
<a href="orderdetail.php?id=<?= $row["id"]; ?>">
Order #<?= $row["id"]; ?>
<?= $row["created"]; ?>
<?= $row["shipping_address"]; ?>
</a>
</li><?php
}
?>
PLACRORDER.PHP
<?php
// This is placeorder.php, this shall basically move cart contents to database as a new order
// Copypaste from regsubmit.php follows:
require_once "config.php";
include "header.php";
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error)
die("Connection to database failed:" .
$conn->connect_error);
$conn->query("set names utf8"); // Support umlaut characters
// TODO: If the shopping cart is empty it should not be possible to place an order!
$_SESSION["cart"] or die("User has no items in the shopping cart!");
// This inserts row to orders table
$statement = $conn->prepare("INSERT INTO `lauri_orders` (`user_id`) VALUES (?)");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("i", $_SESSION["user"]); // User ID is the logged in user's ID
if (!$statement->execute()) {
die("Execute failed: (" . $statement->errno . ") " . $statement->error);
}
$order_id = $conn->insert_id; // This contains the ID for the inserted order
// This inserts rows to order_products table
$statement = $conn->prepare(
"INSERT INTO `lauri_order_products` (`order_id`, `product_id`, `count`) VALUES (?,?,?)");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
foreach ($_SESSION["cart"] as $product_id => $count) {
$statement->bind_param("iii", $order_id, $product_id, $count);
if (!$statement->execute()) {
die("Execute failed: (" . $statement->errno . ") " . $statement->error);
}
}
// Here of course we should reset shopping cart:
$_SESSION["cart"] = array();
header('Location: orders.php'); // This should redirect to orders page (which we haven't created yet)
?>
REGISTRATION.PHP
<?php
require_once "config.php";
include "header.php";
?>
<h1>Register user account</h1>
<form method="post" action="regsubmit.php">
<div>
<label for="email">E-mail</label>
<input type="email" name="email" required/>
</div>
<div>
<label for="password">Password</label>
<input type="password" name="password" required/>
</div>
<div>
<select name="country">
<option value="ee">Estonia</option>
<option value="lt">Latvia</option>
<option value="lv">Lithuania</option>
</select>
</div>
<div>
<label for="phone">Telephone number</label>
<input type="tel"/>
</div>
<div>
<label for="vatin">VAT indication number</label>
<input type="text" pattern="([A-Z0-9]{4,14})?$"/>
</div>
<div>
<label for="dob">Date of birth</label>
<input type="date" name="dob" placeholder="dd/mm/yyyy" required/>
</div>
<div>
<label for="first_name">First name</label>
<input type="text" name="first_name" required/>
</div>
<div>
<label for="last_name">Last name</label>
<input type="text" name="last_name" required/>
</div>
<div>
<input type="submit"/>
</div>
</form>
<?php include "footer.php" ?>
REGSUBMIT.PHP
<?php
require_once "config.php";
include "header.php";
$conn = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error)
die("Connection to database failed:" .
$conn->connect_error);
$conn->query("set names utf8");
$statement = $conn->prepare(
"INSERT INTO `lauri_users` (
`email`,
`password`,
`first_name`,
`last_name`,
`phone`,
`dob`,
`salutation`,
`vatin`,
`company`,
`country`,
`address`)
VALUES (?, PASSWORD(?), ?, ?, ?, ?, ?, ?, ?, ?, ?)");
# whenever you get "call to a member function ... on a non-object" this means something
# is failing **before** that line so you have to manually check for errors like this:
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("sssssssssss",
$_POST["email"],
$_POST["password"],
$_POST["first_name"],
$_POST["last_name"],
$_POST["phone"],
$_POST["dob"],
$_POST["salutation"],
$_POST["vatin"],
$_POST["company"],
$_POST["country"],
$_POST["address"]);
if ($statement->execute()) {
echo "Registration was successful! <a href=\"index.php\">Back to main page</a>";
} else {
if ($statement->errno == 1062) {
// This will result in 200 OK
echo "This e-mail is already registered";
} else {
// This will result in 500 Internal server error
die("Execute failed: (" .
$statement->errno . ") " . $statement->error);
}
}
?>
UPLOAD.PHP
<html>
<body>
<form method="post" enctype="multipart/form-data">
<input type="text" name="product_title"/>
<input type="text" name="product_description"/>
<input type="file" name="product_image" required/>
<input type="file" name="product_thumbnail"/>
<input type="submit"/>
</form>
<!-- You also need:
mkdir uploads
chmod 777
-->
<?php
if (array_key_exists("product_image", $_FILES)) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $_FILES["product_image"]["tmp_name"]);
if ($mimetype != "application/pdf") die("Go away!");
$checksum = sha1(file_get_contents(
$_FILES["product_image"]["tmp_name"])) . "." .
pathinfo($_FILES["product_image"]["name"], PATHINFO_EXTENSION);
if (!file_exists("uploads/" . $checksum)) {
copy(
$_FILES["product_image"]["tmp_name"],
"uploads/" . $checksum);
}
}
?>
<p>Mimetype was: <?= $mimetype; ?></p>
<p>Checksum was: <a href="uploads/<?=$checksum;?>"><?=$checksum;?></a>
<p>Filename was: <?=$_FILES["product_image"]["name"];?></p>
<p>File stored at: <?=$_FILES["product_image"]["tmp_name"];?></p>
</body>
</html>
STYLE.CSS
input[type='password'] {
color: red;
}
/* Apply font family to paragraphs */
p, ul, li, h1, h2, h, a {
/* Roboto font works only if the font CSS is included from Google */
font-family: "Roboto", Verdana, Arial, sans-serif;
}
html, body {
margin: 0;
padding: 0;
}
body {
padding: 0 1em;
background-color: #aabbff;
}
#content, footer { /* This expects id="content" ;) */
margin: 0 auto;
padding: 0 1em;
max-width: 40em;
border: 1px solid #888;
background-color: white;
}
footer {
color: #fff;
background-color: #222;
}
img { /* This will look ugly tho! */
width: 800px;
height: 100px;
}
MAIN.JS
// In HTML we only have <button id="update_cart">Update cart</button>
// Wait page to be loaded and then associate click event
document.addEventListener("DOMContentLoaded", function() {
document.querySelector("#update_cart").addEventListener(
"click", updateCart
);
document.querySelector("#remove_button").addEventListener(
"click", removeItem
)
});
function removeItem() {
console.info("Going to remove product with id from cart:", this.dataset.product_id);
var formData = new FormData();
formData.append("id", this.dataset.product_id);
formData.append("count", -1);
var request = new XMLHttpRequest();
request.open('POST', 'cart.php', true);
request.send(formData);
}
// This only defines updateCart function, but it does not run it!
function updateCart() {
var request = new XMLHttpRequest();
request.open('GET', 'cart.php', true);
// This is an example of callback
request.onload = function() {
// This function runs once response has been received
if (request.status >= 200 && request.status < 400) {
document.querySelector("#shopping_cart").innerHTML =
request.responseText;
}
};
// This will only start the request
request.send();
}