Download & Extend

Invalid response from server when using hook_form_alter for non-taxonomy hierarchy

Project:Hierarchical Select
Version:6.x-3.x-dev
Component:Code
Category:support request
Priority:normal
Assigned:Wim Leers
Status:closed (fixed)

Issue Summary

Everything works fine when using hook_form - like Wim does in his hs_tutorial module. However when i use hook_form_alter (instead of hook_form) i get a "Received invalid response from the server" error after selecting a root level item. Reloading the page then yields a drupal error: "warning: uasort() [function.uasort]: The argument should be an array in /home/fivthwor/public_html/imaginariums/includes/common.inc on line 2875."

I tried giving the module different weights, disabling contrib modules, clearing and flushing caches - to no avail.

Please see attached module file and i can provide a screencast if necessary.

Comments

#1

Module file:

<?php
// $Id: imaginariums_test.module

function imaginariums_test_node_info() {
  return array(
   
'imaginariums_test' => array(
     
'name' => t('Imaginariums Test'),
     
'module' => 'imaginariums_test',
     
'description' => t("A test module using Hierarchical Select with a non-taxonomy-based hierarchy."),
    )
  );
}


function
imaginariums_test_menu_alter(&$items) {
   
$items ['node/add/activity-story'] = array (
       
'title' =>  t('Activity or Story'),
       
'title callback' =>  'check_plain',
       
'page callback' => 'custom_add',
       
'page arguments' => array (0 => 3),
       
'access callback' => 'node_access',
       
'access arguments' => array (
           
0 => 'create',
           
1 => 'activity_story',
        ),
       
'file' => 'node.pages.inc',
       
'module' => 'node',
    );   
}


function
custom_add ($share_experience_forum) {
        global
$hs_structured_array;
       
$hs_structured_array = array();
       
//I'm building hs array here so that we don't have to build it for each call to imaginariums_test_hierarchy
        //i'm doing it here instead of in form_alter because i am not sure when hs accesses it.
       
$root_result = db_query("SELECT node.nid, node.title FROM {node} INNER JOIN {content_field_reference_pod} ON node.nid = content_field_reference_pod.field_reference_pod_nid INNER JOIN {content_type_event_etc} ON content_field_reference_pod.nid = content_type_event_etc.nid INNER JOIN {term_node} ON content_type_event_etc.nid = term_node.nid WHERE term_node.tid = %d", 96);
       
$num_root_rows = FALSE;
        while (
$root_node = db_fetch_object($root_result)) {
           
$num_root_rows = TRUE;
           
$hs_structured_array['root']['children'][] =     $root_node->nid;
           
$hs_structured_array[$root_node->nid]['label'] = $root_node->title;
           
$child_result = db_query("SELECT node.nid, node.title FROM {node} INNER JOIN {content_field_reference_pod} ON node.nid = content_field_reference_pod.nid INNER JOIN {content_type_event_etc} ON content_field_reference_pod.nid = content_type_event_etc.nid WHERE content_type_event_etc.field_core_type_value = '%s' AND content_field_reference_pod.field_reference_pod_nid = %d", 'Event', $root_node->nid);
           
$temp = array();
            while (
$child_node = db_fetch_object($child_result)) {
               
$hs_structured_array[$root_node->nid]['children'][] = $child_node->nid;
               
$hs_structured_array[$child_node->nid]['label'] = $child_node->title;
            }
        }

       
//added node callback code (from node.pages.inc) and slightly modified for this use case
       
global $user;
       
       
$type = 'activity_story';

     
$types = node_get_types();
     
$type = isset($type) ? str_replace('-', '_', $type) : NULL;
     
// If a node type has been specified, validate its existence.
     
if (isset($types[$type]) && node_access('create', $type)) {
       
// Initialize settings:
       
$node = array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => '');

       
drupal_set_title(t('Create @name', array('@name' => $types[$type]->name)));
       
$output = drupal_get_form($type .'_node_form', $node);
      }

      return
$output;
       
}


function
imaginariums_test_form_alter(&$form, $form_state, $form_id) {
   
$form_id = $form['form_id']['#value'];
    if (
$form_id == 'activity_story_node_form') {
        if (
arg(1) == "add")  {
           
$form['imaginariums_custom_select'] = array(
               
'#type' => 'hierarchical_select',
               
'#weight' => 1,
               
'#title' => t('Select your pod'),
               
'#required' => FALSE,
               
'#default_value' => 204,
               
'#config' => array(
                   
'module' => 'imaginariums_test',
                   
'params' => array(
                       
'root' => 'root',
                    ),
                   
'save_lineage' => 1,
                   
'enforce_deepest' => 0,
                   
'level_labels' => array(
                       
'status' => 1,
                       
'labels' => array(
                           
0 => t('Choose:'),
                           
1 => t('Select an event (if applicable):'),
                        ),
                    ),
                ),
            );
        }
       
    }
       
}


