A taxonomy tree involving more than 5 nested categories can't be treated with the module.

CommentFileSizeAuthor
#6 ssu.png53.91 KBrconstantine
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

rconstantine’s picture

Status: Active » Needs review

Sorry folks. I'm going to be lazy and post the code changes inline, rather than attach a patch. You can shoot me later.

In taxonomy_super_select_form_alter, delete everything after

 // Go through each enabled vocab and create taxonomy super select
    foreach($valid_vocabs AS $vid => $input){
      // Get root terms for vocabulary only
      $terms = taxonomy_get_tree($vid, 0, -1, 1);
      $form['taxonomy'][$vid] = _tss_branch($vid, $vocabularies[$vid]);
      if($tags[$vid]){
        $form['taxonomy'][$vid]['tags'] = $tags[$vid];
      }

Take care to leave necessary closing braces.

Immediately after the code above and before the remaining braces, add this:

_tss_next_nested($terms, $vid, $input, $tss, $form['#node'], $form['taxonomy'][$vid]);

The function should end with three closing braces in case you deleted them.

Then add this function:

/**
 * Recursive function to allow infinite depth vocabularies.
 * 
 * @param array &$terms The result of taxonomy_get_tree for the vocabulary's $vid.
 * @param array &$vid The vocabulary to work on. Passed by reference just to keep overhead
 * of copies down.
 * @param array &$input The portion of the vocabulary to look at (parent_type?). Passed by
 * reference just to keep overhead of copies down.
 * @param array $tss These are the settings for this module.
 * @param array &$form_node This is a subsection of $form, namely $form['#node'] should be
 * passed in.
 * @param array &$form_branch This is a subsection of $form. Each iteration adds to the one
 * before, then passes itself as the new branch. _tss_branch() is called for each iteration
 * and appended to it. 
 * 
 * @return since values are passed in via reference, no return value is required.
 */
function _tss_next_nested(&$terms, &$vid, &$input, $tss, &$form_node, &$form_branch) {
  foreach($terms as $index => $term){
    $child = taxonomy_get_children($term->tid, $vid);
    if(count($child)){
      if($tss[$vid]['parents']){
        $term->is_parent = TRUE;
        $term->parent_type  = $input;
        $term->parent_value = $form_node->taxonomy[$term->tid]->tid;
      }
      $form_branch[$term->tid] = _tss_branch($vid, $term);
      _tss_next_nested($child, $vid, $input, $tss, $form_node, $form_branch[$term->tid]);
    }
    else{
      if($value =  $form_node->taxonomy[$term->tid]->tid){
        $form_branch[$term->tid]['#collapsed'] = FALSE;
      }
      $form_branch[$term->tid] = _tss_branch($vid, $term, $value, $input);
    }
  }
}

From my small testing session, everything seems to be the same as before in terms of function.

rconstantine’s picture

I should have checked other issues before posting, but---

I saw the alphabetizing patch at http://drupal.org/node/136319, so incorporated it. My new function should now be:

/**
 * Recursive function to allow infinite depth vocabularies.
 * 
 * @param array &$terms The result of taxonomy_get_tree for the vocabulary's $vid.
 * @param array &$vid The vocabulary to work on. Passed by reference just to keep overhead
 * of copies down.
 * @param array &$input The portion of the vocabulary to look at (parent_type?). Passed by
 * reference just to keep overhead of copies down.
 * @param array $tss These are the settings for this module.
 * @param array &$form_node This is a subsection of $form, namely $form['#node'] should be
 * passed in.
 * @param array &$form_branch This is a subsection of $form. Each iteration adds to the one
 * before, then passes itself as the new branch. _tss_branch() is called for each iteration
 * and appended to it. 
 * 
 * @return since values are passed in via reference, no return value is required.
 */
function _tss_next_nested(&$terms, &$vid, &$input, $tss, &$form_node, &$form_branch) {
  $fieldweight = 0;
  foreach($terms as $index => $term){
    $child = taxonomy_get_children($term->tid, $vid);
    if(count($child)){
      if($tss[$vid]['parents']){
        $term->is_parent = TRUE;
        $term->parent_type  = $input;
        $term->parent_value = $form_node->taxonomy[$term->tid]->tid;
      }
      $form_branch[$term->tid] = _tss_branch($vid, $term, NULL, 'fieldset', $fieldweight++);
      _tss_next_nested($child, $vid, $input, $tss, $form_node, $form_branch[$term->tid]);
    }
    else{
      if($value =  $form_node->taxonomy[$term->tid]->tid){
        $form_branch[$term->tid]['#collapsed'] = FALSE;
      }
      $form_branch[$term->tid] = _tss_branch($vid, $term, $value, $input, $fieldweight++);
    }
  }
}

and _tss_branch() should now be:

function _tss_branch($vid, $term, $value = NULL, $type = 'fieldset', $fieldweight = -1){
  $required = $term->required ? ' <span class="form-required" title="'.t('This field is required.').'">*</span>' : '';
  switch($type){
    case 'fieldset':
      // Automatically expand required vocabs or if the parent term is selected
      $collapsed = ($required OR $term->parent_value) ? FALSE : TRUE;
      $form = array(
        '#type' => 'fieldset',
        '#title' => t($term->name).$required,
        '#collapsible' => TRUE,
        '#collapsed' => $collapsed, 
        '#weight' => ($fieldweight >= 0) ? $fieldweight : $term->weight,
        '#parents' => array('taxonomy', $vid),
        '#description' => t($term->description),
      );
      // If we have vocabulary that is single select and not required or is freetagging we need a way to unselect the term
      if((!$required OR $term->tags) AND $term->multiple == 0 AND $term->module == 'taxonomy'){
        $form['none'] = array(
          '#type' => 'radio',
          '#title' => '<em>'.t('Select None').'</em>',
          '#return_value' => 0,
          '#default_value' => '',
          '#weight' => -12,
          '#parents' => array('taxonomy', $term->vid),
        );
      }
      if($term->is_parent){
        $term->weight = -11;
        $form['parent'] = _tss_branch($term->vid, $term, $term->parent_value, $term->parent_type);
      }
    break;
    case 'radio':
      $form = array(
        '#type' => 'radio',
        '#title' => ($term->is_parent ? '<strong>' : '').t($term->name).($term->is_parent ? '</strong>' : ''),
        '#return_value' => $term->tid,
        '#default_value' => $value,
        '#weight' => ($fieldweight >= 0) ? $fieldweight : $term->weight,
        '#parents' => array('taxonomy', $vid),
      );
    break;
    case 'checkbox':
      $form = array(
        '#type' => 'checkbox',
        '#title' => ($term->is_parent ? '<strong>' : '').t($term->name).($term->is_parent ? '</strong>' : ''),
        '#return_value' => $term->tid,
        '#default_value' => $value,
        '#weight' => ($fieldweight >= 0) ? $fieldweight : $term->weight,        
      );
    break;
  }
  return $form;
}

Again, sorry for the inline code.

rconstantine’s picture

Title: Depth Limited to 5 » Depth Limited to 5 -> not anymore
Status: Needs review » Reviewed & tested by the community

I've been using this code just fine in my own module, cck_taxonomy_super_select_ultra. Could probably be committed to this project as-is.

SemperFideles’s picture

I've tried this "patch" twice on two sites and the taxonomy is still not organized alphabetically on my site.

rconstantine’s picture

Status: Reviewed & tested by the community » Needs work

Well what do you know. Not sure how I missed that glaring error! Would have been nice to know about it sooner. At least the nesting part works. I have verified that. I wonder if I had too small of a test taxonomy before or something. Or maybe I entered it in in alphabetical order and didn't realize it, so it was spitting out correctly for wrong reasons. In any case, I'll fix it in my module, and if there is an easy translation to this one, post the changes.

rconstantine’s picture

FileSize
53.91 KB

No, wait a minute. I just realized mine is alphabetized, or pseudo-alphabetized if you'd like to call it that. I'm not sure if I adjusted things since the posted code above or not. Let me know if you get the same results as the screen shot.

Basically, each level is in order with leaf terms alphabetized, then branch terms. There is an exception. If you've set the option (in my module) to have branch terms 'checkable', then they appear first inside of themselves (bolded) before the alphabetized leaf terms. At least, I think so.

So for the first level, the leaves are "baseball, football, and new term" which are in order, followed by the branches, "fish, indoor activities, outdoor activities". Inside of fish, there are leaf terms of "fish and deep sea fishing" so the branch term comes first. Indoor activities looks similarly okay. Outdoor activities seems to not be in leaf/branch order and seems to be the only problem here. Perhaps I have an issue when a child branch comes before the current branch alphabetically in getting that child to the proper place in the list. So other than that problem, do you see any other deviations from my explanation of how it should work?

SemperFideles’s picture

Title: Depth Limited to 5 -> not anymore » Only could get it to alphabetize by weighting

I don't know. I had 7 taxonomies and they would not sort alphabetically for me. I ended up having to force the issue by assigning different weights to the terms. I even tried exporting the table of the main vocabularies, re-ordering them in the sql file and then re-importing them so they were in the table in alphabetical order and the selections were still all jumbled in the category selections. It mattered not if I had the module installed or not installed.

rconstantine’s picture

Well, although I may not fix this version of the code, I'll very likely fix the version of it in my module since that's the one I use and I'd like it to be alphabetic. Thanks for the info.

NancyDru’s picture

Status: Needs work » Reviewed & tested by the community

It worked for me, although, admittedly, I have a small vocabulary. I think it is better, at this point, to get the unlimited depth code into the module. Ordering, if it is not fixed can be accomplished with weighting.

NancyDru’s picture

Status: Reviewed & tested by the community » Fixed

This is now in 5.x-1.10. If the alphabetization is not correct, please open a new issue.

Anonymous’s picture

Status: Fixed » Closed (fixed)

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