1. Trang chủ
  2. » Công Nghệ Thông Tin

Phát triển web với PHP và MySQL - p 76 pot

10 126 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

the first level articles, which have no parent. After the tree has been constructed, we simply call its display function to actually display the list of articles. Using the treenode Class The code for the treenode class is shown in Listing 29.5. (You might find it useful at this stage to look over Chapter 6, “Object Oriented PHP,” to remind yourself how classes work.) LISTING 29.5 treenode Class from treenode_class.php—The Backbone of the Application <? // functions for loading, contructing and // displaying the tree are in this file class treenode { // each node in the tree has member variables containing // all the data for a post except the body of the message var $m_postid; var $m_title; var $m_poster; var $m_posted; var $m_children; var $m_childlist; var $m_depth; function treenode($postid, $title, $poster, $posted, $children, $expand, $depth, $expanded, $sublist) { // the constructor sets up the member variables, but more // importantly recursively creates lower parts of the tree $this->m_postid = $postid; $this->m_title = $title; $this->m_poster = $poster; $this->m_posted = $posted; $this->m_children =$children; $this->m_childlist = array(); $this->m_depth = $depth; // we only care what is below this node if it // has children and is marked to be expanded // sublists are always expanded if(($sublist||$expand) && $children) { $conn = db_connect(); Building Web Forums C HAPTER 29 29 BUILDING WEB FORUMS 725 35 7842 CH29 3/6/01 3:34 PM Page 725 $query = “select * from header where parent = $postid order by posted”; $result = mysql_query($query); for ($count=0; $row = @mysql_fetch_array($result); $count++) { if($sublist||$expanded[ $row[‘postid’] ] == true) $expand = true; else $expand = false; $this->m_childlist[$count]= new treenode($row[‘postid’],$row[‘title’], $row[‘poster’],$row[‘posted’], $row[‘children’], $expand, $depth+1, $expanded, $sublist); } } } function display($row, $sublist = false) { // as this is an object, it is responsible for displaying itself // $row tells us what row of the display we are up to // so we know what color it should be // $sublist tells us whether we are on the main page // or the message page. Message pages should have // $sublist = true. // On a sublist, all messages are expanded and there are // no “+” or “-” symbols. // if this is the empty root node skip displaying if($this->m_depth>-1) { //color alternate rows echo “<tr><td bgcolor = “; if ($row%2) echo “‘#cccccc’>”; else echo “‘#ffffff’>”; // indent replies to the depth of nesting for($i = 0; $i<$this->m_depth; $i++) { echo “<img src = ‘images/spacer.gif’ height = 22 width = 22 alt = ‘’ valign = bottom>”; } Building Practical PHP and MySQL Projects P ART V 726 LISTING 29.5 Continued 35 7842 CH29 3/6/01 3:34 PM Page 726 // display + or - or a spacer if ( !$sublist && $this->m_children && sizeof($this->m_childlist)) // we’re on the main page, have some children, and they’re expanded { // we are expanded - offer button to collapse echo “<a href = ‘index.php?collapse=”. $this->m_postid.”#$this->m_postid’ ><img src = ‘images/minus.gif’ valign = bottom height = 22 width = 22 alt = ‘Collapse Thread’ border = 0></a>”; } else if(!$sublist && $this->m_children) { // we are collapsed - offer button to expand echo “<a href = ‘index.php?expand=”. $this->m_postid.”#$this->m_postid’><img src = ‘images/plus.gif’ height = 22 width = 22 alt = ‘Expand Thread’ border = 0></a>”; } else { // we have no children, or are in a sublist, do not give button echo “<img src = ‘images/spacer.gif’ height = 22 width = 22 alt = ‘’valign = bottom>”; } echo “ <a name = $this->m_postid ><a href = ‘view_post.php?postid=$this->m_postid’>$this->m_title - $this->m_poster - “.reformat_date($this->m_posted).”</a>”; echo “</td></tr>”; // increment row counter to alternate colors $row++; } // call display on each of this node’s children // note a node will only have children in its list if expanded $num_children = sizeof($this->m_childlist); for($i = 0; $i<$num_children; $i++) { $row = $this->m_childlist[$i]->display($row, $sublist); } return $row; } }; ?> Building Web Forums C HAPTER 29 29 BUILDING WEB FORUMS 727 LISTING 29.5 Continued 35 7842 CH29 3/6/01 3:34 PM Page 727 This class contains the functionality that drives the tree view in this application. One instance of the treenode class contains details about a single posting and links to all the reply postings of that class. This gives us the following member variables: var $m_postid; var $m_title; var $m_poster; var $m_posted; var $m_children; var $m_childlist; var $m_depth; Notice that the treenode does not contain the body of the article. There is no need to load this until a user goes to the view_post.php script. We need to try to make this relatively fast, as we are doing a lot of data manipulation to display the tree list, and need to recalculate when the page is refreshed, or a button is pressed. The naming scheme for these variables follows a naming scheme commonly used in OO appli- cations—starting variables with m_ to remind us that they are member variables of the class. Most of these variables correspond directly to rows from the header table in our database. The exceptions are $m_childlist and $m_depth. We will use the variable $m_childlist to hold the replies to this article. The variable $m_depth will hold the number of tree levels that we are down—this will be used for creating the display. The constructor function sets up the values of all the variables, as follows: function treenode($postid, $title, $poster, $posted, $children, $expand, $depth, $expanded, $sublist) { // the constructor sets up the member variables, but more // importantly recursively creates lower parts of the tree $this->m_postid = $postid; $this->m_title = $title; $this->m_poster = $poster; $this->m_posted = $posted; $this->m_children =$children; $this->m_childlist = array(); $this->m_depth = $depth; Building Practical PHP and MySQL Projects P ART V 728 35 7842 CH29 3/6/01 3:34 PM Page 728 When we construct the root treenode from display_tree() from the main page, we are actu- ally creating a -dummy node with no article associated with it. We pass in some initial values: $tree = new treenode($start, ‘’, ‘’, ‘’, 1, true, -1, $expanded, $sublist); This creates a root node with a $postid of zero. This can be used to find all the first-level postings because they have a parent of zero. We set the depth to -1 because this node isn’t actually part of the display. All the first-level postings will have a depth of zero, and be at the far left of the screen. Subsequent depths step towards the right. The most important thing that happens in this constructor is that the children nodes of this node are instantiated. We begin this process by checking if we need to expand the children nodes. We only perform this process if a node has some children, and we have elected to dis- play them: if(($sublist||$expand) && $children) { $conn = db_connect(); We then connect to the database, and retrieve all the child posts, as follows: $query = “select * from header where parent = $postid order by posted”; $result = mysql_query($query); We then fill the array $m_childlist with instances of the treenode class, containing the replies to the post stored in this treenode, as follows: for ($count=0; $row = @mysql_fetch_array($result); $count++) { if($sublist||$expanded[ $row[‘postid’] ] == true) $expand = true; else $expand = false; $this->m_childlist[$count]= new treenode($row[‘postid’],$row[‘title’], $row[‘poster’],$row[‘posted’], $row[‘children’], $expand, $depth+1, $expanded, $sublist); } This last line will create the new treenodes, following exactly the same process we have just walked through, but for the next level down the tree. This is the recursive part. A parent tree node is calling the treenode constructor, passing its own postid as parent, and adding one to its own depth before passing it. Each treenode in turn will be created and create its own children until we run out of replies or levels that we want to expand to. Building Web Forums C HAPTER 29 29 BUILDING WEB FORUMS 729 35 7842 CH29 3/6/01 3:34 PM Page 729 Building Practical PHP and MySQL Projects P ART V 730 After all that’s done, we call the root treenode’s display function (this is back in display_tree()), as follows: $tree->display($row, $sublist); The display() function begins by checking whether this is the dummy root node: if($this->m_depth>-1) In this way, the dummy can be left out of the display. We don’t want to completely skip the root node though. We do not want it to appear, but it needs to notify its children that they need to display themselves. The function then starts drawing the table containing the articles. It uses the modulus operator ( %) to decide what color background this row should have (hence they alternate): //color alternate rows echo “<tr><td bgcolor = “;if ($row%2) echo “‘#cccccc’>”; else echo “‘#ffffff’>”; It then uses the $m_depth member variable to work out how much to indent the current item. You will see by looking back at the figures that the deeper level a reply is on, the further it is indented. This is done as follows: // indent replies to the depth of nesting for($i = 0; $i<$this->m_depth; $i++) { echo “<img src = ‘images/spacer.gif’ height = 22 width = 22 alt = ‘’ valign = bottom>”; } The next part of the function works out whether to supply a plus or minus button or nothing at all: // display + or - or a spacer if ( !$sublist && $this->m_children && sizeof($this->m_childlist)) // we’re on the main page, have some children, and they’re expanded { // we are expanded - offer button to collapse echo “<a href = ‘index.php?collapse=”. $this->m_postid.”#$this->m_postid’ ><img src = ‘images/minus.gif’ valign = bottom height = 22 width = 22 alt = ‘Collapse Thread’ border = 0></a>”; } else if(!$sublist && $this->m_children) { 35 7842 CH29 3/6/01 3:34 PM Page 730 Building Web Forums C HAPTER 29 29 BUILDING WEB FORUMS 731 // we are collapsed - offer button to expand echo “<a href = ‘index.php?expand=”. $this->m_postid.”#$this->m_postid’><img src = ‘images/plus.gif’ height = 22 width = 22 alt = ‘Expand Thread’ border = 0></a>”; } else { // we have no children, or are in a sublist, do not give button echo “<img src = ‘images/spacer.gif’ height = 22 width = 22 alt = ‘’valign = bottom>”; } Next, we display the actual details of this node: echo “ <a name = $this->m_postid ><a href = ‘view_post.php?postid=$this->m_postid’>$this->m_title - $this->m_poster - “.reformat_date($this->m_posted).”</a>”; echo “</td></tr>”; We change the color for the next row: // increment row counter to alternate colors $row++; After that, there is some code that will be executed by all treenodes, including the root one, as follows: // call display on each of this node’s children // note a node will only have children in its list if expanded $num_children = sizeof($this->m_childlist); for($i = 0; $i<$num_children; $i++) { $row = $this->m_childlist[$i]->display($row, $sublist); } return $row; Again this is a recursive function call, which calls on each of this node’s children to display themselves. We pass them the current row color and get them to pass it back when they are fin- ished with it, so we can keep track of the alternating color. That’s it for this class. The code is fairly complex. You might like to experiment with running the application and then come back to look at it again when you are comfortable with what it does. Viewing Individual Articles The display_tree() call ends up giving us links to a set of articles. If we click one of these articles, we will go to the view_post.php script, with a parameter of the postid of the article to be viewed. Sample output from this script is shown in Figure 29.7. 35 7842 CH29 3/6/01 3:34 PM Page 731 FIGURE 29.7 We can now see the message body for this posting. This script shows us the message body, as well as the replies to this message. You will see that the replies are again displayed as a tree, but completely expanded this time, and without any plus or minus buttons. This is the effect of the $sublist switch coming into action. Let’s look at the code for view_post.php, shown in Listing 29.6. LISTING 29.6 view_post.php—Displays a Single Message Body <? // include function libraries include (‘include_fns.php’); // get post details $post = get_post($postid); do_html_header($post[“title”]); // display post display_post($post); // if post has any replies, show the tree view of them if($post[‘children’]) { Building Practical PHP and MySQL Projects P ART V 732 35 7842 CH29 3/6/01 3:34 PM Page 732 echo “<br><br>”; display_replies_line(); display_tree($expanded, 0, $postid); } do_html_footer(); ?> This script uses three main function calls to do its job: get_post(), display_post(), and display_tree(). The get_post() function pulls the function details out of the database. The code for this func- tion is shown in Listing 29.7. LISTING 29.7 get_post() Function from discussion_fns.php—Retrieves a Message from the Database function get_post($postid) { // extract one post from the database and return as an array if(!$postid) return false; $conn = db_connect(); //get all header information from ‘header’ $query = “select * from header where postid = $postid”; $result = mysql_query($query); if(mysql_numrows($result)!=1) return false; $post = mysql_fetch_array($result); // get message from body and add it to the previous result $query = “select * from body where postid = $postid”; $result2 = mysql_query($query); if(mysql_numrows($result2)>0) { $body = mysql_fetch_array($result2); if($body) { $post[‘message’] = $body[‘message’]; } } return $post; } Building Web Forums C HAPTER 29 29 BUILDING WEB FORUMS 733 LISTING 29.6 Continued 35 7842 CH29 3/6/01 3:34 PM Page 733 This function, given a postid, will perform the two queries required to retrieve the message header and body for that posting, and put them together into a single associative array which it then returns. The results of this function are then passed to the display_post() function from output_fns.php. This just prints out the array with some HTML formatting, so we have not included it here. Finally, the view_post.php script checks whether there are any replies to this article and calls display_tree() to show them in the sublist format—that is, fully expanded with no plusses or minuses. Adding New Articles After all that, we can now look at how a new post is added to the forum. A user can do this in two ways: first, by clicking on the New Post button in the index page, and second, by clicking on the Reply button on the view_post.php page. These actions both activate the same script, new_post.php, just with different parameters. Figure 29.8 shows the output from new_post.php when we have reached it by hitting the Reply button. Building Practical PHP and MySQL Projects P ART V 734 FIGURE 29.8 Replies have the text of the original automatically inserted and marked. 35 7842 CH29 3/6/01 3:34 PM Page 734 . script, new_post .php, just with different parameters. Figure 29.8 shows the output from new_post .php when we have reached it by hitting the Reply button. Building Practical PHP and MySQL Projects P ART. (‘include_fns .php ); // get post details $post = get_post($postid); do_html_header($post[“title”]); // display post display_post($post); // if post has any replies, show the tree view of them if($post[‘children’]) { Building. Practical PHP and MySQL Projects P ART V 726 LISTING 29.5 Continued 35 7842 CH29 3/6/01 3:34 PM Page 726 // display + or - or a spacer if ( !$sublist && $this->m_children && sizeof($this->m_childlist)) //

Ngày đăng: 06/07/2014, 19:20

Xem thêm: Phát triển web với PHP và MySQL - p 76 pot