Hi, welcome to the third part of our tutorial on PHP CRUD. In this part I will be talking of the CREATE. We will discovering or rediscover how that works.
What is create?
In all cases applications are meant to treat/process data. No matter the data the application processes or no matter how it does it, there are some common points any application considers: the data input
phase, processing
phase, and an output
phase.
The input
phase consists of the application require some little information in order to give a given feed back. In the case of a website, we usually use forms to ask user to enter their details in order for our application to recognize them as member or other things. Once the application has this information, it has to store this data somewhere, either in a database, a file, in session, or in cookies, etc.
That action of saving the data is called the creation phase, or simply CREATE
. In our case here we will be saving our data into a database.
Now that you know what CREATE
means in CRUD, let see what we are going to do here. To demonstrate how that is done, I will be developing the option to add a new admin and a product in the database.
In order to accomplish that, I have done some changes to the admin menu which becomes:
<ul>
<li><a href="dashboard.php">Dashboard</a></li>
<li><a href="add-admin.php">Add Admin</a></li>
<li><a href="add-product.php">Add Product</a></li>
<li><a href="list-products.php">List Products</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
You can see here that for each aspect I have prepared a specific file to handle that. I made it this way just to show you step by step the difference between each action.
Add new admin
For this we're going to use the add-admin.php
file. We will also need the includes/classes/admin-class.php
file because it will contain some common functions to admins.
add-admin.php
is going to be at the root of the project. It will contain the form through which the admins can be input.
We have already seen in the previous part how our admin table
looks like. It's actually a very minimalistic one. Admins have just a username
and a password
.
So here are the source codes for each page:
add-admin.php
<?php
// Start from getting the hader which contains some settings we need
require_once 'includes/header.php';
// Redirect visitor to the login page if he is trying to access
// this page without being logged in
if (!isset($_SESSION['admin_session']) )
{
session::destroy('admin_session');
$commons->redirectTo(SITE_PATH.'index.php');
}
?>
<html>
<head>
<title>Products Management System | Admin Panel</title>
<link href='https://fonts.googleapis.com/css?family=Oswald:400,300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link rel="stylesheet" href="public/css/CreativeButtons/css/component.css">
<link rel="stylesheet" href="public/css/style.css">
</head>
<body>
<main class="container">
<a href="https://lancecourse.com/en/howto/make-your-first-crud-with-php-case-of-a-product-management-system/34" class="btn btn-4 btn-4d icon-arrow-left">Return to tutorial</a>
<div class="admin-pannel">
<div class="dashboard">
<h3>Add Admin</h3>
<hr>
<p>Please fill in the form bellow to add a new admin.</p>
<?php if ( isset($_SESSION['errors']) ): ?>
<div class="pannel panel-warning">
<?php foreach ($_SESSION['errors'] as $error):?>
<li><?= $error ?></li>
<?php endforeach ?>
</div>
<?php session::destroy('errors'); endif ?>
<?php if ( isset($_SESSION['confirm']) ): ?>
<div class="pannel panel-success">
<li><?= $_SESSION['confirm'] ?></li>
</div>
<?php session::destroy('confirm'); endif ?>
<!-- We send the form information to process-new-admin.php to handle it -->
<form action="process-new-admin.php" method="POST">
<div>
<label for="username">New Admin Username</label>
<input type="text" name="username" id="username">
</div>
<div>
<label for="password">New Admin Password</label>
<input type="password" name="password" id="password">
</div>
<div>
<label for="repassword">Re-enter Password</label>
<input type="password" name="repassword" id="repassword">
</div>
<div class="activate">
<button type="submit" class="btn-1a">Save Admin</button>
</div>
</form>
</div>
<aside class="admin-menu">
<p>Connected as, <?= strip_tags($_SESSION['admin_session']) ?></p>
<ul>
<li><a href="dashboard.php">Dashboard</a></li>
<li><a href="add-admin.php">Add Admin</a></li>
<li><a href="add-product.php">Add Product</a></li>
<li><a href="list-products.php">List Products</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</aside>
<div style="clear:both"> </div>
</div>
<footer>
<?= date("Y") ?> © lancecourse.com - Project by <a href="http://zooboole.me" target="_blank">zooboole</a> - Credit to <a href="http://tympanus.net/codrops/2013/06/13/creative-button-styles/" target="_blank">tympanus.net</a>
</footer>
</main>
</body>
</html>
process-new-admin.php
<?php
/*
* We process the admin login form here
*/
// Start from getting the hader which contains some settings we need
require_once 'includes/header.php';
// require the admins class which containes most functions applied to admins
require_once ROOT."../includes/classes/admin-class.php";
$admins = new Admins($dbh);
// check if the form is submitted
if (isset($_POST))
{
// If the form is submitted
// first we check if all fields are filled out
// In our case all fields are required, so we can just loop
$errors = array();
foreach($_POST as $key => $value)
{
if(empty($value) || trim($value) == '') {
$errors[$key] = "The field ".$key." should not be empty.";
}
$$key = $value;
}
// If there is any error we send back to the form
if (!empty($errors) || sizeof($errors) != 0)
{
session::set('errors', $errors);
$commons->redirectTo(SITE_PATH.'add-admin.php');
}
// Check if password are the same
if (!$admins->ArePasswordsSame($_POST['password'], $_POST['repassword']))
{
session::set('errors', ['The two passwords do not match.']);
$commons->redirectTo(SITE_PATH.'add-admin.php');
}
// From here you can unset the repassword field
// the password is in $_POST['password']
unset($_POST['repassword']);
// Now let's check if another admin is not using the new username already
if ($admins->adminExists($_POST['username']))
{
session::set('errors', ['This username is already in use by another admin.']);
$commons->redirectTo(SITE_PATH.'add-admin.php');
}
// We've checked everything,
// now we can CREATE the admin in the admins table
if (!$admins->addNewAdmin($username, $password))
{
session::set('errors', ['An error occured while saving the new admin.']);
$commons->redirectTo(SITE_PATH.'add-admin.php');
}
// Else we display a confirmation message
session::set('confirm', 'New admin added successfully!');
$commons->redirectTo(SITE_PATH.'add-admin.php');
}
Add new product
This function is the same as adding a new admin. They all show how to CREATE. So I am just adding to satisfy this topic and also I believe someone may like to use it and improve.
add-product.php
<?php
// Start from getting the hader which contains some settings we need
require_once 'includes/header.php';
// Redirect visitor to the login page if he is trying to access
// this page without being logged in
if (!isset($_SESSION['admin_session']) )
{
session::destroy('admin_session');
$commons->redirectTo(SITE_PATH.'index.php');
}
?>
<html>
<head>
<title>Products Management System | Admin Panel</title>
<link href='https://fonts.googleapis.com/css?family=Oswald:400,300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link rel="stylesheet" href="public/css/CreativeButtons/css/component.css">
<link rel="stylesheet" href="public/css/style.css">
</head>
<body>
<main class="container">
<a href="https://lancecourse.com/en/howto/make-your-first-crud-with-php-case-of-a-product-management-system" class="btn btn-4 btn-4d icon-arrow-left">Return to tutorial</a>
<div class="admin-pannel">
<div class="dashboard">
<h3>Add A Product</h3>
<hr>
<p>Please fill in the form bellow to add a new product.</p>
<?php if ( isset($_SESSION['errors']) ): ?>
<div class="pannel panel-warning">
<?php foreach ($_SESSION['errors'] as $error):?>
<li><?= $error ?></li>
<?php endforeach ?>
</div>
<?php session::destroy('errors'); endif ?>
<?php if ( isset($_SESSION['confirm']) ): ?>
<div class="pannel panel-success">
<li><?= $_SESSION['confirm'] ?></li>
</div>
<?php session::destroy('confirm'); endif ?>
<!-- We send the form information to process-new-admin.php to handle it -->
<form action="process-new-product.php" method="POST">
<div>
<label for="name">Product Name</label>
<input type="text" name="name" id="name">
</div>
<div>
<label for="price">Price(Unit)</label>
<input type="number" name="price" id="price" min="1" step="any">
</div>
<div>
<label for="expiry">Expires on</label>
<input type="date" name="expiry" id="expiry">
</div>
<div>
<label for="description">Description</label>
<textarea name="description" id="description" cols="30" rows="10"></textarea>
</div>
<div class="activate">
<button type="submit" class="btn-1a">Save product</button>
</div>
</form>
</div>
<aside class="admin-menu">
<p>Connected as, <?= strip_tags($_SESSION['admin_session']) ?></p>
<ul>
<li><a href="dashboard.php">Dashboard</a></li>
<li><a href="add-admin.php">Add Admin</a></li>
<li><a href="add-product.php">Add Product</a></li>
<li><a href="list-products.php">List Products</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</aside>
<div style="clear:both"> </div>
</div>
<footer>
<?= date("Y") ?> © lancecourse.com - Project by <a href="http://zooboole.me" target="_blank">zooboole</a> - Credit to <a href="http://tympanus.net/codrops/2013/06/13/creative-button-styles/" target="_blank">tympanus.net</a>
</footer>
</main>
</body>
</html>
process-new-product.php
<?php
/*
* We process the admin login form here
*/
// Start from getting the hader which contains some settings we need
require_once 'includes/header.php';
// require the admins class which containes most functions applied to admins
require_once ROOT."../includes/classes/admin-class.php";
$admins = new Admins($dbh);
// check if the form is submitted
if (isset($_POST))
{
// If the form is submitted
// first we check if all required fields are filled out
// In this case the productname, price and the expiry date
$errors = array();
foreach($_POST as $key => $value)
{
if((empty($value) || trim($value) == '') && $key!='description') {
$errors[$key] = "The field ".$key." should not be empty.";
}
$$key = $value;
}
// Description is not set in the loop
$description = $_POST['description'];
// If there is any error we send back to the form
if (!empty($errors) || sizeof($errors) != 0)
{
session::set('errors', $errors);
$commons->redirectTo(SITE_PATH.'add-product.php');
}
// We've checked everything,
// now we can CREATE the admin in the admins table
if (!$admins->addNewProduct($name, $price, $expiry, $description))
{
session::set('errors', ['An error occured while saving the new product.']);
$commons->redirectTo(SITE_PATH.'add-product.php');
}
// Else we display a confirmation message
session::set('confirm', 'New product added successfully!');
$commons->redirectTo(SITE_PATH.'add-product.php');
}
Finally the source code for includes/classes/admin-class.php
<?php
/**
* The admins class
* It contains all action and behaviours admins may have
*/
class Admins
{
private $dbh = null;
public function __construct($db)
{
$this->dbh = $db->dbh;
}
public function loginAdmin($username, $password)
{
//Un-comment this to see a cryptogram of a password
// echo session::hashPassword($password);
// die;
$request = $this->dbh->prepare("SELECT username, password FROM admins WHERE username = ?");
if($request->execute( array($username) ))
{
// This is an array of objects.
// Remember we setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); in config/dbconnection.php
$data = $request->fetchAll();
// But if things are right, the array should contain only one object, the corresponding user
// so, we can do this
$data = $data[0];
return session::passwordMatch($password, $data->password) ? true : false;
}else{
return false;
}
}
/**
* Check if the admin username is unique
* If though we've set this criteria in our database,
* It's good to make sure the user is not try that
* @param $username The username
* @return Boolean If the username is already usedor not
*
*/
public function adminExists( $username )
{
$request = $this->dbh->prepare("SELECT username FROM admins WHERE username = ?");
$request->execute([$username]);
$Admindata = $request->fetchAll();
return sizeof($Admindata) != 0;
}
/**
* Compare two passwords
* @param String $password1, $password2 The two passwords
* @return Boolean Either true or false
*/
public function ArePasswordsSame( $password1, $password2 )
{
return strcmp( $password1, $password2 ) == 0;
}
/**
* Create a new row of admin
* @param String $username New admin username
* @param String $password New Admin password
* @return Boolean The final state of the action
*
*/
public function addNewAdmin($username, $password)
{
$request = $this->dbh->prepare("INSERT INTO admins (username, password) VALUES(?,?) ");
// Do not forget to encrypt the pasword before saving
return $request->execute([$username, session::hashPassword($password)]);
}
/**
* Create a new row of product
*
*/
public function addNewProduct($name, $price, $expiry, $description)
{
$request = $this->dbh->prepare("INSERT INTO products (product_name, product_price, product_expires_on, product_description, created_on) VALUES(?,?,?,?,?) ");
// Do not forget to encrypt the pasword before saving
return $request->execute([$name, $price, $expiry, $description, time()]);
}
}
Bottom line
That's it. In the next part we'll end the project with the possibility of listing products(READ
), editing(UPDATE
), and deleting(DELETE
) them. And I will also be uploading my source code for you. Meanwhile the demo is here, and use admin
as username and password.
Thanks for following. Don't forget to share this with friends.
Last updated 2024-01-11 UTC