Basic E-commerce site development part-1

In this tutorial, we will learn the way to design the basic database of a simple e-commerce site and create the structure of the file to connect with the database and design the basic front page.

Steps:

1. Create a database named ecommerce and run the following SQL statements to create the required tables.

CREATE TABLE `categories` (
`id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
`category` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `category_UNIQUE` (`category` ASC) )
ENGINE = InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `pages` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`categories_id` SMALLINT UNSIGNED NOT NULL,
`title` VARCHAR(100) NOT NULL,
`description` TINYTEXT NOT NULL,
`content` LONGTEXT NULL,
`date_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `date_created` (`date_created` ASC),
INDEX `fk_pages_categories_idx` (`categories_id` ASC),
CONSTRAINT `fk_pages_categories`
FOREIGN KEY (`categories_id`) REFERENCES `categories` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION )
ENGINE = InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `pdfs` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`title` VARCHAR(100) NOT NULL,
`description` TINYTEXT NOT NULL,
`tmp_name` CHAR(63) NOT NULL,
`file_name` VARCHAR(100) NOT NULL,
`size` MEDIUMINT UNSIGNED NOT NULL,
`date_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE INDEX `tmp_name_UNIQUE` (`tmp_name` ASC),
INDEX `date_created` (`date_created` ASC) )
ENGINE = InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `users` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`type` ENUM('member','admin') NOT NULL DEFAULT 'member',
`username` VARCHAR(45) NOT NULL,
`email` VARCHAR(80) NOT NULL,
`pass` VARCHAR(255) NOT NULL,
`first_name` VARCHAR(45) NOT NULL,
`last_name` VARCHAR(45) NOT NULL,
`date_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`date_expires` DATE NOT NULL,
`date_modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`),
UNIQUE INDEX `username_UNIQUE` (`username` ASC),
UNIQUE INDEX `email_UNIQUE` (`email` ASC),
INDEX `login` (`email` ASC, `pass` ASC) )
ENGINE = InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `orders` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`users_id` INT UNSIGNED NOT NULL,
`transaction_id` VARCHAR(45) NOT NULL,
`payment_status` VARCHAR(45) NOT NULL,
`payment_amount` INT UNSIGNED NOT NULL,
`date_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `date_created` (`date_created` ASC),
INDEX `transaction_id` (`transaction_id` ASC),
CONSTRAINT `fk_orders_users1` FOREIGN KEY (`id`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION )
ENGINE = InnoDB DEFAULT CHARSET=utf8;

2. Create a folder named webclass-1 and a file named db_connection.php with the following content.

<?php
// Set the database access information as constants:
DEFINE ('DB_USER', 'root');
DEFINE ('DB_PASSWORD', '');
DEFINE ('DB_HOST', 'localhost');
DEFINE ('DB_NAME', 'ecommerce');


// Make the connection:
$dbc = mysqli_connect (DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
// Set the character set:
mysqli_set_charset($dbc, 'utf8');

// Function for escaping and trimming form data.
// Takes one argument: the data to be treated (string).
// Returns the treated data (string).

function escape_data ($data, $dbc) {

	// Strip the slashes if Magic Quotes is on:
	if (get_magic_quotes_gpc()) $data = stripslashes($data);
	// Apply trim() and mysqli_real_escape_string():
	return mysqli_real_escape_string ($dbc, trim ($data));
} 

3. Create html and pdfs folders inside the htdocs folder.
4. Create css, js, images, includes and ajax folder inside html folder.
5. Create config.php, header.php, footer.html, login.php, login_form.php, form_functions.php and index.html inside includes folder.
6. Add the following files inside css folder.

bootstrap.min.css

 

sticky-footer-navbar.css

7. Add the following file inside js folder.

bootstrap.min.js

8. Add the following content in config.php file.

<?php
if (!defined('LIVE')) DEFINE('LIVE', false);
// Errors are emailed here:
DEFINE('CONTACT_EMAIL', 'you@example.com');


// ************ CONSTANTS *********** //
// Determine location of files and the URL of the site:
define ('BASE_URI', '../');
define ('BASE_URL', 'localhost/webclass-1/html/');
define ('PDFS_DIR', BASE_URI . 'pdfs/'); // Added in Chapter 5.
define ('MYSQL', BASE_URI . 'db_connection.php');

// Start the session:
session_start();

function my_error_handler($e_number, $e_message, $e_file, $e_line, $e_vars) {

	// Build the error message:
	$message = "An error occurred in script '$e_file' on line $e_line:\n$e_message\n";
	// Add the backtrace:
	$message .= "<pre>" .print_r(debug_backtrace(), 1) . "</pre>\n";
	// Or just append $e_vars to the message:
	// $message .= "<pre>" . print_r ($e_vars, 1) . "</pre>\n";
	if (!LIVE) { // Show the error in the browser.
		echo '<div class="alert alert-danger">' . nl2br($message) . '</div>';
	}
	else { // Development (print the error).
		// Send the error in an email:
		error_log ($message, 1, CONTACT_EMAIL, 'From:admin@example.com');

		// Only print an error message in the browser, if the error isn't a notice:
		if ($e_number != E_NOTICE) {
			echo '<div class="alert alert-danger">A system error occurred. We apologize for the inconvenience.</div>';
		}

	} // End of $live IF-ELSE.
	return true; // So that PHP doesn't try to handle the error, too.

} // End of my_error_handler() definition.

set_error_handler('my_error_handler');

// ************ REDIRECT FUNCTION ************ //
function redirect_invalid_user($check = 'user_id', $destination = 'index.php', $protocol = 'http://') {

	// Check for the session item:
	if (!isset($_SESSION[$check])) {
		$url = $protocol . BASE_URL . $destination; // Define the URL.
		header("Location: $url");
		exit(); // Quit the script.
	}
} 
?>

9. Create template.php file inside html folder with the following script.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<title><?php 

if (isset($page_title)) {
echo $page_title;
} else {
echo 'Knowledge is Power: And It Pays to Know';
}

?></title>

<!-- Bootstrap core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="css/sticky-footer-navbar.css" rel="stylesheet">
</head>
<body>
<!-- Wrap all page content here -->
<div id="wrap">
<!-- Fixed navbar -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Knowledge is power</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contact</a>
</li>

<li class="nav-item">
<a class="nav-link" href="#">Register</a>
</li>

<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Account
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="logout.php">Logout</a></li>
<li><a class="dropdown-item" href="renew.php">Renew</a></li>
<li><a class="dropdown-item" href="change_password.php">Change Password</a></li>
<li><a class="dropdown-item" href="favorites.php">Favorites</a></li>
<li><a class="dropdown-item" href="recommendations.php">Recommendations</a></li>
</ul>
</li>

<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Admin
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="add_page.php">Add Page</a></li>
<li><a class="dropdown-item" href="add_pdf.php">Add PDF</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
</ul>

<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav>
<!-- Begin page content -->
<div class="container">
<div class="row">
<div class="col-3">
<h3 class="text-success">Content</h3>
<div class="list-group">
<a href="category.php?id=3" class="list-group-item"><span class="badge">7</span>Common Attacks
</a>
<a href="category.php?id=5" class="list-group-item"><span class="badge">11</span>Database Security
</a>
<a href="category.php?id=1" class="list-group-item"><span class="badge">9</span>General Web Security
</a>
<a href="category.php?id=4" class="list-group-item"><span class="badge">3</span>JavaScript Security
</a>
<a href="category.php?id=2" class="list-group-item"><span class="badge">2</span>PHP Security
</a>
<a href="pdfs.php" class="list-group-item"><span class="badge">5</span>PDF Guides
</a>
</div><!--/list-group-->
<form>
<fieldset>
<legend>Login</legend>
<div class="mb-3">
<label for="exampleInputEmail1" class="form-label">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">

</div>
<div class="mb-3">
<label for="exampleInputPassword1" class="form-label">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1">
</div>

<button type="submit" class="btn btn-primary">login</button>
</fieldset>
</form> 

</div><!--/col-3-->
<div class="col-9">
<h1>Welcome</h1>
<p class="lead">Welcome to Knowledge is Power, a site dedicated to keeping you up-to-date on the Web security and programming information you need to know. Blah, blah, blah. Yadda, yadda, yadda.</p>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent consectetur volutpat nunc, eget vulputate quam tristique sit amet. Donec suscipit mollis erat in egestas. Morbi id risus quam. Sed vitae erat eu tortor tempus consequat. Morbi quam massa, viverra sed ullamcorper sit amet, ultrices ullamcorper eros. Mauris ultricies rhoncus leo, ac vehicula sem condimentum vel. Morbi varius rutrum laoreet. Maecenas vitae turpis turpis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce leo turpis, faucibus et consequat eget, adipiscing ut turpis. Donec lacinia sodales nulla nec pellentesque. Fusce fringilla dictum purus in imperdiet. Vivamus at nulla diam, sagittis rutrum diam. Integer porta imperdiet euismod.</p>

</div><!--/col-9-->
</div><!--/row-->
</div><!--/container-->
</div><!--/wrap-->

<div id="footer">
<div class="container">
<p class="text-muted credit"><span class="pull-left"><a href="site_map.php">Site Map</a> | <a href="policies.php">Policies</a></span> <span class="pull-right">&copy; Knowledge is Power - 2021</span></p>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</body>
</html>

10. Add the following content in the header.php file.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<title><?php // Use a default page title if one wasn't provided...
if (isset($page_title)) {
echo $page_title;
} else {
echo 'Knowledge is Power: And It Pays to Know';
}
?></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- Bootstrap core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="css/sticky-footer-navbar.css" rel="stylesheet">
</head>
<body>
<!-- Fixed navbar -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Knowledge is power</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<?php // Dynamically create header menus...

// Array of labels and pages (without extensions):
$pages = array (
'Home' => 'index.php',
'About' => '#',
'Contact' => '#',
'Register' => 'register.php'
);

// The page being viewed:
$this_page = basename($_SERVER['PHP_SELF']);
// Create each menu item:
foreach ($pages as $k => $v) {
// Start the item:
echo '<li class="nav-item" ';
// Add the class if it's the current page:
if ($this_page == $v) echo ' class="active"';
// Complete the item:
echo '><a class="nav-link active" aria-current="page" href="' . $v . '">' . $k . '</a></li>
';

} // End of FOREACH loop.

// Show the user options:
if (isset($_SESSION['user_id'])) {
// Show basic user options:
// Includes references to some bonus material discussed in Part Four!
echo ' <li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Account
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="logout.php">Logout</a></li>
<li><a class="dropdown-item" href="renew.php">Renew</a></li>
<li><a class="dropdown-item" href="change_password.php">Change Password</a></li>
<li><a class="dropdown-item" href="favorites.php">Favorites</a></li>
<li><a class="dropdown-item" href="recommendations.php">Recommendations</a></li>
</ul>
</li>';
// Show admin options, if appropriate:
if (isset($_SESSION['user_admin'])) {
echo '<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Admin
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="add_page.php">Add Page</a></li>
<li><a class="dropdown-item" href="add_pdf.php">Add PDF</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>';
}

} 
?>

</ul>
</div><!--/.nav-collapse -->
</div><!--/container-->
</nav><!--/navbar-->
<!-- Begin page content -->
<div class="container">
<div class="row">
<div class="col-3">
<h3 class="text-success">Content</h3>
<div class="list-group">
<?php // Dynamically generate the content links:
$q = 'SELECT * FROM categories ORDER BY category';
$r = mysqli_query($dbc, $q);
while (list($id, $category) = mysqli_fetch_array($r, MYSQLI_NUM)) {
echo '<a href="category.php?id=' . $id . '" class="list-group-item" title="' . $category . '">' . htmlspecialchars($category) . '
</a>';
}
?>
<a href="pdfs.php" class="list-group-item" title="PDFs">PDF Guides
</a>
</div><!--/list-group-->
<?php // Should we show the login form?
if (!isset($_SESSION['user_id'])) {
require('includes/login_form.php');
}

?>
</div><!--/col-3-->
<div class="col-9">
<!-- CONTENT -->

11. Add the following content into footer.html.

<!-- END CONTENT -->
</div><!--/col-9-->
</div><!--/row-->
</div><!--/container-->
</div><!--/wrap-->
<div id="footer">

<div class="container">

<p class="text-muted credit"><span class="pull-left"><a href="site_map.php">Site Map</a> | <a href="policies.php">Policies</a></span> <span class="pull-right">&copy; Knowledge is Power - 2021</span></p>

</div>
</div>
<script src="js/bootstrap.min.js"></script>
</body>
</html>

12. Create index.php file inside html folder and add the following content in the file.

<?php
require('./includes/config.php');
// The config file also starts the session.
// To test the sidebars:
$_SESSION['user_id'] = 1;
$_SESSION['user_admin'] = true;
$_SESSION['user_not_expired'] = true;
//$_SESSION=array();
// Require the database connection:
require(MYSQL);
// If it's a POST request, handle the login attempt:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
include('./includes/login.php');
}
// Include the header file:
include('./includes/header.php');
/* PAGE CONTENT STARTS HERE! */
?><h1>Welcome</h1>
<p class="lead">Welcome to Knowledge is Power, a site dedicated to keeping you up-to-date on the Web security and programming information you need to know. Blah, blah, blah. Yadda, yadda, yadda.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent consectetur volutpat nunc, eget vulputate quam tristique sit amet. Donec suscipit mollis erat in egestas. Morbi id risus quam. Sed vitae erat eu tortor tempus consequat. Morbi quam massa, viverra sed ullamcorper sit amet, ultrices ullamcorper eros. Mauris ultricies rhoncus leo, ac vehicula sem condimentum vel. Morbi varius rutrum laoreet.</p>
<h3>Lorem Ipsum</h3>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent consectetur volutpat nunc, eget vulputate quam tristique sit amet. Donec suscipit mollis erat in egestas. Morbi id risus quam. Sed vitae erat eu tortor tempus consequat. Morbi quam massa, viverra sed ullamcorper sit amet, ultrices ullamcorper eros. Mauris ultricies rhoncus leo, ac vehicula sem condimentum vel. Morbi varius rutrum laoreet.</p>

<?php /* PAGE CONTENT ENDS HERE! */
// Include the footer file to complete the template:
include('./includes/footer.html');
?>

***Reference: Main code has taken from effortless e-commerce with PHP and MySQL book.