Saturday, 15 August 2009

Wednesday, 12 August 2009

Thursday, 6 August 2009

Monday, 3 August 2009

aaaaa

This page list all the products Yongda supermarket has. Users can see all products or just products from certain category. From this page the users can see the product detail , add new product, modify and delete.

Below is what the page look like. The table shows the product name, thumbnail, category, and modify and delete link. We show the product image if it exist. In case we haven't supply the image the default image is shown instead.


Sunday, 2 August 2009

Admin - Add Product

Adding a product for the online shop is a straightforward process. Just enter the product information and hit the 'Add Product' button. When adding a product we will require these information :

  • Category
  • Product name
  • Description
  • Price
  • Quantity in stock
  • Image
All is mandatory except for the image. I can add the product image later.
Not much difference from the add category form.



On top of the form the admin can see the category combo box. I build this so that the admin can only select the second level category. This is to ensure that all product are added on the second level category and not put in the top level category by mistake.

The one responsible to build the list is the buildCategoryOptions() function in admin/library/functions.php. Below is the snippet for the code that build the combo box. Just in case I will need the ability to add some product to the first level category you can replace the buildCategoryOptions() with the commented function code written below it.
function buildCategoryOptions($catId = 0)
{
$sql = "SELECT cat_id, cat_parent_id, cat_name
FROM tbl_category
ORDER BY cat_id"
;
$result = dbQuery($sql) or die('Cannot get Product. ' . mysql_error());

$categories = array();
while(
$row = dbFetchArray($result)) {
list(
$id, $parentId, $name) = $row;

if (
$parentId == 0) {
// we create a new array for each top level categories
$categories[$id] = array('name' => $name, 'children' => array());
} else {
// the child categories are put int the parent category's array
$categories[$parentId]['children'][] = array('id' => $id, 'name' => $name);
}
}

// build combo box options
$list = '';
foreach (
$categories as $key => $value) {
$name = $value['name'];
$children = $value['children'];

$list .= "";

foreach (
$children as $child) {
$list .= ";
if (
$child['id'] == $catId) {
$list.= " selected";
}

$list .= ">{$child['name']}rn";
}

$list .= "";
}

return
$list;
}
The product quantity is limited to 65,535 since in the table definition I only use smallint(5) . I find this number adequate for most online shops. But if do carry more than that amount for an item just change the data type to something bigger like mediumint(8).

The product image you need to supply is the large size product image which will be shown in the product detail page. The script will generate a thumbnail for it to be shown in the product browsing page. I define the maximum image size and the thumbnail size in config.php

// some size limitation for the category
// and product images

// all category image width must not
// exceed 75 pixels
define('MAX_CATEGORY_IMAGE_WIDTH', 75);

// do we need to limit the product image width?
// setting this value to 'true' is recommended
define('LIMIT_PRODUCT_WIDTH', true);

// maximum width for all product image
define('MAX_PRODUCT_IMAGE_WIDTH', 300);

// the width for product thumbnail
define('THUMBNAIL_WIDTH', 75);

if (!
get_magic_quotes_gpc()) {
if (isset(
$_POST)) {
foreach (
$_POST as $key => $value) {
$_POST[$key] = trim(addslashes($value));
}
}

if (isset(
$_GET)) {
foreach (
$_GET as $key => $value) {
$_GET[$key] = trim(addslashes($value));
}
}
}
I need to restrict the image size so it won't destroy the site layout. Imagine that if the image is 1000 pixels wide and 2000 pixels high. It will make the product detail page look awful. Image resizing can be turned on or off. If you set LIMIT_PRODUCT_WIDTH to false on config.php the script will just upload the image without worying about it's size. It's not recommended though.

Admin - Delete Category

When the admin decides that a category is no longer needed, he/she can remove it from the database. To delete a category go to the category listing page and click on the 'delete' link on the category you wish to delete

Deleting a category will delete all product in that category and in all it's children. For example if the admin delete the "HOMEWARE" category than all product in "Kitchen ware" and "Electric Goods" will also be deleted. The function used to delete category is called deleteCategory() and it's located in admin/category/processCategory.php

The deletion process is like this :

  1. Update the cat_id for all products in that category to zero
  2. Remove the category image ( if exist )
  3. Delete the category from database
function deleteCategory()
{
if (isset($_GET['catId']) && (int)$_GET['catId'] > 0) {
$catId = (int)$_GET['catId'];
} else {
header('Location: index.php');
}

// find all the children categories
$children = getChildren($catId);

// make an array containing this category and all it's children
$categories = array_merge($children, array($catId));
$numCategory = count($categories);

// remove all product image & thumbnail
// if the product's category is in $categories
$sql = "SELECT pd_id, pd_image, pd_thumbnail
FROM tbl_product
WHERE cat_id IN (" . implode(',', $categories) . ")";
$result = dbQuery($sql);

while ($row = dbFetchAssoc($result)) {
@unlink(SRV_ROOT . PRODUCT_IMAGE_DIR . $row['pd_image']);
@unlink(SRV_ROOT . PRODUCT_IMAGE_DIR . $row['pd_thumbnail']);
}

// delete the products
$sql = "DELETE FROM tbl_product
WHERE cat_id IN (" . implode(',', $categories) . ")";
dbQuery($sql);

// then remove the categories image
_deleteImage($categories);

// finally remove the category from database;
$sql = "DELETE FROM tbl_category
WHERE cat_id IN (" . implode(',', $categories) . ")";
dbQuery($sql);

header('Location: index.php');
}