/**
* @file
* The hierarchical select functions below originate from the attached help files in this tutorial - <a href="http://drupal.org/node/532724
*/
//----------------------------------------------------------------------------
//" title="http://drupal.org/node/532724
*/
//----------------------------------------------------------------------------
//" rel="nofollow">http://drupal.org/node/532724
*/
//-----------------------------------...</a> Main functionality of Hierarchical Select
/**
* Definition of hierarchy.
*/
function imaginariums_test_hierarchy() {
   
//AC_Mod Since this function is called multiple times i just generated the array previously
    //and stored it in global variable $hs_structured_array
   
global $hs_structured_array;
    return
$hs_structured_array;
}


//----------------------------------------------------------------------------
// Hierarchical Select hooks.

/**
* Implementation of hook_hierarchical_select_params().
*/
function imaginariums_test_hierarchical_select_params() {
   
// This module defines only one hierarchy, so parameters are not necessary.
   
return array();
}

/**
* Implementation of hook_hierarchical_select_root_level().
*/
function imaginariums_test_hierarchical_select_root_level($params) {
   
$hierarchy = imaginariums_test_hierarchy();
   
$items = $hierarchy['root']['children'];
    return
_imaginariums_test_items_associate_labels_with_items($items);
}

/**
* Implementation of hook_hierarchical_select_children().
*/
function imaginariums_test_hierarchical_select_children($parent) {
   
$hierarchy = imaginariums_test_hierarchy();
   
$items = $hierarchy[$parent]['children'];
    return
_imaginariums_test_items_associate_labels_with_items($items);
}

/**
* Implementation of hook_hierarchical_select_lineage().
*/
function imaginariums_test_hierarchical_select_lineage($item, $params) {
   
// If given the item "Company A-Accounts Payable-Employee C", this will
    // generate the following lineage:
    // Array
    // (
    //         [0] => Company A
    //         [1] => Company A-Accounts Payable
    //         [2] => Company A-Accounts Payable-Employee C
    // )
   
$parts = explode('-', $item);
    
   
$lineage = array();
    for (
$i = 0; $i < count($parts); $i++) {
       
$lineage[] = implode('-', array_slice($parts, 0, $i + 1));
    }
    return
$lineage;

}

/**
* Implementation of hook_hierarchical_select_valid_item().
*/
function imaginariums_test_hierarchical_select_valid_item($item, $params) {
   
$hierarchy = imaginariums_test_hierarchy();
    return isset(
$hierarchy[$item]['label']);
}

/**
* Implementation of hook_hierarchical_select_item_get_label().
*/
function imaginariums_test_hierarchical_select_item_get_label($item, $params) {
   
$hierarchy = imaginariums_test_hierarchy();
    return
$hierarchy[$item]['label'];
}


//----------------------------------------------------------------------------
// Helper functions.

/**
* Given an array of items, associate the labels with the items.
*
* @param $items
*     An array of item objects.
* @return
*     An associative array of (item, label) pairs.
*/
function _imaginariums_test_items_associate_labels_with_items($items) {
   
$hierarchy = imaginariums_test_hierarchy();
   
$options = array();
    
    if (
count($items)) {
        foreach (
$items as $item) {
           
// Use the translated item when available!
           
$options[$item] = t($hierarchy[$item]['label']);
        }
    }
    
     return
$options;
}
?>

#2

Assigned to:Anonymous» Wim Leers
Status:active» postponed (maintainer needs more info)

Instead of generating the hierarchy in custom_add(), generate it in imaginariums_test_hierarchy() and use a static variable to generate it only once. That might help.

#3

Wim - thanks for your timely response

I went ahead and put the internal_hierarchy array generating code back into imaginariums_test_hierarchy() static array - where it belongs. : )
I also removed the menu_alter and custom_add callback from my modules code. The error persists.

Have you found no problem using a hook_form_alter instead of a hook_form with your example code?

hook_form_alter seems like a fairly common place for implementing hs api for non-taxonomy use cases. Ergo is there anyone else out there who has done this successfully?

#4

OK - substituting form_alter for form works fine with hs_tutorial module. There is something specific to what i am doing that is creating the error - perhaps i'll post what is causing it incase someone else bumps up against it.

THANK YOU Wim for an awesome module and great support.

#5

Riddle me this ???

Everything works fine after i removed the following if statement from my hook_form_alter:

if (arg(1) == "add") {}

what that has to do with HS i have no idea - i'm just glad i got it working : )

#6

Status:postponed (maintainer needs more info)» fixed

Ahhh, of course! The arg(1) is NOT equal to 'add' when updating HS, since HS uses a callback to a different path for that.

Glad you got it solved :)

#7

Status:fixed» active

Hi Wim

Sorry to reopen this but i really need to execute different hierarchical select depending on arg(n).

i tried to create and use my own uri args but it makes no difference.

$uri_args = explode('/', substr(request_uri(), 1));

Do you think there is anything you could do to hs to make it more amiable to the arg . . . . .

or anything i could do on my side?

#8

Status:active» postponed (maintainer needs more info)

There's nothing I can do. That's how it works.

What you could do, is add a GET argument. E.g. node/add/page?bleh=whatever. This will be carried on.

If it is the adding of nodes you want to detect, there's other ways to do that. For example, check if a node object is present. If not, a new node is being created, if it is, an existing node is being edited.

#9

Status:postponed (maintainer needs more info)» fixed

OK - I'll add the GET

mahalos!

#10

Status:fixed» closed (fixed)

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

nobody click here