only for RuBoard - do not distribute or recompile Previous Section Next Section

Implementing User Functions

There are five things we want our users to be able to do after they have logged in:

You can see most of these options in Figure 28.6. We will now look at the implementation of each of these options.

Viewing Lists

We will implement a number of options for viewing available lists and list details. In Figure 28.6, you can see two of these options: Show My Lists, which will retrieve the lists this user is subscribed to, and Show Other Lists, which will retrieve the lists the user is not subscribed to.

If you look back at Figure 28.4, you will see that we have another option, Show All Lists, which will retrieve all the available mailing lists on the system. For the system to be truly scalable, we should add paging functionality (to display, say, 10 results per page). We have not done this here for brevity.

These three menu options activate the show-my-lists, show-other-lists, and show-all-lists actions, respectively. As you have probably realized, all these actions work quite similarly. The code for these three actions is as follows:

						
case 'show-all-lists':
{
  display_items("All Lists", get_all_lists(), 'information',
                'show-archive','');
  break;
}
case 'show-other-lists':
{
    display_items("Unsubscribed Lists",
                  get_unsubscribed_lists(get_email()), 'information',
                  'show-archive', 'subscribe');
    break;
}
case '':
case 'show-my-lists':
{
    display_items("Subscribed Lists", get_subscribed_lists(get_email()),
                 'information', 'show-archive', 'unsubscribe');
    break;
}

					

As you can see, all these actions call the display_items() function from the output_fns.php library, but they each call it with different parameters. They all also use the get_email() function we mentioned earlier to get the appropriate email address for this user.

To see what this function does, look at Figure 28.7.

Figure 28.7. The display_items() function has been used to lay out a list of the lists that the user is not subscribed to.
graphics/28fig07.gif

This is the Show Other Lists page.

Let's look at the code for the display_items() function. It is shown in Listing 28.6.

Listing 28.6 display_items() Function from output_fns.php—This Function Is Used to Display a List of Items with Associated Actions
function display_items($title, $list, $action1='', $action2='', $action3='')
{
  global $table_width;
  echo "<table width = $table_width cellspacing = 0 cellpadding = 0
         border = 0>";

  // count number of actions
  $actions = (($action1!='') + ($action2!='') + ($action3!=''));

  echo "<tr>
        <th colspan = ". (1+$actions) ." bgcolor='#5B69A6'> $title </th>
        </tr>";

  // count number of items
  $items = sizeof($list);
  if($items == 0)
    echo "<tr>
         <td colspan = ".(1+$actions)."align = center>No Items to Display</td>
         </tr>";
  else
  {
    // print each row
    for($i = 0; $items; $i++)
    {
      if($i%2) // background colors alternate
        $bgcolor = "'#ffffff'";
      else
        $bgcolor = "'#ccccff'";
      echo "<tr
            <td bgcolor = $bgcolor
             width = ". ($table_width - ($actions*149)) .">";
      echo $list[$i][1]; 
      if($list[$i][2])
        echo " - ".$list[$i][2];
      echo "</td>";

      // create buttons for up to three actions per line
      for($j = 1; $j<=3; $j++)
      {
        $var = 'action'.$j;
        if($$var)
        {
          echo "<td bgcolor = $bgcolor width = 149>";
          // view/preview buttons are a special case as they link to a file
          if($$var == 'preview-html'||$$var == 'view-html'||
             $$var == 'preview-text'||$$var == 'view-text')
            display_preview_button($list[$i][3], $list[$i][0], $$var);
          else
            display_button( $$var, "&id=" . $list[$i][0] );
          echo "</td>";
        }
      }
      echo "</tr>\ n";
    }
    echo "</table>";
  }
}

This function will output a table of items, with each item having up to three associated action buttons. The function expects five parameters, which are, in order:

We could, as an alternative, have used keywords as indices to the array.

The third, fourth, and fifth parameters to the function are used to pass in three actions that will be displayed on buttons corresponding to each item. In Figure 28.7, these are the three action buttons shown as Information, Show Archive, and Subscribe.

We got these three buttons for the Show All Lists page by passing in the action names, information, show-archive, and subscribe. By using the display_button() function, these actions have been turned into buttons with those words on them, and the appropriate action assigned to them.

Each of the Show actions calls the display_items() function in a different way, as you can see by looking back at their actions. As well as having different titles and action buttons, each of the three uses a different function to build the array of items to display. Show All Lists uses the function get_all_lists(), Show Other Lists uses the function get_unsubscribed_ lists(), and Show My Lists uses the function get_subscribed_lists(). All these functions work in a similar fashion. They are all from the mlm_fns.php function library.

We'll look at get_unsubscribed_lists() because that's the example we've followed so far. The code for the get_unsubscribed_lists() function is shown in Listing 28.7.

