Posted by Hunabku on October 6, 2009 at 9:24pm
Jump to:
| 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
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
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
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
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
OK - I'll add the GET
mahalos!
#10
Automatically closed -- issue fixed for 2 weeks with no activity.