I needed to be able to create separate Node Hierarchies for my (sub)domains. When I tried creating a page, nodehiearchy simply consolidated all the nodes into one level. I finally figured out the "problem". I'm sure there's a valid reason for why this is, but I haven't found it yet. So if this helps any of you that have both these module and can't live without either.... wonderful :)

And just out of curiousity, is there any plans to integrate Domain Access into Node Hierarchy?

I ended up replacing both LEFT JOIN with JOIN to allow Domain Access (prefix) to work properly. Each domain has prefixed tables for {menu_links} and {nodehierarchy_menu_links}. This allows the {node} table to keep unique nids for all content (required for searching and why I didn't simply prefix {node}) while maintaining separate nodehierarchy per domain.

Unfortunately I do not know how to do patching, so I hope this suffices.

6.x-2.x-dev (2010-Feb-14): nodehierarchy.module
1449: function _nodehierarchy_parent_options($child_type, $exclude = NULL) {
... code
-1469: LEFT JOIN {nodehierarchy_menu_links} nh_parent
+1469: JOIN {nodehierarchy_menu_links} nh_parent
-1471: LEFT JOIN {menu_links} ml
+1471: JOIN {menu_links} ml
... code
1477: }

CommentFileSizeAuthor
#7 nodehierarchy.module.750002.patch2.37 KBmarkhalliwell

Comments

markhalliwell’s picture

Status: Active » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

ronan’s picture

Priority: Normal » Critical
Status: Closed (fixed) » Active

I've discovered an issue with this.

By switching the Joins from a LEFT (outer) JOIN to a (inner) JOIN you we are not getting the same results. I was using an outer join so that items could be assigned as parents even if they do not already have a node-hierarchy menu item created yet (it is created automatically when the child node is saved). This change makes it impossible to assign as a parent any top-level node which is not visible in the menu.

Mark: if you could explain how switching the JOIN helped your use case we may be able to figure out a way to solve both needs, otherwise I'll have to roll back this change.

Thanks

markhalliwell’s picture

Sorry, I thought this was stable when I committed. I can see now why you did what you did. I had changed this because I needed Domain Access to work properly on my site and the only thing I could figure out at the time was to take out the LEFTs in the JOINS.

I have created a prefixed table for each subdomain (ie: domain_3_nodehierarchy_menu_links). This is needed to provide a separate hierarchy for each site, without sacrificing and prefix the node table (mainly because of how our search works). This is a more proper way to add support for Domain Access and I believe I have found a solution:

/**
 * Return a list of menu items that are valid possible parents for the given node.
 */
function _nodehierarchy_parent_options($child_type, $exclude = NULL) {
  static $options = array();

  // If these options have already been generated, then return that saved version.
  if (isset($options[$child_type][$exclude])) {
    return $options[$child_type][$exclude];
  }

  // Get all the possible parents.
  $types = nodehierarchy_get_allowed_parent_types();
  foreach ($types as $i => $type) {
    $types[$i] = "'$type'";
  }

  // Get the items with menu links.
  $items = $mlids = array();
  if ($types) {
    
    // 2010/06/29
    // Added Domain Access support
    //
    if (module_exists('domain')){
      global $_domain;
      $domain = array();
      $domain['join'] = "LEFT JOIN {domain_access} da ON da.nid = n.nid";
      $domain['where'] = "da.gid = '" . $_domain['domain_id'] . "' AND ";
    }
    $result = db_query(
        "SELECT n.nid, n.type as type, n.title as title, n.uid as uid, ml.*,
                IF(depth IS NULL, 1, depth) as depth, IF(ml.mlid IS NULL, CONCAT('nid:', n.nid), ml.mlid) as mlid, ml.mlid as linkid
           FROM {node} n
      LEFT JOIN {nodehierarchy_menu_links} nh_parent
             ON nh_parent.nid = n.nid
      LEFT JOIN {menu_links} ml
             ON ml.mlid = nh_parent.mlid
      " . ($domain ? $domain['join'] : '') . "
          WHERE " . ($domain ? $domain['where'] : '') . "(ml.module = 'nodehierarchy' OR ml.module IS NULL)
            AND n.type IN (". implode(', ', $types) .")
          ORDER BY IF(p1 IS NULL, n.created, 0) ASC, p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC, p6 ASC, p7 ASC, p8 ASC, p9 ASC"
    );
  }

  // Flatten tree to a list of options.
  $parent_types = nodehierarchy_get_allowed_parent_types($child_type);
  $out = nodehierarchy_tree_data($result, $exclude, $parent_types);

  // Static caching to prevent these options being built more than once.
  $options[$child_type][$exclude] = $out;
  return $out;
}
markhalliwell’s picture

Status: Active » Needs review
dgorton’s picture

Priority: Critical » Normal
Status: Needs review » Needs work

Hrmmm. This seems a bit edge-casey. Rolled this back in latest dev so that the module still works without Domain_access installed. Let's try for a more generalized solution that isn't an 'if' on domain being installed.

markhalliwell’s picture

Status: Needs work » Patch (to be ported)
StatusFileSize
new2.37 KB

You need an "if" to provide support for those who have domain installed and enabled and those who don't. "if" it exists, then we restrict the nodes that are assigned to the current domain by including the domain specific SQL. If it doesn't, then we don't include the domain specific SQL and the query is untouched. This is pretty standard "support" in my opinion.

markhalliwell’s picture

Status: Patch (to be ported) » Reviewed & tested by the community
markhalliwell’s picture

Could you maybe elaborate a little more of what you mean. I don't mind coming up with a better solution if I get the general idea, but for now this seems appropriate.

markhalliwell’s picture

Status: Reviewed & tested by the community » Closed (duplicate)

setting as dup of #921198: Rework administration and node create/edit with new features and clean design

A much simpler method has been implemented (less than 3 lines).