Another thing that's been bugging me is that this whole structure
depends on there being a single root node in the MPTT. That's not
necessarily the case (in fact, it's probably unlikely to be the case).
Some of the manipulation functions of MPTTNode will need to be
replicated in MPTT (specifically, append() and prepend()) in order to
manipulate nodes that aren't child nodes.

On Nov 3, 9:48 am, drzax <[EMAIL PROTECTED]> wrote:
> Damn...thought I sent this on Friday. Oh well...
>
> That's starting to look really good, and well fleshed out. Thanks for
> sharing. I'm still not sure I've quite understood the MPTT
> constructor. What are the $table and $fields parameters for?
>
> This is looking excellent for working with things like nested
> categories (with each category containing a bunch of posts or pages),
> but I'm wondering if you've considered how it might be used to create
> a nested menu of pages (for example). That is, where the MPTTNodes
> aren't just a categorisation of another object, but represent a single
> other object in a 1-1 relationship. Also worth thinking about is the
> possibility that those other objects in the 1-1 relationship with
> records in the 'terms' table might be different types of object, all
> within one MPTT hierarchy.
>
> This kind of thing will obviously be possible (the DB structure
> already supports it) but I think it's definitely worth thinking about
> at this early stage and making sure the classes are easy to use in
> this manner, otherwise there will be teAmptation to go around the MPTT
> classes for specific purposes like (like building menus that contain a
> mix of content types, for example).
>
> I'm not sure I've explained what I mean there, particularly well, so
> if it unclear, let me know and I'll try harder. Looking forward to
> seeing the first commit and playing with the code.
>
> Cheers,
> Simon
>
> On Oct 30, 6:08 pm, Nathan Hammond <[EMAIL PROTECTED]> wrote:
>
> > In my work so far I've got it using a parent field. It just made more
> > sense to me from a speed perspective. Fortunately, the decision about
> > the final approach can be resolved later since that won't change the
> > interface, just the underlying code. I'll commit it as a branch, let
> > people test it, and see what they think.
>
> > Since I'm basing my approach off of JavaScript's DOM traversal methods
> > I've got three basic objects, described in detail below. In short, the
> > only concern of yours that I've not addressed, the appending being a
> > method of the node, is JavaScript's approach. You'll see below that
> > I'm trying very hard to craft something both intuitive and familiar. I
> > agree with you that since it is a bigger change in this model than in
> > the DOM approach (affecting all subsequent nodes) that it might
> > possibly be best to implement this as an invocation of an MPTT method,
> > but for now I'm sticking with JavaScript's approach as it is easier.
>
> > *ponder*
>
> > I do however retain a reference to the MPTT object on the node and I
> > guess it would be relatively trivial to alias the modification
> > functions back upstream to that object... (using a mixed JS and PHP
> > notation)
> > $node->remove() = function () { $this->mptt->remove($this); }
>
> > Bah, you're right, and I'll do it later. I only have to figure out how
> > I want to handle the MPTTSet stuff and then I'm done with r1. Which
> > means I can put it up so others can contribute and I won't hold things
> > up when I get distracted by the other project I'm working on (a
> > Dashboard widget to enable/disable a local caching DNS server in OS
> > X).
>
> > Thanks Simon! I really appreciate your input, I've made a number of
> > changes for the better because of it.
> > Nathan
>
> > ***
>
> > 1. MPTT. This stores the definition of the table and provides some
> > basic global methods. You can think of this like the document object
> > in JavaScript.
> > __constructor($table, $fields) - Takes $table and optionally $fields
> > to define the rules it is working under.
> > get_node($id) - (document.getElementById) - Takes a node ID.
> > create_node($paramarray) - (document.createElement) - Takes an
> > associative array to define necessary fields.
> > get_leaf_nodes() - (document.querySelectorAll) - Returns leaf nodes.
> > sort_level($related, $sortBy) - Passed either a MPTTNode or a node ID
> > and a sort clause.
> > replace_node($related, $new) - Passed either a MPTTNode or a node ID
> > and the new node.
> > move_node ($method, $related, $new) - Used to avoid traversal if you
> > already know everything you need.
>
> > 2. MPTTNode. This represents a specific node. It presently does not
> > extend QueryRecord, but now that you mention it, it will.
> > __constructor($mptt, $nodeInfo, $last) - (jQuery) - Takes a reference
> > to the defining MPTT object, this node's info, and the $last most
> > recent selection (for chaining).
>
> > /* Attributes */
> > depth() - Returns the depth of the current node.
>
> > /* Traversal, Chaining*/
> > end() - (jQuery().end()) - Returns the previous selection.
> > parent() - (jQuery.parent()) - Returns the parent of the current node.
> > child($n) - (jQuery.find(> :n)) - Returns the Nth child of the current
> > node.
> > prev() - (jQuery.prev()) - Returns the previous sibling of the current
> > node.
> > next() - (jQuery.next()) - Returns the next sibling of the current
> > node.
> > prevAll() - (jQuery.prevAll()) - Returns all previous siblings.
> > nextAll() - (jQuery.nextAll()) - Returns all following siblings.
> > siblings() - (jQuery.siblings()) - Returns all siblings.
> > children() - (jQuery.children()) - Returns all children.
> > ancestors() - (jQuery.ancestors() - with a plugin I wrote for jQuery)
> > - Returns all ancestors.
> > descendants() - (jQuery.descendants() - with a plugin I wrote for
> > jQuery) - Returns all descendants.
> > andSelf() - (jQuery.andSelf()) - Returns $last merged with current.
>
> > /*Modification*/
> > append($node, $sort = false) - (document.element.appendChild())
> > append_to($node, $sort = false) - (document.element.appendChild())
> > insert_before - (document.element.insertBefore())
> > insert_after - (document.element.insertAfter()) (often prototyped in)
> > remove - (document.element.removeChild())
>
> > 3. MPTTSet. This extends ArrayObject right now and I've not fully
> > fleshed it out (which is why I've not asked for a branch yet). The
> > basic idea is that it will provide some of the base level
> > functionality that MPTTNode does (end(), in particular) and then
> > determine how to handle other functions accordingly.
>
> > On Oct 29, 7:15 am, drzax <[EMAIL PROTECTED]> wrote:
>
> > > Hi Nathan,
>
> > > I've been thinking about this sporadically over the past couple of
> > > weeks and I'm keen to see if you've made any progress. I have a couple
> > > of questions about your proposed solution, which (aside from my
> > > previous points) I quite like the look of.
>
> > > First of all this line:
>
> > > $mptt = new MPTT( array( 'table' => 'mytree' ) );
>
> > > I've assumed (maybe incorrectly) that an instance of the MPTT class
> > > basically represents a record in the vocabularies table. If I'm right
> > > with that assumption:
> > > - will it extend QueryRecord?
> > > - what is the data being passed to the constructor?
>
> > > Also, I've assumed that MPTTNode essentially represents a record in
> > > the terms table.
>
> > > In relation to this line:
> > > $return = $mptt->get_node(27)->parent()->child(0)->append($mptt-
>
> > > >create_node( array( 'slug' => 'javascript' ) ));
>
> > > This seems to indicate that append(MPTTNode) is a method of the
> > > MPTTNode class, which doesn't quite add up. Given that (almost) every
> > > append action will necessarily involve manipulation of more than one
> > > node in the tree, shouldn't the append method be part of the MPTT
> > > class?
>
> > > None of this is by way of criticism, just looking to clarify your
> > > thoughts. I'm looking forward to seeing your implementation of this.
> > > BTW, did anyone make a decision re: the parent field?
>
> > > Cheers,
> > > Simon
>
> > > On Oct 17, 6:06 am, Nathan Hammond <[EMAIL PROTECTED]> wrote:
>
> > > > Regardless of the eventual underlying implementation in terms of
> > > > adjacency or MPTT, here is the syntax I'm coming up with:
>
> > > > $mptt = new MPTT( array( 'table' => 'mytree' ) );
> > > > $return = $mptt->get_node(27)->parent()->child(0)->append($mptt-
>
> > > > >create_node( array( 'slug' => 'javascript' ) ));
>
> > > > The way to describe that:
> > > > 1. From the MPTT object defined by the table mytree;
> > > > 2. Get node id 27;
> > > > 3. Get node 27's parent;
> > > > 4. Get the first child of node 27's parent;
> > > > 5. Append the node that is created by the same MPTT object to the
> > > > first child of node 27's parent.
> > > > 6. Assign the return value of the last operation (the most recently
> > > > touched node, in this case the new one) to $return.
>
> > > > Of course, that is *way* overkill and anybody who is fiddling with
> > > > their MPTT tree in that manner might need to get their head looked at.
> > > > However, I'd rather enable that degree of complexity to be easily
> > > > accomplished so that nobody has any need to modify this base class. By
> > > > creating such an easy to use API I think we'd manage to avoid the
> > > > problem of somebody wanting to directly fiddle with the tables.
> > > > Hopefully.
>
> > > > In any case, I'm basing this syntactical design off of JavaScript, and
> > > > jQuery in particular, as that is my primary expertise. To accomplish
> > > > this I am writing two classes: MPTT, representing the entire tree; and
> > > > MPTTNode, representing just a specific node from that tree. Tree level
> > > > operations (in general, operations performed on more than one node)
> > > > are methods of the MPTT class. Node manipulation is handled by methods
> > > > in the MPTTNode class. There may eventually be a third class as well,
> > > > MPTTSet, which could be used to handle applying actions to all nodes
> > > > currently selected (basically an enumerator), we'll see.
>
> > > > Any comments on this approach?
> > > > Nathan
--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/habari-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to