Here’s how you can recreate the calendar example shown at: http://developer.yahoo.com/yui/examples/calendar/multi.html To do so, locate all the following files in the build folder of the
Trang 1A Simple YUI Calendar
For example, clicking through to the calendar link reveals how you can make your own
calendars, a common feature needed by many websites Here’s how you can recreate the calendar example shown at:
http://developer.yahoo.com/yui/examples/calendar/multi.html
To do so, locate all the following files in the build folder of the downloaded YUI
dis-tribution on your hard disk, and copy them to your web folder (bearing in mind that
assets is a folder, not a file):
• fonts/fonts-min.css
• calendar/assets
• yahoo-dom-event /yahoo-dom-event.js
• calendar/calendar-min.js
Now you can type in the document in Example 19-3, calendar.html, which, when you
call it up in your browser, will look like Figure 19-5
Figure 19-5 A YUI calendar
Other Uses for YUI | 401
Trang 2Example 19-3 calendar.html—a multiselect calendar
<html><head><title>YUI Calendar</title>
<link rel="stylesheet"
type="text/css" href="fonts-min.css" />
<link rel="stylesheet"
type="text/css" href="assets/skins/sam/calendar.css" />
<script src="yahoo-dom-event.js"></script>
<script src="calendar-min.js"></script>
</head><body class="yui-skin-sam">
<div id="cal1Container"></div>
<script>
YAHOO.namespace("example.calendar")
YAHOO.example.calendar.init = function() {
YAHOO.example.calendar.cal1 =
new YAHOO.widget.Calendar("cal1", "cal1Container",
{ MULTI_SELECT: true } )
YAHOO.example.calendar.cal1.render()
}
YAHOO.util.Event.onDOMReady(YAHOO.example.calendar.init)
</script>
</body></html>
All that remains to do is place the following DIV where you want it on your web page, and the calendar will appear there:
<div id="cal1Container"></div>
You can also link directly to the various files on the Yahoo! server by modifying the three lines that link to the YUI libraries to read as follows:
<link rel="stylesheet" type="text/css"
href="http://yui.yahooapis.com/2.7.0/build/calendar/assets/skins/sam/calendar.css" />
<script src="http://yui.yahooapis.com/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js">
</script>
<script src="http://yui.yahooapis.com/2.7.0/build/calendar/calendar-min.js">
</script>
All the other YUI features are just as easy to use, and require you only
to carefully read the accompanying documentation before copying and
pasting the supplied code There’s even a link to the YUI Dependency
Configurator supplied with each example, which will build a
copy-and-paste script to load all the dependent JavaScript and CSS files for any
feature, directly from the Yahoo! servers.
I hope you have a lot of fun using the resources supplied by YUI (and any of the other frameworks you try) If you do, you’ll find yourself saved from reinventing the wheel time and time again
402 | Chapter 19: Using YUI for Ajax and More
Trang 3In the next and final chapter I’ll bring everything you’ve learned so far together into a social networking application
Test Your Knowledge: Questions
Question 19-1
What is YUI’s method of implementing an Ajax connection?
Question 19-2
Write a callback object for YUI called callback to reference a success handler called
succeeded and a failure handler called failed
Question 19-3
Write a GET call to asyncRequest that references the program getdata.php and a
callback object
Question 19-4
How can you encode the URL mysite.com/message?m=123, which contains the ?
symbol, so that if sent as a GET request it will be treated just as a string and not interpreted?
See the section “Chapter 19 Answers” on page 451 in Appendix A for the answers to these questions
Test Your Knowledge: Questions | 403
Trang 5CHAPTER 20
Bringing It All Together
Now that you’ve reached the end of your journey into learning the hows, whys, and wherefores of dynamic web programming, I want to leave you with a real example that you can sink your teeth into In fact, it’s 10 examples, because I’ve put together a simple social networking project comprising all the main features you’d expect from such a site
Across the various files, there are examples of MySQL table creation and database access, file inclusion, session control, DOM access, Ajax calls, event and error handling, file uploading, image manipulation, and a whole lot more
Each example file is complete and self-contained, yet works with all the others to build
a fully working social networking site I have deliberately left styling and design to an absolute minimum to keep the examples short and easy to follow This means that, as
it stands, the end product is particularly usable on mobile platforms such as the iPhone, where reducing the file size and dimensions of web documents is important
I leave it up to you to take any pieces of code you think you can use and expand on them for your own purposes Perhaps you may even wish to build on these files to create
a social networking site of your own
Designing a Social Networking Site
Before writing any code, I sat down and came up with several things that I decided were essential to such a site These included:
• A sign-up process
• A login form
• A logout facility
• Session control
• User profiles with uploaded thumbnails
• A member directory
405
Trang 6• Adding members as friends
• Public and private messaging between members
That’s 8 main elements, but in the end it turned out that because the project would
require a main index.html page and a separate include file for the main functions, 10
PHP program files were required
I decided to name the project Robin’s Nest, but you have to modify only one line of
code to change this to a name of your choice Also, all the filenames (except
index.html) start with the letters rn to separate them from any other files you have saved
from this book If you change these names, make sure you also change all references across all the files
About Third-Party Add-Ons
For reasons of simplicity and size, and so that you don’t have to install add-ons to your server if you don’t wish to, I have deliberately not used either PEAR (see Appendix E)
or Smarty (see Chapter 12) in these examples But if you plan on extending the code,
I strongly recommend you consider them, as PEAR can make the programming process simpler Furthermore, if you will be working with separate designers, Smarty can re-move the programming layer from the presentation layer, leaving them free to create
at their heart’s content
However, where I have implemented an Ajax call, I have also included an alternative YUI version, as you can use it without installing any software on your server
On the Website
All the examples in this chapter can be found on the companion website located at
http://lpmj.net, where the code syntax is color-highlighted, making it easier to follow You can also download the examples from there to your computer by clicking on the
“Examples” link This will download an archive file called examples.zip, which you
should extract to a suitable location on your computer
Of particular interest to this chapter, within the ZIP file there’s a folder called
robinsnest, in which all the following examples have been saved using the correct
file-names required by this sample application So you can easily copy them all to your web development folder to try them out
rnfunctions.php
So let’s jump right into the project, starting with Example 20-1, rnfunctions.php, the
include file of main functions This file contains a little more than just the functions, though, because I have added the database login details here instead of using yet another
406 | Chapter 20: Bringing It All Together
Trang 7separate file So the first half-dozen lines of code define the host, database name, user-name, and password of the database to use
It doesn’t matter what you call the database, as long as it already exists (see Chap-ter 8 for how to create a new database) Also make sure to correctly assign a MySQL username and password to $dbuser and $dbpass With correct values, the subsequent two lines will open a connection to MySQL and select the database The last of the initial instructions sets the name of the social networking site by assigning the value
“Robin’s Nest” to the variable $appname If you want to change the name, here’s the place to do so
The Functions
The project uses six main functions:
createTable
Checks whether a table already exists and, if not, creates it
tableExists
Returns a value of 1 if a table already exists, otherwise 0
queryMysql
Issues a query to MySQL, outputting an error message if it fails
destroySession
Destroys a PHP session and clears its data to log users out
sanitizeString
Removes potentially malicious code or tags from user input
showProfile
Displays a user’s image and “about me” if they have one
All of these should be obvious in their action to you by now, with the possible exception
of showProfile, which looks for an image of the name user.jpg (where user is the
user-name of the current user), and if found, displays it It also displays any “about me” text the user may have saved
I have ensured that error handling is in place for all the functions that need it, so that they can catch any typographical or other errors you may introduce However, if you use any of this code on a production server, you will probably want to provide your own error-handling routines to make the code more user-friendly
So type this file in and save it as rnfunctions.php and you’ll be ready to move on to the
next section
Example 20-1 rnfunctions.php
<?php // rnfunctions.php
$dbhost = 'localhost'; // Unlikely to require changing
$dbname = 'publications'; // Modify these
$dbuser = 'username'; // variables according
rnfunctions.php | 407
Trang 8$dbpass = 'password'; // to your installation
$appname = "Robin's Nest"; // and preference
mysql_connect($dbhost, $dbuser, $dbpass) or die(mysql_error());
mysql_select_db($dbname) or die(mysql_error());
function createTable($name, $query)
{
if (tableExists($name))
{
echo "Table '$name' already exists<br />";
}
else
{
queryMysql("CREATE TABLE $name($query)");
echo "Table '$name' created<br />";
}
}
function tableExists($name)
{
$result = queryMysql("SHOW TABLES LIKE '$name'");
return mysql_num_rows($result);
}
function queryMysql($query)
{
$result = mysql_query($query) or die(mysql_error());
return $result;
}
function destroySession()
{
$_SESSION=array();
if (session_id() != "" || isset($_COOKIE[session_name()]))
setcookie(session_name(), '', time()-2592000, '/');
session_destroy();
}
function sanitizeString($var)
{
$var = strip_tags($var);
$var = htmlentities($var);
$var = stripslashes($var);
return mysql_real_escape_string($var);
}
function showProfile($user)
{
if (file_exists("$user.jpg"))
echo "<img src='$user.jpg' border='1' align='left' />";
$result = queryMysql("SELECT * FROM rnprofiles WHERE user='$user'");
408 | Chapter 20: Bringing It All Together
Trang 9if (mysql_num_rows($result))
{
$row = mysql_fetch_row($result);
echo stripslashes($row[1]) "<br clear=left /><br />";
}
}
?>
rnheader.php
For uniformity, each page of the project needs to have the same overall design and layout Therefore I placed these things in Example 20-2, rnheader.php This is the file that is actually included by the other files and it, in turn, includes rnfunctions.php This
means that only a single include is required in each file
rnheader.php starts by calling the function session_start As you’ll recall from Chap-ter 13, this sets up a session that will remember certain values we want stored across different PHP files
With the session started, the program then checks whether the session variable
'user' is currently assigned a value If so, a user has logged in and the variable
$loggedin is set to TRUE
Using the value of $loggedin, an if block displays one of two sets of menus The
non-in set simply offers options of Home, Sign up, and Log in, whereas the
logged-in version offers full access to the project’s features Additionally, if a user is logged logged-in, his or her username is appended in brackets to the page title and placed before the menu options We can freely refer to $user wherever we want to put in the name, because if the user is not logged in, that variable is empty and will have no effect on the output
The only styling applied in this file is to set the default font to Verdana at a size of 2 via
a <font > tag For a more comprehensive design and layout, you’ll probably wish to apply CSS styling to the HTML
Example 20-2 rnheader.php
<?php // rnheader.php
include 'rnfunctions.php';
session_start();
if (isset($_SESSION['user']))
{
$user = $_SESSION['user'];
$loggedin = TRUE;
}
else $loggedin = FALSE;
echo "<html><head><title>$appname";
if ($loggedin) echo " ($user)";
rnheader.php | 409
Trang 10echo "</title></head><body><font face='verdana' size='2'>";
echo "<h2>$appname</h2>";
if ($loggedin)
{
echo "<b>$user</b>:
<a href='rnmembers.php?view=$user'>Home</a> |
<a href='rnmembers.php'>Members</a> |
<a href='rnfriends.php'>Friends</a> |
<a href='rnmessages.php'>Messages</a> |
<a href='rnprofile.php'>Profile</a> |
<a href='rnlogout.php'>Log out</a>";
}
else
{
echo "<a href='index.php'>Home</a> |
<a href='rnsignup.php'>Sign up</a> |
<a href='rnlogin.php'>Log in</a>";
}
?>
rnsetup.php
With the pair of included files written, it’s now time to set up the MySQL tables they will use This is done with Example 20-3, rnsetup.php, which you should type in and
load into your browser before calling up any other files—otherwise you’ll get numerous MySQL errors
The tables created are kept short and sweet, and have the following names and columns:
rnmembers
username user (indexed), password pass
rnmessages
ID id (indexed), author auth (indexed), recipient recip, message type pm, message message
rnfriends
username user (indexed), friend’s username friend
rnprofiles
username user (indexed), “about me” text
Because the function createTable first checks whether a table already exists, this pro-gram can be safely called multiple times without generating any errors
It is very likely that you will need to add many more columns to these tables if you choose to expand on this project If so, you may need to issue a MySQL DROP TABLE
command before recreating a table
410 | Chapter 20: Bringing It All Together