Listing 28.7 get_unsubscribed_lists() Function from mlm_fns.php—This Function Is Used to Build an Array of Mailing Lists That a User Is Not Subscribed To
function get_unsubscribed_lists($email)
{
  $list = array();

  $query = "select lists.listid, listname, email from lists left join sub_lists
                   on lists.listid = sub_lists.listid
                   and email='$email'where email is NULL order by listname";
  if(db_connect())
  {
    $result = mysql_query($query);
    if(!$result)
      echo "<p>Unable to get list from database.";
    $num = mysql_numrows($result);
    for($i = 0; $i<$num; $i++)
    {
      array_push($list, array(mysql_result($result, $i, 0),
                 mysql_result($result, $i, 1)));
    }
  }
  return $list;
}

As you can see, this function requires an email address passed into it. This should be the email address of the subscriber that we are working with. The get_subscribed_lists() function also requires an email address as a parameter, but the get_all_lists() function does not for obvious reasons.

Given a subscriber's email address, we connect to the database and fetch all the lists the subscriber is not subscribed to. As usual for this kind of query in MySQL, we use a LEFT JOIN to find unmatched items.

We loop through the result and build the array row by row using the array_push() built-in function.

Now that we know how this list is produced, let's look at the action buttons associated with these displays.

Viewing List Information

The Information button shown in Figure 28.7 triggers the 'information' action, which is as follows:

						
case 'information':
    {
      display_information($id);
      break;
    }

					

To see what the display_information() function does, look at Figure 28.8.

Figure 28.8. The display_information() function shows a blurb about a mailing list.
graphics/28fig08.gif

The function displays some general information about a particular mailing list, as well as listing the number of subscribers and the number of newsletters that have been sent out to that list and are available in the archive (more on that in a minute).

The code for this function is shown in Listing 28.8.

Listing 28.8 display_information() Function from output_fns.php—This Function Displays List Information
function display_information($listid)
{
  if(!$listid)
    return false;
  $info = load_list_info($listid);

  if($info)
  {
    echo "<h2>".pretty($info[listname])."</h2>";
    echo '<p>'.pretty($info[blurb]);
    echo '<p>Number of subscribers:'. $info[subscribers];
    echo '<p>Number of messages in archive:'. $info[archive];
  }
}

The display_information() function uses two other functions to help it achieve its Web task: the load_list_info() function and the pretty() function. The load_list_info() function actually retrieves the data from the database. The pretty() function simply formats the data from the database by stripping out slashes, turning newlines into HTML line breaks, and so on.

Let's look briefly at the load_list_info() function. This function is in the mlm_fns.php function library. The code for it is shown in Listing 28.9.

Listing 28.9 load_list_info() Function from mlm_fns.php—This Function Builds an Array of List Information
function load_list_info($listid)
{
  if(!$listid)
    return false;

  if(!db_connect())
    return false;

  $query = "select listname, blurb from lists where listid = $listid";
  $result = mysql_query($query);
  if(!$result) 
  {
    echo "Cannot retrieve this list";
    return false;
  }
  $info =  mysql_fetch_array($result);

  $query = "select count(*) from sub_lists where listid = $listid";
  $result = mysql_query($query);
  if($result)
  {
    $info['subscribers'] = mysql_result($result, 0, 0);
  }

  $query = "select count(*) from mail where listid = $listid
            and status = 'SENT'";
  $result = mysql_query($query);
  if($result)
  {
    $info['archive'] = mysql_result($result, 0, 0);
  }
  return $info;
}

This function runs three database queries to collect the name and blurb for a list from the lists table; the number of subscribers from the sub_lists table; and the number of newsletters sent from the mail table.

Viewing List Archives

In addition to viewing the list blurb, users can look at all the mail that has been sent to a mailing list by clicking on the Show Archive button. This activates the show-archive action, which triggers the following code:

						
case 'show-archive':
{
  display_items("Archive For ".get_list_name($id),
                 get_archive($id), 'view-html', 'view-text', '');
  break;
}

					

Again, this function uses the display_items() function to list out the various items of mail that have been sent to the list. These items are retrieved using the get_archive() function from mlm_fns.php. This function is shown in Listing 28.10.

Listing 28.10 get_archive() Function from mlm_fns.php—This Function Builds an Array of Archived Newsletters for a Given List
function get_archive($listid)
{
  //returns an array of the archived mail for this list
  //array has rows like (mailid, subject)

  $list = array();
  $listname = get_list_name($listid);
  $query = "select mailid, subject, listid from mail
            where listid = $listid and status = 'SENT'order by sent";

  if(db_connect())
  {
    $result = mysql_query($query);
    if(!$result)
    {
      echo "<p>Unable to get list from database - $query.";
      return false;
    }
    $num = mysql_numrows($result);
    for($i = 0; $i<$num; $i++)
    {
      $row = array(mysql_result($result, $i, 0),
                   mysql_result($result, $i, 1), $listname, $listid);
      array_push($list, $row);
    }
  }
  return $list;
}

Again, this function gets the required information—in this case, the details of mail that has been sent—from the database and builds an array suitable for passing to the display_items() function.