Admin - Edit Category

add.php is where I can modify a category information.
If admin change the category image then the old image will be deleted from the server and the new image is uploaded.
To get the category info from database we need the category id from the query string. If $_GET['catId'] is not present or empty I just redirect to index.php. If it's present and not empty we fetch the category info. To look at the code below:
if (!defined('WEB_ROOT')) {
exit;
}
// make sure a category id exists
if (isset($_GET['catId']) && (int)$_GET['catId'] > 0) {
$catId = (int)$_GET['catId'];
} else {
header('Location:index.php');
}
$sql = "SELECT cat_id, cat_name, cat_description, cat_image
FROM tbl_category
WHERE cat_id = $catId";
$result =& dbQuery($sql);
$row =& dbFetchAssoc(&$result);
extract($row);
next to the category image I have a delete link: Clicking on the link will call the function deleteImage(). This function will pop a confirmation box and if the admin confirm the deletion the function will redirect him to processCategory.php where all category related process is taken care of.
function deleteImage()
{
if (isset($_GET['catId']) && (int)$_GET['catId'] > 0) {
$catId = (int)$_GET['catId'];
} else {
header('Location: index.php');
}
_deleteImage($catId);
// update the image name in the database
$sql = "UPDATE tbl_category
SET cat_image = ''
WHERE cat_id = $catId";
dbQuery($sql);
header("Location: index.php?view=modify&catId=$catId");
}
To delete the image from the server the deleteImage() function calls _deleteImage().

After deleting the image I update the category information in database. I only need to set cat_image to an empty string and I am done. The final thing that deleteImage() do is redirect back to the category modification page. I don't redirect to category listing page because the admin may still want to modify the category further.



Find freelance programmers at ScriptLance.com - Search worldwide

Saturday, 1 August 2009

Making a connection page

After designing and inserting data into the hosting database, I use PHP scripting to connect with the database by script below:

$dbConn = mysql_connect ($dbHost, $dbUser, $dbPass) or die ('MySQL connect failed. ' . mysql_error());

The function mysql_connect() means to connect with MySQL database. In the function, a variable $dbHost to specify the server to connect with, $dbUser to specifies the username to log in with and $dbPass to specifies the password to log in with. If these variables are not matched with Hosting server authentication, then an error message will be shown by mysql_error.

I then use mysql_select_db() to make a chosen database active

mysql_select_db($dbName) or die('Cannot select database. ' . mysql_error());

with variable $dbName to specify the database name.

Admin - Add Category

Here the admin can add new product category for the online shop. The information I need are the category name, description, image. Both the name and description are mandatory but the image is not. If I don't have the category image I can leave the field blank. Of course it's not recommended because when the customers come to the shop they will see the default image.

The category description here will not be shown anywhere on the shop. It's only purpose is to let the shop owner / admin to know what the category is all about.

The form has a hidden variable called hidParentId. The value is set from category/list.php as explained on the previous page.

input name="btnAddCategory" type="button" id="btnAddCategory"
value="Add Category" class="box"
onClick="addCategory()"

When I submit the form the process then handed to processCategory.php. All kind of category processing ( add, modify, delete ) are done in this file. On top of the script there's a simple switch to call the appropriate function based on the action required.

$action = isset($_GET['action']) ? $_GET['action'] : '';

switch ($action) {
case 'addCategory' :
addCategory();
break;

case 'modifyCategory' :
modifyCategory();
break;

case 'deleteCategory' :
deleteCategory();
break;

case 'deleteImage' :
deleteImage();
break;

default :
// if action is not defined or unknown
// move to main category page
header('Location: index.php');
}

On the add category form the form action is set as processCategory.php?action=addCategory so if I look at the code above the script will call addCategory();. If no action is defined we just redirect to category main page.

When saving the product image there is a possibility of name conflict. It may seem weird for two categories to have the same image name, but in some cases it can happen. To avoid such conflict we will generate a new name for each category image we upload using the combination of rand(), time() and md5() functions like this :

// get the image extension
$ext = substr(strrchr($image['name'], "."), 1);

// generate a random new file name to avoid name conflict
$imagePath = md5(rand() * time()) . ".$ext";

The image name wil then become something like 6c444ed816ce251d610c25154dc28462.jpg. Now it's almost impossible for us to ever hit the name conflict problem. We will use the same name generation for the product image and thumbnail.

How does it work ?

The time() function will return the number of seconds elapsed since the beginning of ( computer ) time which is January 1, 1970. Using rand() function we get a random value less or equal to the number of seconds. We need to use rand() because this shopping cart can have more than one admin. If two admins happen to submit the form at the same second the result of time() will be the same.

As the final step md5() use the random value and return the hash ( a string with 32 characters ). If I feel that using 32 characters for a filename is too much I can use substr() function to cut it like this :

// get the image extension
$ext = substr(strrchr($image['name'], "."), 1);

// generate a random new file name to avoid name conflict
$imagePath = substr(md5(rand() * time()), 0, 10) . ".$ext";