PhpRiot
Download This Article
Download this article or the entire “Implementing An N-Level Nested Tree In PHP And PostgreSQL” series with all listings and files.




More information
Related Books
Professional Linux Programming

Professional Linux Programming

As Linux increases its presence throughout the world as a target platform for professional...
Browse Articles
Ajax (4), APC (1), CAPTCHA (1), CSS (3), Debugging (1), File Upload (1), Google (3), Google Maps (2), JavaScript (12), JSON (2), MVC (1), MySQL (7), onbeforeunload (1), OOP (1), PHP (28), PhpDoc (1), PostgreSQL (6), Prototype (11), Reflection (1), RFC 1867 (1), Robots (1), Scriptaculous (1), SEO (1), Sessions (1), SimpleXML (1), Smarty (5), SOAP (1), SPL (1), Templates (2), W3C (1), XHTML (1), Zend Framework (1), Zend_Search_Lucene (1)

PhpRiot Newsletter
Your Email Address:

Implementing An N-Level Nested Tree In PHP And PostgreSQL, Part 2

Some Utility Functions

Here are a few functions that are used to find out various metadata about the tree.

Check if a node descends from another node

This function checks if one node descends from another node.

Listing 8 NestedTree.class.php
<?php
    class NestedTree
    {
        // ... other code ...
 
        /**
         * Check if one node descends from another node. If either node is not
         * found, then false is returned.
         *
         * @param   int     $descendant_id  The node that potentially descends
         * @param   int     $ancestor_id    The node that is potentially descended from
         * @return  bool                    True if $descendant_id descends from $ancestor_id, false otherwise
         */
        function isDescendantOf($descendant_id, $ancestor_id)
        {
            $node = $this->getNode($ancestor_id);
            if (is_null($node))
                return false;
 
            $query = sprintf('select count(*) as is_descendant
                                  from %s
                                  where %s = %d
                                  and nleft > %d
                                  and nright < %d',
                             $this->table,
                             $this->fields['id'],
                             $descendant_id,
                             $node->nleft,
                             $node->nright);
 
            $result = pg_query($query);
 
            if ($row = pg_fetch_object($result)) {
                return $row->is_descendant > 0;
            }
 
            return false;
        }
 
        // ... other code ...
    }
?>

Check if a node is a child of another another node

This function checks if one node is a child of another node.

Listing 9 NestedTree.class.php
<?php
    class NestedTree
    {
        // ... other code ...
 
        /**
         * Check if one node is a child of another node. If either node is not
         * found, then false is returned.
         *
         * @param   int     $child_id       The node that is possibly a child
         * @param   int     $parent_id      The node that is possibly a parent
         * @return  bool                    True if $child_id is a child of $parent_id, false otherwise
         */
        function isChildOf($child_id, $parent_id)
        {
            $query = sprintf('select count(*) as is_child from %s where %s = %d and %s = %d',
                             $this->table,
                             $this->fields['id'],
                             $child_id,
                             $this->fields['parent'],
                             $parent_id);
 
            $result = pg_query($query);
 
            if ($row = pg_fetch_object($result)) {
                return $row->is_child > 0;
            }
 
            return false;
        }
 
        // ... other code ...
    }
?>

Find the number of descendants a node has

Using the nleft and nright values of a node, we can determine how many descendants it has. Remembering from the first article in this series, we can determine this using (nright – nleft – 1) / 2.

Listing 10 NestedTree.class.php
<?php
    class NestedTree
    {
        // ... other code ...
 
        /**
         * Find the number of descendants a node has
         *
         * @param   int     $id     The ID of the node to search for. Pass 0 to count all nodes in the tree.
         * @return  int             The number of descendants the node has, or -1 if the node isn't found.
         */
        function numDescendants($id)
        {
            if ($id == 0) {
                $query = sprintf('select count(*) as num_descendants from %s', $this->table);
                $result = pg_query($query);
                if ($row = pg_fetch_object($result))
                    return (int) $row->num_descendants;
            }
            else {
                $node = $this->getNode($id);
                if (!is_null($node)) {
                    return ($node->nright - $node->nleft - 1) / 2;
                }
            }
            return -1;
        }
 
        // ... other code ...
    }
?>

Finding the number of children a node has is also fairly simple – all we need to do is count the number of nodes that have a parent_id equal to the ID of the passed node.

Listing 11 NestedTree.class.php
<?php
    class NestedTree
    {
        // ... other code ...
 
        /**
         * Find the number of children a node has
         *
         * @param   int     $id     The ID of the node to search for. Pass 0 to count the first level items
         * @return  int             The number of descendants the node has, or -1 if the node isn't found.
         */
        function numChildren($id)
        {
            $query = sprintf('select count(*) as num_children from %s where %s = %d',
                             $this->table,
                             $this->fields['parent'],
                             $id);
            $result = pg_query($query);
            if ($row = pg_fetch_object($result))
                return (int) $row->num_children;
 
            return -1;
        }
 
        // ... other code ...
    }
?>

Whew. Now that we’ve gotten through all that – we just need the write the functions that build the tree data! Mind you, these are probably the most complicated functions in class. Anyway, on to it…

In This Article


Tagged in , ,