Subscribing and Unsubscribing

On the list of mailing lists shown in Figure 28.7, each list has a button that enables users to subscribe to it. Similarly, if users use the Show My Lists option to see the lists to which they are already subscribed, they will see an Unsubscribe button next to each list.

These buttons activate the subscribe and unsubscribe actions, which trigger the following two pieces of code, respectively:

						
  case 'subscribe':
  {
    subscribe(get_email(), $id);
    display_items("Subscribed Lists", get_subscribed_lists(get_email()),
                    'information', 'show-archive', 'unsubscribe');
    break;
  }
  case 'unsubscribe' :
  {
    unsubscribe(get_email(), $id);
    display_items("Subscribed Lists", get_subscribed_lists(get_email()),
                  'information', 'show-archive', 'unsubscribe');
    break;
  }

					

In each case, we call a function (subscribe() or unsubscribe()) and then redisplay a list of mailing lists the user is now subscribed to using the display_items() function again.

The subscribe() and unsubscribe() functions are shown in Listing 28.11.

Listing 28.11 subscribe() and unsubscribe() Functions from mlm_fns.php—These Functions Add and Remove Subscriptions for a User
function subscribe($email, $listid)
{
  if(!$email||!$listid||!list_exists($listid)||!subscriber_exists($email))
    return false; 

 //if already subscribed exit
 if(subscribed($email, $listid))
   return false;

 if(!db_connect())
    return false;

 $query = "insert into sub_lists values ('$email', $listid)";

 $result = mysql_query($query);
        return $result;
}

function unsubscribe($email, $listid)
{
  if(!$email||!$listid)
    return false;

  if(!db_connect())
    return false;

 $query = "delete from sub_lists where email = '$email'and listid = $listid";
 $result = mysql_query($query); 
  return $result;
}

The subscribe() function adds a row to the sub_lists table corresponding to the subscription; the unsubscribe() function deletes this row.

Changing Account Settings

The Account Settings button, when clicked, activates the account-settings action. The code for this action is as follows:

						
case 'account-settings':
{
  display_account_form($normal_user, $admin_user, get_email(),
        get_real_name(get_email()), get_mimetype(get_email()));
  break;
}

					

As you can see, we are reusing the display_account_form() function that we used to create the account in the first place. However, this time we are passing in the user's current details, which will be displayed in the form for easy editing. When the user clicks on the submit button in this form, the store-account action is activated as discussed previously.

Changing Passwords

Clicking on the Change Password button activates the change-password action, which triggers the following code:

						
case 'change-password' :
{
  display_password_form();
  break;
}

					

The display_password_form() function (from the output_fns.php library) simply displays a form for the user to change his password. This form is shown in Figure 28.9.

Figure 28.9. The display_password_form() function enables users to change their passwords.
graphics/28fig09.gif

When a user clicks on the Change Password button at the bottom of this form, the store-change-password action will be activated. The code for this is as follows:

						
case 'store-change-password' :
{
  if(change_password(get_email(), $old_passwd,
     $new_passwd, $new_passwd2))
  {
    echo "<p>OK: Password changed.<br><br><br><br><br><br>";
  }
  else
  {
    echo "<p>Sorry, your password could not be changed.";
    display_password_form();
  }
  break;
}

					

As you can see, this code tries to change the password using the change_password() function and reports success or failure to the user. The change_password() function can be found in the user_auth_fns.php function library. The code for this function is shown in Listing 28.12.

Listing 28.12 change_password() Function from user_auth_fns.php—This Function Validates and Updates a User's Password
function change_password($email, $old_password, $new_password,
                         $new_password_conf)
// change password for email/old_password to new_password
// return true or false
{
  // if the old password is right
  // change their password to new_password and return true
  // else return false
  if (login($email, $old_password))
  {
    if($new_password==$new_password_conf)
    {
      if (!($conn = db_connect()))
        return false;
      $query = "update subscribers
               set password = password('$new_password')
               where email = '$email'";
      $result = mysql_query($query);
      return $result;
    }
    else
      echo "<p> Your passwords do not match.";
  }
  else
    echo "<p> Your old password is incorrect.";

  return false; // old password was wrong
}

This function is similar to other password setting and changing functions we have looked at. It compares the two new passwords entered by the user to make sure they are the same, and if they are, tries to update the user's password in the database.

Logging Out

When a user clicks on the Log Out button, it triggers the log-out action. The code executed by this action in the main script is actually in the preprocessing section of the script, as follows:

						
if($action == 'log-out')
{
  session_destroy();
unset($action);
  unset($normal_user);
  unset($admin_user);
}

					

This snippet of code disposes of the session variables and destroys the session. Notice that it also unsets the $action variable—this means that we enter the main case statement without an action, triggering the following code:

						
case '':
{
  if(!check_logged_in())
    display_login_form($action);
  break;
}

					

This will allow another user to log in, or allow the user to log in as someone else.

only for RuBoard - do not distribute or recompile Previous Section Next Section