Web Exam help

From ICO wiki
Jump to navigationJump to search

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();
}