Location: PHPKode > scripts > DOMXML guestbook > domxml-guestbook/class.xml.php
<?php
/**
 * $Id: class.xml.php,v0.1 2005/01/30 16:36:22 stan_f  Exp $
 * Class encapsulating XML messages storage for a guestbook
 * Performs all basic operations that should be available to manage messages
 * This is free software distributed under the terms of GPL. 
 * You can modify the source to fit your purposes.
 *
 * Found that PHP 5.0.3 isn't too solid working with DOMXML. Some of necessary
 * methods are not implemented yet and the old ones are history. There's lack of docs,
 * so one has to guess HOW and WHAT to use :=(
 *
 * @project   XML_Guestbook
 * @author    Stan F <hide@address.com>
 * @site      http://northernsun.spb.ru
 * @depends   none
 * @platform  *nix/win32, designed for PHP4 and for sure incompatible with PHP5
 */

/**
 * Class representing one message. This is to create some logic in passing info to ANY
 * message handler that I plan to implement in the future ( not only XML, but also FILE and DB )
 * It isn't well documented cuz I think everything here is pretty transparent.
 */

class CommonMessage{
    var $id;
    var $stat;
    var $name;
    var $ip;
    var $date;
    var $email;
    var $url;
    var $msg;
    var $_init = false;
    // Constructor/PHP4
    function CommonMessage( $stat, $name, $ip,  $msg, $url = '', $email = '', $date = '', $id = 0 ){
        $this->id    = $id;
        $this->stat  = $stat;
        $this->name  = $name;
        $this->ip    = $ip;
        $this->date  = $date;
        $this->email = $email;
        $this->url   = $url;
        $this->msg   = $msg;
        // mark this instance initiated
        $this->_init();
    }
    // Init the object
    function _init(){
        $this->_init = true;
    }
    // Check the init
    function is_init(){
        return $this->_init;
    }
    // Encode the messages to keep em off breaking XML
    function encode(){
        $vars = get_object_vars( $this );
        foreach( $vars as $var_name=>$var_value ){
            $this->$var_name = htmlspecialchars( $var_value );
        }
    }
}

/**
 * Message Set class
 * Encapsulates all basic operations required to manage messages and interact with the XML storage
 * @var o_DOMDocument  XML_MessageSet::xmltree
 * @access             (should be ) private
 * @desc               Holds the XML document contents
 * @var string         XML_MessageSet::xmlfile
 * @access             (should be ) private
 * @desc               XML storage filename
 */
class XML_MessageSet{
    
    var $xmltree;
    var $xmlfile;
    
    //
    // Construct the XML tree from file
    // @param  string  $filename
    //
    function XML_MessageSet( $filename ){
        $this->xmlfile = $filename;
        $this->xmltree = domxml_open_file( $this->xmlfile );
    }
    
    //
    // Save back to XML file
    //
    function save(){
        $this->xmltree->dump_file( $this->xmlfile, false, true );
    }
    
    //
    // Return ID for the new message
    // @access  private
    //
    function _id(){
        $root = $this->xmltree->document_element();
        $posts = $root->get_elements_by_tagname( 'post' );
        $i = 0;
        $max_id = 0;
        // find maximal ID value
        while( !empty( $posts[$i] ) ){
            $mb = $posts[$i];
            $max_id = $mb->get_attribute( 'id' );
            $i++;
        }
        // increase max ID value by one to gain uniqueness and return it
        return $max_id + 1;
    }
    
    //
    // Add new message to XML tree
    // @param  o_CommonMessage  $msg
    // @desc CommonMessage instance containing full message info
    //
    function add( $msg ){
        // get new ID
        $id = $this->_id();
        // create new 'post' element
        $el = new DOMElement( 'post' );
        // set ID and date *attributes*
        $el->set_attribute( 'id', $id );
        $el->set_attribute( 'date', date('d.m.Y H:i:s') );
        // creating child nodes and appending 'em to post:
        $stat = new DOMNode( 'stat' );
        $stat->set_content( $msg->stat );
        $el->append_child( $stat );
        $name = new DOMNode( 'name' );
        $name->set_content( $msg->name );
        $el->append_child( $name );
        $ip = new DOMNode( 'ip' );
        $ip->set_content( $msg->ip );
        $el->append_child( $ip );
        $email = new DOMNode( 'email' );
        $email->set_content( $msg->email );
        $el->append_child( $email );
        $url = new DOMNode( 'url' );
        $url->set_content( $msg->url );
        $el->append_child( $url );
        $msg = new DOMNode( 'msg' );
        $msg->set_content( $msg->msg );
        $el->append_child( $msg );
        // tie the new post to XML tree
        $root = $this->xmltree->document_element();
        $root->append_child( $el );
    }
    
