We can enhance the view by making the rating system a clickable image, where the customer can click on the number of stars they wish to give the product and their rating is saved.. Howev
Trang 1It is back!
Once the product is back in stock, we need to then alert those customers that the
product which they were interested in is back in stock, and that they can proceed to
make their purchase This isn't something we can implement now, as we don't have
an administrative interface in place yet However, we can discuss what is involved in
doing this:
1 The administrator alters the stock level
2 Customers interested in that product are looked up
3 E-mails for each of those customers are generated with relevant details, such
as their name and the name of the product being automatically inserted
4 E-mails are sent to the customers
The database contains a processed field, so once an e-mail is sent, we can set the
processed value to 1, and then once we have alerted all of our customers, we can delete
those records This covers us in the unlikely event that all the new stock sells out while
we are e-mailing customers, and a new customer completes the notification form
Giving power to customers
There are two very powerful social-oriented features, which we can implement into
our framework
Product ratings
Product ratings are quite simple to add to our framework: we simply need to record
a series of ratings between one and five, and display the average of these on the
product view We can enhance the view by making the rating system a clickable
image, where the customer can click on the number of stars they wish to give the
product and their rating is saved
There are a few minor considerations that need to be taken into account However,
if the logged-in customer has already rated a product, we should then update their
rating If the customer is not logged in, we must record some information about them
such as their IP address and the date and time of the rating This way we prevent
duplicate ratings from the same customer
Trang 2From a database perspective, we would need to capture the following information:
ID (Integer, Primary Key, Auto Increment)
ContentID (Integer)
Rating (Integer)
User ID (Integer)
Timestamp (datetime)
Session ID (Varchar)
IP Address (Varchar)
The following SQL represents that table in our database:
CREATE TABLE `content_ratings` (
`ID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`contentID` INT NOT NULL ,
`rating` INT NOT NULL ,
`userID` INT NOT NULL ,
`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`sessionID` VARCHAR( 255 ) NOT NULL ,
`IPAddress` VARCHAR( 50 ) NOT NULL
) ENGINE = INNODB;
Saving a rating
When a rating is made, we need to check to see if the current user has already rated
that content element; if they have, then we must update that rating For users who
are not logged in, we should use their session name and IP address to lookup a
potential rating from the past 30 days; if a rating is found, that should be updated
Saving the rating should be made simple by processing values from the URL This
way, we can have a graphic of five stars or hearts, which when clicked, contain a link
to the corresponding number of stars, to save the suitable rating
As ratings and reviews (comments) will not be content specific, we will need a
separate controller for these To return the customer to the page they were on
previously, we could investigate looking up the referring page, and then redirecting
the user to that page once their rating has been saved
The constructor of the controller needs to parse the URL bits to extract the content ID
and the rating value, ensure that the rating is within allowed limits, and then call the
saveRating function, which either inserts or updates a rating as appropriate
•
•
•
•
•
•
•
Trang 3To check if the user has rated the product already, we query the database; depending
on if the user is logged in, this query is different For users who are not logged in, we
assume users with the same IP address and session data within the past 30 days were
the current users
private function saveRating( $contentID, $rating )
{
if( $this->regisry->getObject('authenticate')->isLoggedIn() )
{
$u = $this->registry->getObject('authenticate')->getUserID();
$sql = "SELECT ID FROM content_ratings
WHERE contentID={$contentID} AND userID={$u}";
}
else
{
$when = strtotime("-30 days");
$when = date( 'Y-m-d h:i:s', $when );
$s = session_id();
$ip = $_SERVER['REMOTE_ADDR'];
$sql = "SELECT ID FROM content_ratings
WHERE content_id={$contentID} AND userID=0
AND sessionID='{$s}' AND IPAddress='{$ip}'
AND timestamp > '{$when}'";
}
$this->registry->getObject('db')->executeQuery( $sql );
If the product has already been rated, we update the rating
if( $this->regisry->getObject('db')->numRows() == 1 )
{
// update
$data = $this->registry->getObject('db')->getRows();
$update = array();
$update['rating'] = $rating;
$update['timestamp'] = date('Y-m-d h:i:s');
$this->registry->getObject('db')->
updateRecords( 'content_ratings', $update, 'ID=' $data['ID']);
$this->registry->getObject('template')->getPage()->
addTag('message_heading', 'Rating changed');
$this->registry->getObject('template')->getPage()->
addTag('message_heading', 'Your rating has been changed');
$this->registry->getObject('template')->
buildFromTemplates('header.tpl.php', 'message.tpl.php',
'footer.tpl.php');
Trang 4Otherwise, we insert a new record in the ratings table.
else
{
// insert
$rating = array();
$rating['rating'] = $rating;
$rating['contentID'] = $contentID;
$rating['sessionID'] = session_id();
$rating['userID'] = ( $this->registry->
getObject('authenticate')->isLoggedIn() == true ) ?
$this->registry->getObject('authenticate')->getUserID() : 0;
$rating['IPAddress'] = $_SERVER['REMOTE_ADDR'];
$this->registry->getObject('db')->
insertRecords( 'content_ratings', $rating );
$this->registry->getObject('template')->getPage()->
addTag('message_heading', 'Rating saved');
$this->registry->getObject('template')->getPage()->
addTag('message_heading', 'Your rating has been saved');
$this->registry->getObject('template')->
buildFromTemplates('header.tpl.php', 'message.tpl.php',
'footer.tpl.php');
}
}
Viewing ratings
To display the ratings, we need to alter the content or products query to also perform
a subquery, which averages out the rating
( SELECT sum(rating)/count(*)
FROM content_ratings
WHERE contentID=c.ID ) AS rating
Improving the user interface for ratings
Displaying ratings as nice graphics, which display both the current rating and allow
the user to select their own rating from them, are chapters in themselves There are a
number of Internet tutorials that document this process; you may find them useful:
http://www.komodomedia.com/blog/2005/08/creating-a-star-rater-using-css/
http://www.search-this.com/2007/05/23/css-the-star-matrix-pre-loaded/
•
•
Trang 5Product reviews
Product reviews can work as a simple comment form for the products, taking the
name and e-mail address of the customer, as well as their review Product reviews
can be represented in the same way that we would represent comments on pages or
blog entries, and because we have set up our database to store pages, products, and
other types of content with a reference to a single database table, we can reference
our reviews or comments to any content type From a database perspective, a table
with the following fields would suffice:
ID Integer (Auto Increment,
Primary Key) Review ID Content Integer The content entity the user is
reviewing Customer name Varchar The customer
Customer email Varchar The customer's e-mail
address Review Longtext The customer's review
IPAddress Varchar The user's IP address
Date Added Timestamp The date they added the
review Approved Boolean If the review is approved and
shown on the site
The following SQL code represents that table in our database:
CREATE TABLE `content_comments` (
`ID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`content` INT NOT NULL,
`authorName` VARCHAR( 50 ) NOT NULL,
`authorEmail` VARCHAR( 50 ) NOT NULL,
`comment` LONGTEXT NOT NULL,
`IPAddress` VARCHAR( 40 ) NOT NULL,
`dateadded` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`approved` BOOL NOT NULL,
INDEX ( `content` )
) ENGINE = INNODB COMMENT = 'Content comments - also for product
reviews';
ALTER TABLE `content_comments`
ADD FOREIGN KEY ( `content` ) REFERENCES `book4`.`content` (`ID`)
ON DELETE CASCADE ON UPDATE CASCADE ;