502 Chapter 24 Building User Authentication and Personalization Note that fopen() will only be able to open files if your server has direct access to the Internet. If it needs to access other HTTP servers via a proxy server, fopen() will not work. This function and the others relating to bookmarks are all in the function library url_fns.php.You can see the code for the add_bm() function in Listing 24.22. Listing 24.22 The add_bm() function from url_fns.php—This Function Adds New Bookmarks to the Database function add_bm($new_url) { // Add new bookmark to the database echo "Attempting to add ".htmlspecialchars($new_url).'<br />'; global $HTTP_SESSION_VARS; $valid_user = $HTTP_SESSION_VARS['valid_user']; if (!($conn = db_connect())) return false; // check not a repeat bookmark $result = mysql_query("select * from bookmark where username='$valid_user' and bm_URL='$new_url'"); if ($result && (mysql_num_rows($result)>0)) return false; // insert the new bookmark if (!mysql_query( "insert into bookmark values ('$valid_user', '$new_url')")) return false; return true; } This function is fairly simple. It checks that a user does not already have this bookmark listed in the database. (Although it is unlikely that users would enter a bookmark twice, it is possible and even likely that they might refresh the page.) If the bookmark is new, then it is entered into the database. Looking back at add_bm.php,you can see that the last thing it does is call get_user_urls() and display_user_urls(), the same as member.php.We’ll move on and look at these functions next. Displaying Bookmarks In the member.php script and the add_bm() function, we used the functions get_user_urls() and display_user_urls().These functions get the user’s bookmarks 30 525x ch24 1/24/03 3:36 PM Page 502 503 Implementing Bookmark Storage and Retrieval from the database and display them, respectively.The get_user_urls() function is in the url_fns.php library, and the display_user_urls() function is in the output_fns.php library. The get_user_urls() function is shown in Listing 24.23. Listing 24.23 The get_user_urls() Function from url_fns.php—This Function Retrieves a User’s Bookmarks from the Database function get_user_urls($username) { //extract from the database all the URLs this user has stored if (!($conn = db_connect())) return false; $result = mysql_query( "select bm_URL from bookmark where username = '$username'"); if (!$result) return false; //create an array of the URLs $url_array = array(); for ($count = 1; $row = mysql_fetch_row ($result); ++$count) { $url_array[$count] = addslashes($row[0]); } return $url_array; } Let’s briefly step through this function. It takes a username as parameter, and retrieves the bookmarks for that user from the database. It will return an array of these URLs or false if the bookmarks could not be retrieved. The array from get_user_urls() can be passed to display_user_urls().This is again a simple HTML output function to print the user’s URLs in a nice table format, so we won’t go through it here. Refer back to Figure 24.6 to see what the output looks like.The function actually puts the URLs into a form. Next to each URL is a check box that enables bookmarks to be marked for deletion.We will look at this next. Deleting Bookmarks When a user marks some bookmarks for deletion and clicks on the Delete BM option in the menu, the form containing the URLs will be submitted. Each one of the check boxes is produced by the following code in the display_user_urls() function: echo "<td><input type=\"checkbox\" name=\"del_me[]\" value=\"$url\"></td>"; 30 525x ch24 1/24/03 3:36 PM Page 503 504 Chapter 24 Building User Authentication and Personalization The name of each input is del_me[].This means that, in the PHP script activated by this form, we will have access to an array called $del_me that will contain all the book- marks to be deleted. Clicking on the Delete BM option activates the delete_bms.php script.This script is shown in Listing 24.24. Listing 24.24 delete_bms.php—This Script Deletes Bookmarks from the Database <?php require_once('bookmark_fns.php'); session_start(); //create short variable names $del_me = $HTTP_POST_VARS['del_me']; $valid_user = $HTTP_SESSION_VARS['valid_user']; do_html_header('Deleting bookmarks'); check_valid_user(); if (!filled_out($HTTP_POST_VARS)) { echo 'You have not chosen any bookmarks to delete. Please try again.'; display_user_menu(); do_html_footer(); exit; } else { if (count($del_me) >0) { foreach($del_me as $url) { if (delete_bm($valid_user, $url)) echo 'Deleted '.htmlspecialchars($url).'.<br />'; else echo 'Could not delete '.htmlspecialchars($url).'.<br />'; } } else echo 'No bookmarks selected for deletion'; } 30 525x ch24 1/24/03 3:36 PM Page 504 505 Implementing Bookmark Storage and Retrieval // get the bookmarks this user has saved if ($url_array = get_user_urls($valid_user)); display_user_urls($url_array); display_user_menu(); do_html_footer(); ?> We begin this script by performing the usual validations.When we know that the user has selected some bookmarks for deletion, we delete them in the following loop: foreach($del_me as $url) { if (delete_bm($valid_user, $url)) echo 'Deleted '.htmlspecialchars($url).'.<br />'; else echo 'Could not delete '.htmlspecialchars($url).'.<br />'; } As you can see, the delete_bm() function does the actual work of deleting the book- mark from the database.This function is shown in Listing 24.25. Listing 24.25 delete_bm()Function in url_fns.php—This Function Deletes a Single Bookmark from a User’s List function delete_bm($user, $url) { // delete one URL from the database if (!($conn = db_connect())) return false; // delete the bookmark if (!mysql_query( "delete from bookmark where username='$user' and bm_url='$url'")) return false; return true; } As you can see, this is again a pretty simple function. It attempts to delete the bookmark for a particular user from the database. One thing to note is that we want to remove a particular username-bookmark pair. Other users might still have this URL bookmarked. Some sample output from running the delete script on our system is shown in Figure 24.10. As in the add_bms.php script, when the changes to the database have been made, we display the new bookmark list using get_user_urls() and display_user_urls(). Listing 24.24 Continued 30 525x ch24 1/24/03 3:36 PM Page 505 506 Chapter 24 Building User Authentication and Personalization Figure 24.10 The deletion script notifies the user of deleted bookmarks and then displays the remaining bookmarks. Implementing Recommendations Finally, we come to the link recommender script, recommend.php. There are many different ways we could approach recommendations.We have decid- ed to perform what we call a “like-minds” recommendation.That is, we will look for other users who have at least one bookmark the same as our given user.The other bookmarks of those other users might appeal to our given user as well. The easiest way to implement this as an SQL query would be to use a subquery. First, we get the list of similar users in a subquery, and then we look at their bookmarks in an outer query. However, as you might recall, MySQL does not support subqueries.We will have to perform two different queries and feed the output of the first into the next.We can do this either by setting up a temporary table with the results from the first query, or by processing the first query results through PHP. We have chosen the second approach. Both approaches have merit. Using a tempo- rary table is probably slightly faster, but processing in PHP makes it easier to test and modify the code. We begin by running the following query: select distinct(b2.username) from bookmark b1, bookmark b2 30 525x ch24 1/24/03 3:36 PM Page 506 . is call get_user_urls() and display_user_urls(), the same as member .php. We’ll move on and look at these functions next. Displaying Bookmarks In the member .php script and the add_bm() function,. results through PHP. We have chosen the second approach. Both approaches have merit. Using a tempo- rary table is probably slightly faster, but processing in PHP makes it easier to test and modify. functions get_user_urls() and display_user_urls().These functions get the user’s bookmarks 30 525x ch24 1/24/03 3:36 PM Page 502 503 Implementing Bookmark Storage and Retrieval from the database and display