    //
    // Drop messages
    // @param  array  $drop
    // @desc   Get an array of integers and remove elements with matching IDs
    //
    function drop( $drop ){
        $root = $this->xmltree->document_element();
        $posts = $root->get_elements_by_tagname( 'post' );
        // loop through posts and get rid of ones with IDs contained in $drop
        foreach( $posts as $post ){
            if( in_array( $post->get_attribute('id'), $drop ) ){
                $root->remove_child( $post );
            }
        }
    }
    
    //
    // Replace messages with new ones: create updated node to replace 
    // the old one with, and replacement itself
    // @param  o_CommonMessage  $msg
    // @desc   New XML element. Note that the ID should be set to nonzero _explicitly_,
    //         or the replacement will probably fail! 
    //         Will replace the element with id == $msg::id.
    //
    function replace( $msg ){
        // The algorithm is much like XML_MessageSet::add(), but instead of blind tying
        // the new element will replace the old one. If ID doesn't match any existing one,
        // no changes done to the tree.
        // -------------------------------------------------------------------------------
        // create new 'post' element
        $root = $this->xmltree->document_element();
        $el = new DOMElement( 'post' );
        // set ID and date *attributes*
        $el->set_attribute( 'id', $msg->id );
        $el->set_attribute( 'date', $msg->date );
        // creating child nodes and appending 'em to post:
        $stat = new DOMNode( 'stat' );
        $stat->set_content( '3'.$msg->stat );
        $el->append_child( $stat );
        $name = new DOMNode( 'name' );
        $name->set_content( $msg->name );
        $el->append_child( $name );
        $ip = new DOMNode( 'ip' );
        $ip->set_content( $msg->ip );
        $el->append_child( $ip );
        $email = new DOMNode( 'email' );
        $email->set_content( $msg->email );
        $el->append_child( $email );
        $url = new DOMNode( 'url' );
        $url->set_content( $msg->url );
        $el->append_child( $url );
        // replace the existing post
        $old = $this->xmltree->get_elements_by_tagname( 'post' );
        foreach( $old as $old_one ){
            if( $old_one->get_attribute( 'id' ) == $msg->id ){
                // NOTE THAT THERE'S A MISTAKE IN THE DOCS
                // AND *THIS* ARGS ORDER IS THE RIGHT ONE!
                $root->replace_child( $el, $old_one );
            }
        }
    }
    
    //
    // Return array of CommonMessage objects
    // This way, all XML manipulations are just inside the class
    //
    function retrieve_messages_array(){
        $root = $this->xmltree->document_element();
        // Retrieve all posts
        $posts = $root->get_elements_by_tagname( 'post' );
        $nodenames = array( 'stat', 'name', 'ip', 'email', 'url', 'msg' );
        $posts_array = array();
        foreach( $posts as $post ){
            $id = $post->get_attribute( 'id' );
            $date = $post->get_attribute( 'date' );
            $name = ''; $stat = 0; $ip = ''; $email = ''; $url = ''; $msg = '';
            $children = $post->child_nodes();
            foreach( $children as $child ){
                $_tname = $child->node_name();
                if( in_array( $_tname, $nodenames ) ){
                    ${$_tname} = $child->get_content();
                }
            }
            $cmsg = new CommonMessage( $stat, $name, $ip,  $msg, $url, $email, $date, $id );
            $posts_array[] = $cmsg;
        }
        return $posts_array;
    }
    
    //
    // Installation: create empty XML file with root element
    // You can call it statically if you're lazy to create empty XML.
    //
    function install( $xmlfilename ){
        $xmldoc = domxml_new_doc( '1.0' );
        $xmldoc->add_root( 'guestbook' );
        $xmldoc->dump_file( $xmlfilename );
        echo "Now you can use file '$xmlfilename' as your XML storage.";
    }
    
}

?> 
Return current item: DOMXML guestbook