Flylib.com

Books Software

 
 
 

Section 12.2. AJAX Reliance Scale


12.2. AJAX Reliance Scale

You can use AJAX such that it's 100 percent optional, and your application will be just fine with JavaScript turned off. This type of AJAX usage is usually accomplished by developing an application and then adding small amounts of JavaScript to enhance specific functions. JavaScript behaviors are a great technique to use in this approach. At the opposite end of the spectrum, you have a pure AJAX application; in a case like this, the back-end Web server provides only a set of services (such as creating users, listing tickets, and so on). The entire user interface and the logic that drives it are built in JavaScript. A Web application with AJAX enhancement follows the normal Web pattern; forms post like normal to the server and pages reload on a regular basis. An AJAX application breaks out of that mode: The site is loaded once, and from that point on, all interaction with the server is controlled by JavaScript, with requests being made as needed and the DOM being updated as well.

These two styles of AJAX development create two ends of a scale. Although both these approaches have their merits, most applications won't fit neatly into either of the categories. Instead, you'll have a mix somewhere in the middle; an enhanced application will add features such as user selection that work only with AJAX support, but other functions will submit like normal. You might also have a page with few normal reloads . It will not quite fit into the AJAX application structure because the majority of the logic rests on the back-end server.

One important item to remember is that although applications can exist all along the scale, you'll have a hard time moving an application from one end to the other. If your design is structured around server-side logic, you can easily make features that require AJAX optional again by providing non-AJAX versions of them. However, you might have a tough time getting rid of all the page reloads, because you'll find yourself having a large amount of duplicated client and server logic that will be hard to keep in sync. Making a completely AJAX-driven application not rely on AJAX communications will offer these same types of problems, because you'll have to duplicate large amounts of logic on the server to make the switch. If you're making a mixed application, you won't have this problem, because moving small features that cause normal refreshes to an AJAX request will be easy. An AJAX reliance scale with a number of AJAX applications placed on it is shown in Figure 12-1.

Figure 12-1. AJAX reliance scale


The trouble ticket system built in this chapter will rely on AJAX for server communication needs past the original page load. This puts the application at the far right of the scale, with applications like Mp3act, which is described in Chapter 4, "Adding AJAX to Your Web Development Process." Heavy reliance like this can make supporting old browsers extremely difficult, but old browser support isn't usually needed for internal applications, so this isn't an issue for the trouble-ticket system.



12.3. Creating the Back End

The first step to building our application is creating the back-end services that will perform all the database work. Think of the functions as a set of services that will be exposed to the client application. In some cases, these services might already exist and are offered to other applications using SOAP or some other Web services technology, but in most cases, you'll be creating them just for your AJAX application. Because the trouble-ticket application is offering only basic functionality, the back end in this case can be quite simple. In this case, it's grouped into a single class, but as the application grows, you may want to factor it into multiple classes to keep it manageable.

Because the focus of this use case is AJAX, we're not going to look at the back- end code in detail. The back end is implemented in PHP and uses a lightweight class to talk to a MySql database. The code is in Ticket.class.php , with the SQL to set up the database in Ticket.sql . If you want to run the example on your own server, you'll need to edit the first six lines of the Ticket.class.php file, updating its database connection settings. A nice aspect about a back end like this is that it can be easily implemented in any language that has a library to expose the services provided by the class using a JSON RPC mechanism or something similar. We'll be using HTML_AJAX to expose the class from PHP and will cover that in detail once we cover the API provided and the results to expect from each method.

All interactions with the back end are performed by using the API provided by the Ticket class. The methods perform actions against the database that has two tables. The basic definition of the Tickets and Users tables is shown in Figure 12-2.

Figure 12-2. Database definition of Tickets and User Tables


The addUser method creates a new user; it takes three parameters: the new username to use, the password, and the email address. The method does basic validation requiring that none of the fields is empty; if any are, the method returns false . If a user is successfully added, the method returns TRue . The method's signature is

addUser($username,$password,$email)


The updateUser method updates information about the currently logged in user. If no user is logged in, the method returns false . If the update succeeds, an associative array containing the user's profile is returned. The method takes a single parameter, which is an associative array containing the fields to update. updateUser's signature is

updateUser($fields)


An example input is as follows :

$fields = array(
        'email' => 'new email',
        'password' => 'new password'
);


Although we store a user_id , username , password , and email address for each user, only emails and passwords can be updated; user_id is auto_created, and username can be set only when an account is created. An example profile array that would be returned by this method is as follows:

array
  'user_id' => '1'
  'username' => 'josh'
  'email' => 'josh@bluga.net'
  'loggedIn' => true


The listUsers method returns an array containing a list of all the users in the system. The key of the array is the user_id , and the value is the username. The array is ordered by the username. The listUsers method takes no parameters:

listUsers()


An example output is shown here:

array
  1 => 'josh'


The addTicket method adds a new trouble ticket to the system. It takes two parameters: the title of the ticket and a descriptive text field. The user must be logged in to submit a ticket; if the user isn't logged in, this method returns false . On successful creation of a ticket, the method returns the new ticket_id. addTicket has a signature of

addTicket($title,$description)


getTicket grabs an associative array with all the information about a ticket. This method can be used without logging in. The returned array contains two subarrays: the first subarray with a key of users contains the output from listUsers , whereas the second subarray with a key of ticket is the ticket information. The getTicket method's signature is

getTicket($ticketId)


Example output is shown here:

array
  'users' =>
    array
      1 => 'josh'
  'ticket' =>
    array
      'ticket_id' => '1'
      'creator' => 'josh'
      'assigned' => '1'
      'title' => 'Test Ticket'
      'description' => 'Test'
      'status' => 'new'
      'created_time' => '2006-02-26 12:38:32'
      'last_change' => '2006-02-26 12:38:32'
      'assigned_to' => 'josh'


The updateTicket method updates the fields of a ticket. It has a method signature of

updateTicket($ticketID,$fields)


The first parameter is the ID of the ticket to update, and the second is an associative array of the fields. All the ticket fields except for the ticket_id can be updated using this method. The last_change field is automatically set to the current time when this method is run. The user must be logged in to use this method; false is returned if the user isn't logged in. When the update is completed, an associative array containing the same output as getFields is returned. Ticket status can be updated with this method; possible status values are new , assigned , open , and fixed . An example input value for the attribute $fields is shown here:

$fields = array(
                'title' => 'New Title',
                'description' => 'New Description',
                'status' => 'open',
                'assigned' => 1
        );


The assignTicket method assigns a ticket to a specific user. It takes two parameters: a $ticket_id and a $user_id . The user must be logged in to use this method; if he or she is not, it returns false ; after the ticket is successfully updated, output that matches getTicket is returned. If $userId is set to false , the ticket is unassigned . This method will also automatically update the status of the ticket; if the current status of the ticket is new and $userId isn't false , then the status will be changed to assigned . If the current status of the ticket is assigned and $userId equals false , then the status of the ticket will be changed to open . Note that updateTicket uses this method if its assigned field is set. The value of this field is passed in as $userId . assignTicket' s signature is

assignTicket($ticketId,$userId)


The listUnassignedTickets method lists all the tickets in the system that haven't been assigned to a user. The array is ordered by the last_change date of the tickets. The listUnassignedTickets signature is

listUnassignedTickets()


Example output is shown here:

array
  0 =>
    array
      'ticket_id' => '1'
      'creator' => 'josh'
      'assigned' => null
      'title' => 'Test Ticket'
      'description' => 'Test'
      'status' => 'new'
      'created_time' => '2006-02-26 12:43:39'
      'last_change' => '2006-02-26 12:43:39'
      'assigned_to' => 'Not Assigned'


The listAssignedTickets method returns a list of tickets that are assigned to the currently logged in user. If this method is called without the user being logged in, false is returned. The array is ordered by the last_change date of the tickets. The listAssignedTickets method has no parameters and has a signature of

listAssignedTickets()


Example output is shown here:

array
  0 =>
    array
      'ticket_id' => '1'
      'creator' => 'josh'
      'assigned' => '1'
      'title' => 'Test Ticket'
      'description' => 'Test'
      'status' => 'assigned'
      'created_time' => '2006-02-26 12:43:39'
      'last_change' => '2006-02-26 12:43:39'
      'assigned_to' => 'josh'


The listUpdatedTickets method provides a way to get updated information about tickets that are assigned to the currently logged in user and that have changed since the last time you checked with the back end. This method tries to return a minimal number of ticket records, but in cases where tickets have been unassigned, it sets a flag to note that the table displaying the data needs to be rebuilt and returns the full output of listAssignedTickets . When the rebuild flag is set, the ticket data is returned under a tickets index.

listUpdatedTickets($last_call_time,$current)


An example of output returned in normal mode and then in rebuild mode is shown in Listings 12-1 and 12-2. In normal mode, only new and changed tickets are sent to the client where the table displaying them is updated. In rebuild mode, all the tickets are sent to the client, where the entire table is rebuilt.

Listing 12-1. Normal listUpdatedTickets Output
array
  0 =>
    array
      'ticket_id' => '1'
      'creator' => 'josh'

      'assigned' => '1'
      'title' => 'Test Ticket'
      'description' => 'Blah blah'
      'status' => 'assigned'
      'created_time' => '2006-02-26 13:21:11'
      'last_change' => '2006-02-26 13:21:12'
      'assigned_to' => 'josh'

Listing 12-2. Rebuild Mode listUpdatedTickets Output
array
  'rebuild' => true
  'tickets' =>
    array
      0 =>
        array
          'ticket_id' => '2'
          'creator' => 'josh'
          'assigned' => '1'
          'title' => 'test ticket'
          'description' => 'blah blah'
          'status' => 'assigned'
          'created_time' => '2006-02-26 13:39:06'
          'last_change' => '2006-02-26 13:39:06'
          'assigned_to' => 'josh'

The login method logs a user into the system, storing this status in the user's session. It takes two parameters: the username and the password. If the login is unsuccessful , false is returned; if the login is successful, the user's profile information is returned. The method signature is

login($username,$password)


An example profile output is shown here:

array
  'user_id' => '1'
  'username' => 'josh'
  'email' => 'josh@bluga.net'
  'loggedIn' => true


The isLoggedIn method returns TRue if the user is logged in and false if the user isn't. This method isn't usually called by a JavaScript client but is instead used by other methods in the Ticket class. isLoggedIn has a signature of

isLoggedIn()


The profile method is used to get information about a user's profile. The method takes one optional parameter: $field . If $field is set, that value from the user's profile will be returned; otherwise , the entire profile will be returned. If the user isn't logged in when this method is called, false will be returned. The profile output is identical to the output of a successful login. The profile method has a signature of

profile($field = false)


The logout method logs the current user out of the system and destroys the user's current PHP session. This method always returns a value of true . logout has no parameters; its signature is

logout()