View source
<?php
define('HS_DEVELOPER_MODE', 0);
function hierarchical_select_menu($may_cache) {
if ($may_cache) {
$items[] = array(
'path' => 'hierarchical_select_json',
'callback' => 'hierarchical_select_json',
'type' => MENU_CALLBACK,
'access' => TRUE,
);
$items[] = array(
'path' => 'admin/settings/hierarchical_select',
'title' => t('Hierarchical Select'),
'description' => t('Configure site-wide settings for the Hierarchical Select form element.'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'hierarchical_select_admin_settings',
),
'type' => MENU_NORMAL_ITEM,
);
$items[] = array(
'path' => 'admin/settings/hierarchical_select/settings',
'title' => t('Site-wide settings'),
'weight' => -10,
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/settings/hierarchical_select/configs',
'title' => t('Configurations'),
'description' => t('All available Hierarchical Select configurations.'),
'callback' => 'hierarchical_select_admin_configs',
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/settings/hierarchical_select/implementations',
'title' => t('Implementations'),
'description' => t('Features of each Hierarchical Select implementation.'),
'callback' => 'hierarchical_select_admin_implementations',
'type' => MENU_LOCAL_TASK,
);
}
else {
global $user;
if (!isset($user->theme)) {
$user->theme = variable_get('theme_default', 'garland');
}
if (arg(0) == 'admin' && arg(1) == 'settings' && arg(2) == 'hierarchical_select') {
require_once drupal_get_path('module', 'hierarchical_select') . '/hierarchical_select.admin.inc';
if (in_array(arg(3), array(
'export',
'import',
))) {
require_once drupal_get_path('module', 'hierarchical_select') . '/includes/common.inc';
$items[] = array(
'path' => 'admin/settings/hierarchical_select/export/' . arg(4),
'title' => t('Export'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'hierarchical_select_admin_export',
arg(4),
),
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/settings/hierarchical_select/import/' . arg(4),
'title' => t('Import'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'hierarchical_select_admin_import',
arg(4),
),
'type' => MENU_LOCAL_TASK,
);
}
}
}
return $items;
}
function hierarchical_select_form_alter($form_id, &$form) {
if (_hierarchical_select_form_has_hierarchical_select($form)) {
$form['#after_build'][] = 'hierarchical_select_after_build';
}
}
function hierarchical_select_elements() {
$type['hierarchical_select'] = array(
'#input' => TRUE,
'#process' => array(
'hierarchical_select_process' => array(),
),
'#config' => array(
'module' => 'some_module',
'params' => array(),
'save_lineage' => 0,
'enforce_deepest' => 0,
'entity_count' => 0,
'resizable' => 1,
'level_labels' => array(
'status' => 0,
'labels' => array(),
),
'dropbox' => array(
'status' => 0,
'title' => t('All selections'),
'limit' => 0,
'reset_hs' => 1,
),
'editability' => array(
'status' => 0,
'item_types' => array(),
'allowed_levels' => array(),
'allow_new_levels' => 0,
'max_levels' => 3,
),
'animation_delay' => variable_get('hierarchical_select_animation_delay', 400),
'exclusive_lineages' => array(),
'render_flat_select' => 0,
),
'#default_value' => -1,
);
return $type;
}
function hierarchical_select_requirements($phase) {
$requirements = array();
if ($phase == 'runtime') {
require_once 'includes/install.inc';
drupal_load_updates();
$updates = drupal_get_schema_versions('hierarchical_select');
$current = drupal_get_installed_schema_version('hierarchical_select');
$up_to_date = end($updates) == $current;
$jquery_update_v2 = file_exists(drupal_get_path('module', 'jquery_update') . '/compat.js');
$jquery_interface = module_exists('jquery_interface');
$hierarchical_select_weight = db_result(db_query("SELECT weight FROM {system} WHERE type = 'module' AND name = 'hierarchical_select'"));
$core_overriding_modules = array(
'hs_book',
'hs_menu',
'hs_taxonomy',
);
$path_errors = array();
foreach ($core_overriding_modules as $module) {
$filename = db_result(db_query("SELECT filename FROM {system} WHERE type = 'module' AND name = '%s'", $module));
if (strpos($filename, 'modules/') === 0) {
$module_info = _module_parse_info_file(dirname($filename) . "/{$module}.info");
$path_errors[] = t('!module', array(
'!module' => $module_info['name'],
));
}
}
$weight_errors = array();
foreach (module_implements('hierarchical_select_root_level') as $module) {
$weight = db_result(db_query("SELECT weight FROM {system} WHERE name = '%s'", $module));
if (!($hierarchical_select_weight > $weight)) {
$filename = db_result(db_query("SELECT filename FROM {system} WHERE type = 'module' AND name = '%s'", $module));
$module_info = _module_parse_info_file(dirname($filename) . "/{$module}.info");
$weight_errors[] = t('!module (!weight)', array(
'!module' => $module_info['name'],
'!weight' => $weight,
));
}
}
if ($up_to_date && $jquery_update_v2 && !$jquery_interface && !count($path_errors) && !count($weight_errors)) {
$value = t('All updates installed. jQuery Update 2.x installed. Implementation modules are installed correctly.');
$description = '';
$severity = REQUIREMENT_OK;
}
elseif (!$up_to_date) {
$value = t('Not all updates installed!');
$description = t('Please run update.php to install the latest updates!
You have installed update !installed_update, but the latest update is
!latest_update!', array(
'!installed_update' => $current,
'!latest_update' => end($updates),
));
$severity = REQUIREMENT_ERROR;
}
elseif (!$jquery_update_v2) {
$value = t('jQuery Update 1.x installed!');
$description = t('Please upgrade to jQuery Update 2.x! jQuery Update
1.x contains jQuery 1.1.x, which is incompatible with the Javascript
code of Hierarchical Select!');
$severity = REQUIREMENT_ERROR;
}
elseif ($jquery_interface) {
$value = t('jQuery Interface installed!');
$description = t('Please disable and uninstall jQuery Interface, as it
is incompatible with jQuery Update 2. It is very buggy anyway and any
module that uses it should upgrade to jQuery UI.');
$severity = REQUIREMENT_ERROR;
}
elseif ($path_errors) {
$value = t('Modules incorrectly installed!');
$description = t("The following modules implement Hierarchical Select module for Drupal\n core modules, but are installed in the wrong location. They're\n installed in core's <code>modules</code> directory, but should be\n installed in either the <code>sites/all/modules</code> directory or a\n <code>sites/yoursite.com/modules</code> directory") . ':' . theme('item_list', $path_errors);
$severity = REQUIREMENT_ERROR;
}
elseif ($weight_errors) {
$value = t('Module weight incorrectly configured!');
$description = t('The weight of the Hierarchical Select module (!weight) is not
strictly higher than the weight of the following modules', array(
'!weight' => $hierarchical_select_weight,
)) . ':' . theme('item_list', $weight_errors);
$severity = REQUIREMENT_ERROR;
}
$requirements['hierarchical_select'] = array(
'title' => t('Hierarchical Select'),
'value' => $value,
'description' => $description,
'severity' => $severity,
);
}
return $requirements;
}
function hierarchical_select_json() {
drupal_set_header('Content-Type: text/javascript; charset=utf-8');
$hs_form_build_id = $_POST['hs_form_build_id'];
$hs_form_build_id = _hierarchical_select_get_hs_form_build_id();
$cached = cache_get($hs_form_build_id, 'cache');
$storage = unserialize($cached->data);
$form_id = $_POST['form_id'] = $storage['parameters'][0];
if (module_exists('i18n')) {
i18n_selection_mode($storage['i18n']['mode'], $storage['i18n']['params']);
}
if (HS_DEVELOPER_MODE) {
_hierarchical_select_log("form_id: {$form_id}");
_hierarchical_select_log("hs_form_build_id: {$hs_form_build_id}");
}
$form = call_user_func_array('drupal_retrieve_form', $storage['parameters']);
drupal_prepare_form($form_id, $form);
$hsid = $_POST['hsid'];
$name = $storage['#names'][$hsid];
$part_of_form = _hierarchical_select_get_form_item($form, $name);
$output = drupal_render($part_of_form);
$cache = array();
if ($_POST['client_supports_caching'] == 'true') {
$cache = _hierarchical_select_json_convert_hierarchy_to_cache($part_of_form['hierarchy']['#value']);
}
else {
if ($_POST['client_supports_caching'] == 'false') {
}
}
print drupal_to_js(array(
'cache' => $cache,
'output' => $output,
'log' => $part_of_form['log']['#value'],
));
exit;
}
function hierarchical_select_process($element) {
if (!isset($element['#value']['hsid'])) {
if (!isset($_SESSION['hsid'])) {
$_SESSION['hsid'] = 0;
}
else {
$_SESSION['hsid'] = ($_SESSION['hsid'] + 1) % 100;
}
$hsid = $_SESSION['hsid'];
}
else {
$hsid = check_plain($element['#value']['hsid']);
}
$element['hsid'] = array(
'#type' => 'hidden',
'#value' => $hsid,
);
if (!is_array($element['#value'])) {
$element['#value'] = array(
$element['#value'],
);
}
_hierarchical_select_store_name($element, $hsid);
_hierarchical_select_setup_js();
$config = _hierarchical_select_inherit_default_config($element['#config']);
drupal_add_js(array(
'HierarchicalSelect' => array(
'settings' => array(
$hsid => array(
'animationDelay' => $config['animation_delay'] == 0 ? (int) variable_get('hierarchical_select_animation_delay', 400) : $config['animation_delay'],
'cacheId' => $config['module'] . '_' . implode('_', is_array($config['params']) ? $config['params'] : array()),
'renderFlatSelect' => isset($config['render_flat_select']) ? (int) $config['render_flat_select'] : 0,
'createNewItems' => isset($config['editability']['status']) ? (int) $config['editability']['status'] : 0,
'createNewLevels' => isset($config['editability']['allow_new_levels']) ? (int) $config['editability']['allow_new_levels'] : 0,
'resizable' => isset($config['resizable']) ? (int) $config['resizable'] : 0,
),
),
),
), 'setting');
if (HS_DEVELOPER_MODE) {
$diagnostics = array();
if (!isset($config['module']) || empty($config['module'])) {
$diagnostics[] = t("'module is not set!");
}
elseif (!module_exists($config['module'])) {
$diagnostics[] = t('the module that should be used (module) is not installed!', array(
'%module' => $config['module'],
));
}
else {
$required_params = module_invoke($config['module'], 'hierarchical_select_params');
$missing_params = array_diff($required_params, array_keys($config['params']));
if (!empty($missing_params)) {
$diagnostics[] = t("'params' is missing values for: ") . implode(', ', $missing_params) . '.';
}
}
$config_id = isset($config['config_id']) && is_string($config['config_id']) ? $config['config_id'] : 'none';
if (empty($diagnostics)) {
_hierarchical_select_log("Config diagnostics (config id: {$config_id}): no problems found!");
}
else {
$diagnostics_string = print_r($diagnostics, TRUE);
$message = "Config diagnostics (config id: {$config_id}): {$diagnostics_string}";
_hierarchical_select_log($message);
$element['#type'] = 'item';
$element['#value'] = '<p><span style="color:red;">Fix the indicated errors in the #config property first!</span><br />' . nl2br($message) . '</p>';
return $element;
}
}
list($hs_selection, $db_selection) = _hierarchical_select_process_calculate_selections($element);
if (HS_DEVELOPER_MODE) {
_hierarchical_select_log("Calculated hierarchical select selection:");
_hierarchical_select_log($hs_selection);
if ($config['dropbox']['status']) {
_hierarchical_select_log("Calculated dropbox selection:");
_hierarchical_select_log($db_selection);
}
}
if (count($config['exclusive_lineages']) && $config['dropbox']['status']) {
$selection = !empty($hs_selection) ? $hs_selection : $db_selection;
if (in_array($selection, $config['exclusive_lineages']) || count($selection) == 1 && in_array($selection[0], $config['exclusive_lineages'])) {
$element['#config']['dropbox']['status'] = 0;
$config = _hierarchical_select_inherit_default_config($element['#config']);
if (empty($hs_selection)) {
$hs_selection = $db_selection;
$db_selection = array();
}
}
}
$dropbox = !$config['dropbox']['status'] ? FALSE : _hierarchical_select_dropbox_generate($config, $db_selection);
$hierarchy = _hierarchical_select_hierarchy_generate($config, $hs_selection, $element['#required'], $dropbox);
if (HS_DEVELOPER_MODE) {
_hierarchical_select_log('Generated hierarchy in ' . $hierarchy->build_time['total'] . ' ms:');
_hierarchical_select_log($hierarchy);
if ($config['dropbox']['status']) {
_hierarchical_select_log('Generated dropbox in ' . $dropbox->build_time . ' ms: ');
_hierarchical_select_log($dropbox);
}
}
$element['hierarchy'] = array(
'#type' => 'value',
'#value' => $hierarchy,
);
$element['#tree'] = TRUE;
if ($config['render_flat_select']) {
$element['flat_select'] = _hierarchical_select_process_render_flat_select($hierarchy, $dropbox, $config);
}
$element['hierarchical_select'] = array(
'#theme' => 'hierarchical_select_selects_container',
);
$element['hierarchical_select']['selects'] = _hierarchical_select_process_render_hs_selects($hsid, $hierarchy);
foreach (element_children($element['hierarchical_select']['selects']) as $depth) {
$element['hierarchical_select']['selects'][$depth]['#size'] = $element['#size'];
}
$creating_new_item = FALSE;
if (isset($element['#value']['hierarchical_select']['selects'])) {
foreach ($element['#value']['hierarchical_select']['selects'] as $depth => $value) {
if ($value == 'create_new_item' && _hierarchical_select_create_new_item_is_allowed($config, $depth)) {
$creating_new_item = TRUE;
for ($i = $depth; $i < count($hierarchy->lineage); $i++) {
unset($element['hierarchical_select']['selects'][$i]);
}
$element['hierarchical_select']['create_new_item'] = array(
'#prefix' => '<div class="' . str_replace('_', '-', $value) . '">',
'#suffix' => '</div>',
);
$item_type_depth = $value == 'create_new_item' ? $depth : $depth + 1;
$item_type = !empty($config['editability']['item_types'][$item_type_depth]) ? t($config['editability']['item_types'][$item_type_depth]) : t('item');
$element['hierarchical_select']['create_new_item']['input'] = array(
'#type' => 'textfield',
'#size' => 20,
'#maxlength' => 255,
'#default_value' => t('new @item', array(
'@item' => $item_type,
)),
'#attributes' => array(
'title' => t('new @item', array(
'@item' => $item_type,
)),
'class' => 'create-new-item-input',
),
'#theme' => 'hierarchical_select_textfield',
);
$element['hierarchical_select']['create_new_item']['create'] = array(
'#type' => 'button',
'#value' => t('Create'),
'#attributes' => array(
'class' => 'create-new-item-create',
),
);
$element['hierarchical_select']['create_new_item']['cancel'] = array(
'#type' => 'button',
'#value' => t('Cancel'),
'#attributes' => array(
'class' => 'create-new-item-cancel',
),
);
}
}
}
if ($config['dropbox']['status']) {
if (!$creating_new_item) {
$element['hierarchical_select']['dropbox_add'] = array(
'#type' => 'button',
'#value' => t('Add'),
'#attributes' => array(
'class' => 'add-to-dropbox',
),
);
}
if ($config['dropbox']['limit'] > 0) {
if (count($dropbox->lineages) == $config['dropbox']['limit']) {
$element['dropbox_limit_warning'] = array(
'#value' => t("You've reached the maximal number of items you can select."),
'#prefix' => '<p class="hierarchical-select-dropbox-limit-warning">',
'#suffix' => '</p>',
);
_hierarchical_select_mark_as_disabled($element['hierarchical_select']);
}
}
$element['dropbox']['hidden'] = array(
'#prefix' => '<div class="dropbox-hidden">',
'#suffix' => '</div>',
);
$element['dropbox']['hidden'] = _hierarchical_select_process_render_db_hidden($hsid, $dropbox);
$element['dropbox']['visible'] = _hierarchical_select_process_render_db_visible($hsid, $dropbox);
}
$element['nojs'] = array(
'#prefix' => '<div class="nojs">',
'#suffix' => '</div>',
);
$element['nojs']['update_button'] = array(
'#type' => 'button',
'#value' => t('Update'),
'#attributes' => array(
'class' => 'update-button',
),
);
$element['nojs']['update_button_help_text'] = array(
'#value' => _hierarchical_select_nojs_helptext($config['dropbox']['status']),
'#prefix' => '<div class="help-text">',
'#suffix' => '</div>',
);
$element['hierarchical_select']['#weight'] = 0;
$element['dropbox_limit_warning']['#weight'] = 1;
$element['dropbox']['#weight'] = 2;
$element['nojs']['#weight'] = 3;
unset($element['#post']);
$element['#return_value'] = _hierarchical_select_process_calculate_return_value($hierarchy, $config['dropbox']['status'] ? $dropbox : FALSE, $config['module'], $config['params'], $config['save_lineage']);
$element['#validate'] = array(
'_hierarchical_select_validate' => array(),
);
if (HS_DEVELOPER_MODE) {
$element['log'] = array(
'#type' => 'value',
'#value' => _hierarchical_select_log(NULL, TRUE),
);
drupal_add_js(array(
'HierarchicalSelect' => array(
'initialLog' => array(
$hsid => $element['log']['#value'],
),
),
), 'setting');
}
if ($element['#disabled']) {
_hierarchical_select_mark_as_disabled($element);
}
return $element;
}
function hierarchical_select_after_build($form, $form_values) {
$names = _hierarchical_select_store_name(NULL, NULL, TRUE);
$post_hs_form_build_id = _hierarchical_select_get_hs_form_build_id();
if (!isset($post_hs_form_build_id) && count($names)) {
$parameters = isset($form['#parameters']) ? $form['#parameters'] : array();
$storage = array(
'parameters' => $parameters,
'#names' => $names,
);
if (module_exists('i18n')) {
$storage['i18n'] = array(
'mode' => i18n_selection_mode(),
'params' => i18n_selection_mode('params'),
);
}
$expire = 21600;
$hs_form_build_id = 'hs_form_' . md5(mt_rand());
cache_set($hs_form_build_id, 'cache', serialize($storage), time() + $expire);
}
elseif (isset($post_hs_form_build_id)) {
$hs_form_build_id = $post_hs_form_build_id;
}
$form_element = array(
'#type' => 'hidden',
'#value' => $hs_form_build_id,
'#parents' => array(
'hs_form_build_id',
),
);
$form['hs_form_build_id'] = form_builder($form['form_id']['#value'], $form_element);
$form['#submit']['_hierarchical_select_submit'] = array(
$post_hs_form_build_id,
);
return $form;
}
function _hierarchical_select_validate(&$element) {
$config = _hierarchical_select_inherit_default_config($element['#config']);
if ($config['dropbox']['status']) {
if ($config['dropbox']['limit'] > 0) {
$lineage_count = count($element['#value']['dropbox']['hidden']['lineages_selections']);
if ($lineage_count > $config['dropbox']['limit']) {
form_error($element, t("You've selected %lineage-count items, but you're only allowed to select %dropbox-limit items.", array(
'%lineage-count' => $lineage_count,
'%dropbox-limit' => $config['dropbox']['limit'],
)));
_hierarchical_select_form_set_error_class($element);
}
}
}
if ($element['#disabled']) {
$element['#return_value'] = $element['#default_value'];
}
$value = empty($element['#return_value']) ? 0 : $element['#return_value'];
$element['#value'] = $value;
form_set_value($element, $value);
if ($element['#required'] && empty($element['#value']) && $element['#value'] !== '0') {
form_error($element, t('!name field is required.', array(
'!name' => $element['#title'],
)));
_hierarchical_select_form_set_error_class($element);
}
}
function _hierarchical_select_submit($form_id, $form_values, $hs_form_build_id) {
cache_clear_all($hs_form_build_id, 'cache');
}
function _hierarchical_select_process_get_hs_selection($element) {
$hs_selection = array();
$config = _hierarchical_select_inherit_default_config($element['#config']);
if (count($element['#value']['hierarchical_select']['selects'])) {
if ($config['save_lineage']) {
foreach ($element['#value']['hierarchical_select']['selects'] as $key => $value) {
$hs_selection[] = $value;
}
}
else {
foreach ($element['#value']['hierarchical_select']['selects'] as $key => $value) {
$hs_selection[] = $value;
}
$hs_selection = _hierarchical_select_hierarchy_validate($hs_selection, $config['module'], $config['params']);
$hs_selection = $hs_selection != -1 ? array(
end($hs_selection),
) : array();
}
}
return $hs_selection;
}
function _hierarchical_select_process_get_db_selection($element) {
$db_selection = array();
if (count($element['#value']['dropbox']['hidden']['lineages_selections'])) {
$remove_from_db_selection = !isset($element['#value']['dropbox']['visible']['lineages']) ? array() : array_keys($element['#value']['dropbox']['visible']['lineages']);
foreach ($element['#value']['dropbox']['hidden']['lineages_selections'] as $x => $selection) {
if (!in_array($x, $remove_from_db_selection)) {
$db_selection = array_merge($db_selection, unserialize($selection));
}
}
foreach ($remove_from_db_selection as $key => $x) {
$item = end(unserialize($element['#value']['dropbox']['hidden']['lineages_selections'][$x]));
$position = array_search($item, $db_selection);
if ($position) {
unset($db_selection[$position]);
}
}
$db_selection = array_unique($db_selection);
}
return $db_selection;
}
function _hierarchical_select_process_calculate_selections(&$element) {
$hs_selection = array();
$db_selection = array();
$config = _hierarchical_select_inherit_default_config($element['#config']);
$dropbox = (bool) $config['dropbox']['status'];
$op = $element['#post']['op'];
if (empty($element['#post'])) {
$value = isset($element['#value']) ? $element['#value'] : $element['#default_value'];
$value = is_array($value) ? $value : array(
$value,
);
if ($dropbox) {
$db_selection = $value;
}
else {
$hs_selection = $value;
}
}
else {
if ($dropbox && $op == t('Add')) {
$hs_selection = _hierarchical_select_process_get_hs_selection($element);
$db_selection = _hierarchical_select_process_get_db_selection($element);
$db_selection = array_merge($db_selection, $hs_selection);
if ($config['dropbox']['reset_hs']) {
$hs_selection = array();
}
}
else {
if ($op == t('Create')) {
$label = trim($element['#value']['hierarchical_select']['create_new_item']['input']);
$selects = $element['#value']['hierarchical_select']['selects'];
$depth = count($selects);
$parent = $depth > 0 ? end($selects) : 0;
if (empty($label)) {
$element['#value']['hierarchical_select']['selects'][count($selects)] = 'create_new_item';
}
else {
if ((count(module_invoke($config['module'], 'hierarchical_select_children', $parent, $config['params'])) || $config['editability']['max_levels'] == 0 || $depth < $config['editability']['max_levels']) && _hierarchical_select_create_new_item_is_allowed($config, $depth)) {
$value = module_invoke($config['module'], 'hierarchical_select_create_item', check_plain($label), $parent, $config['params']);
if ($value) {
$element['#value']['hierarchical_select']['selects'][count($selects)] = $value;
}
}
}
$hs_selection = _hierarchical_select_process_get_hs_selection($element);
if ($dropbox) {
$db_selection = _hierarchical_select_process_get_db_selection($element);
}
}
else {
$hs_selection = _hierarchical_select_process_get_hs_selection($element);
if ($dropbox) {
$db_selection = _hierarchical_select_process_get_db_selection($element);
}
}
}
}
$hs_selection = array_unique($hs_selection);
$db_selection = array_unique($db_selection);
return array(
$hs_selection,
$db_selection,
);
}
function _hierarchical_select_process_render_hs_selects($hsid, $hierarchy) {
$form['#tree'] = TRUE;
$form['#prefix'] = '<div class="selects">';
$form['#suffix'] = '</div>';
foreach ($hierarchy->lineage as $depth => $selected_item) {
$form[$depth] = array(
'#type' => 'select',
'#options' => $hierarchy->levels[$depth],
'#default_value' => $selected_item,
'#DANGEROUS_SKIP_CHECK' => TRUE,
'#theme' => 'hierarchical_select_select',
'#childinfo' => $hierarchy->childinfo[$depth],
);
}
return $form;
}
function _hierarchical_select_process_render_db_hidden($hsid, $dropbox) {
$element['#tree'] = TRUE;
foreach ($dropbox->lineages_selections as $x => $lineage_selection) {
$element['lineages_selections'][$x] = array(
'#type' => 'hidden',
'#value' => serialize($lineage_selection),
);
}
return $element;
}
function _hierarchical_select_process_render_db_visible($hsid, $dropbox) {
$element['#tree'] = TRUE;
$element['#theme'] = 'hierarchical_select_dropbox_table';
$element['title'] = array(
'#type' => 'value',
'#value' => t($dropbox->title),
);
$element['separator'] = array(
'#type' => 'value',
'#value' => '›',
);
$element['is_empty'] = array(
'#type' => 'value',
'#value' => empty($dropbox->lineages),
);
if (!empty($dropbox->lineages)) {
foreach ($dropbox->lineages as $x => $lineage) {
$element['lineages'][$x] = array(
'#zebra' => ($x + 1) % 2 == 0 ? 'even' : 'odd',
'#first' => $x == 0 ? 'first' : '',
'#last' => $x == count($dropbox->lineages) - 1 ? 'last' : '',
);
foreach ($lineage as $depth => $item) {
$is_selected = $dropbox->save_lineage || $depth == count($lineage) - 1;
$element['lineages'][$x][$depth] = array(
'#value' => $item['label'],
'#prefix' => '<span class="dropbox-item' . ($is_selected ? ' dropbox-selected-item' : '') . '">',
'#suffix' => '</span>',
);
}
$element['lineages'][$x]['remove'] = array(
'#type' => 'checkbox',
'#title' => t('Remove'),
);
}
}
return $element;
}
function _hierarchical_select_process_render_flat_select($hierarchy, $dropbox, $config) {
$selection = array();
if ($config['dropbox']['status']) {
foreach ($dropbox->lineages_selections as $lineage_selection) {
$selection = array_merge($selection, $lineage_selection);
}
}
else {
$selection = $hierarchy->lineage;
}
$options = array();
foreach ($selection as $value) {
$is_valid = module_invoke($config['module'], 'hierarchical_select_valid_item', $value, $config['params']);
if ($is_valid) {
$options[$value] = $value;
}
}
$element = array(
'#type' => 'select',
'#multiple' => $config['save_lineage'] || $config['dropbox']['status'],
'#options' => $options,
'#default_value' => array_keys($options),
'#theme' => 'hierarchical_select_select',
'#attributes' => array(
'class' => 'flat-select',
),
);
return $element;
}
function _hierarchical_select_process_calculate_return_value($hierarchy, $dropbox = FALSE, $module, $params, $save_lineage) {
if (!$dropbox) {
$return_value = _hierarchical_select_hierarchy_validate($hierarchy->lineage, $module, $params);
if (!$save_lineage) {
$return_value = is_array($return_value) ? end($return_value) : NULL;
}
$return_value = $return_value != -1 ? $return_value : NULL;
}
else {
$return_value = array();
foreach ($dropbox->lineages_selections as $x => $selection) {
if (!$save_lineage) {
$return_value[] = end($selection);
}
else {
$lineage = _hierarchical_select_hierarchy_validate($selection, $module, $params);
$return_value = array_merge($return_value, $lineage);
}
}
$return_value = array_unique($return_value);
}
return $return_value;
}
function _hierarchical_select_inherit_default_config($config, $defaults_override = array()) {
$type = hierarchical_select_elements();
$defaults = $type['hierarchical_select']['#config'];
unset($defaults['module']);
unset($defaults['params']);
$defaults = array_smart_merge($defaults, $defaults_override);
$config = array_smart_merge($defaults, $config);
return $config;
}
function _hierarchical_select_setup_js() {
static $ran_once;
$jquery_ui_components = array(
'effects.core',
'effects.drop',
);
if (!$ran_once) {
$ran_once = TRUE;
$url = base_path();
$url .= variable_get('clean_url', 0) ? '' : 'index.php?q=';
$url .= 'hierarchical_select_json';
drupal_add_css(drupal_get_path('module', 'hierarchical_select') . '/hierarchical_select.css');
drupal_add_js(drupal_get_path('module', 'hierarchical_select') . '/hierarchical_select.js');
if (variable_get('hierarchical_select_js_cache_system', 0) == 1) {
drupal_add_js(drupal_get_path('module', 'hierarchical_select') . '/hierarchical_select_cache.js');
}
if (!module_exists('jquery_form')) {
drupal_add_js(drupal_get_path('module', 'hierarchical_select') . '/hierarchical_select_formtoarray.js');
}
else {
jquery_form_add();
}
if (!module_exists('jquery_ui')) {
foreach ($jquery_ui_components as $component) {
drupal_add_js(drupal_get_path('module', 'hierarchical_select') . "/js/jquery.ui/{$component}.js");
}
}
else {
jquery_ui_add($jquery_ui_components);
}
drupal_add_js(array(
'HierarchicalSelect' => array(
'url' => $url,
'getArguments' => drupal_query_string_encode($_GET, array(
'q',
)),
),
), 'setting');
}
}
function _hierarchical_select_json_convert_hierarchy_to_cache($hierarchy) {
$cache = array();
foreach ($hierarchy->levels as $depth => $items) {
$weight = 0;
foreach ($items as $value => $label) {
$weight++;
$cache[] = array(
'value' => $value,
'label' => $label,
'parent' => $depth == 0 ? 0 : $hierarchy->lineage[$depth - 1],
'weight' => $weight,
);
}
}
$value = end($hierarchy->lineage);
$cache[] = array(
'value' => $value . '-has-no-children',
'label' => '',
'parent' => $value,
'weight' => 0,
);
return $cache;
}
function _hierarchical_select_mark_as_disabled(&$element) {
$element['#disabled'] = TRUE;
foreach (element_children($element) as $key) {
if (isset($element[$key]) && $element[$key]) {
_hierarchical_select_mark_as_disabled($element[$key]);
}
}
}
function _hierarchical_select_create_new_item_is_allowed($config, $depth) {
return isset($config['editability']['allowed_levels'][$depth]) ? $config['editability']['allowed_levels'][$depth] : 1;
}
function _hierarchical_select_nojs_helptext($dropbox_is_enabled) {
$output = '';
$items = array(
t('<span class="highlight">enable Javascript</span> in your browser and then refresh this page, for a much enhanced experience.'),
t('<span class="highlight">click the <em>Update</em> button</span> every time you want to update the selection'),
);
$items[1] .= !$dropbox_is_enabled ? '.' : t(", or when you've checked some checkboxes for entries in the dropbox you'd like to remove.");
$output .= '<span class="warning">';
$output .= t("You don't have Javascript enabled.");
$output .= '</span> ';
$output .= '<span class="ask-to-hover">';
$output .= t('Hover for more information!');
$output .= '</span> ';
$output .= t("But don't worry: you can still use this web site! You have two options:");
$output .= theme('item_list', $items, NULL, 'ul', array(
'class' => 'solutions',
));
return $output;
}
function _hierarchical_select_get_form_item($form, $name) {
if (isset($form['#name']) && $form['#name'] == $name) {
return $form;
}
foreach (element_children($form) as $child) {
$form_item = _hierarchical_select_get_form_item($form[$child], $name);
if ($form_item !== FALSE) {
return $form_item;
}
}
return FALSE;
}
function _hierarchical_select_store_name($form_item = NULL, $hsid = NULL, $reset = FALSE) {
static $names;
if ($reset) {
$ret = $names;
$names = array();
return $ret;
}
if (isset($form_item) && isset($hsid)) {
$names[$hsid] = $form_item['#name'];
}
return $names;
}
function _hierarchical_select_form_has_hierarchical_select($form) {
if ($form['#type'] == 'hierarchical_select') {
return TRUE;
}
else {
$has_hierarchical_select = FALSE;
foreach (element_children($form) as $name) {
if (is_array($form[$name])) {
$has_hierarchical_select = _hierarchical_select_form_has_hierarchical_select($form[$name]);
if ($has_hierarchical_select) {
break;
}
}
}
return $has_hierarchical_select;
}
}
function _hierarchical_select_form_set_error_class(&$element) {
$config = _hierarchical_select_inherit_default_config($element['#config']);
if ($config['dropbox']['status']) {
form_error($element['dropbox']['visible']);
}
else {
for ($i = 0; $i < count(element_children($element['hierarchical_select']['selects'])); $i++) {
form_error($element['hierarchical_select']['selects'][$i]);
}
}
}
function _hierarchical_select_log($item, $reset = FALSE) {
static $log;
if ($reset) {
$copy_of_log = $log;
$log = array();
return $copy_of_log;
}
$log[] = $item;
}
function _hierarchical_select_hierarchy_generate($config, $selection, $required, $dropbox = FALSE) {
$hierarchy = new stdClass();
$start_lineage = microtime();
if ($config['save_lineage'] && is_array($selection) && count($selection) >= 2) {
$root_level = array_keys(module_invoke($config['module'], 'hierarchical_select_root_level', $config['params']));
for ($i = 0; $i < count($selection); $i++) {
if (in_array($selection[$i], $root_level)) {
if ($i != 0) {
list($selection[0], $selection[$i]) = array(
$selection[$i],
$selection[0],
);
}
break;
}
}
for ($i = 0; $i < count($selection); $i++) {
$children = array_keys(module_invoke($config['module'], 'hierarchical_select_children', $selection[$i], $config['params']));
for ($j = $i + 1; $j < count($selection); $j++) {
if (in_array($selection[$j], $children)) {
list($selection[$j], $selection[$i + 1]) = array(
$selection[$i + 1],
$selection[$j],
);
}
}
}
}
$selection = _hierarchical_select_hierarchy_validate($selection, $config['module'], $config['params']);
if ($selection == -1) {
$root_level = module_invoke($config['module'], 'hierarchical_select_root_level', $config['params']);
$first_case = $config['enforce_deepest'] && $config['level_labels']['status'] && !isset($config['level_labels']['labels'][0]);
$second_case = $dropbox && count($dropbox->lineages) > 0;
$hierarchy->lineage[0] = $first_case || $second_case ? 'none' : 'label_0';
}
else {
if ($config['save_lineage']) {
$hierarchy->lineage = is_array($selection) ? $selection : array(
0 => $selection,
);
}
else {
$selection = is_array($selection) ? $selection[0] : $selection;
if (module_invoke($config['module'], 'hierarchical_select_valid_item', $selection, $config['params'])) {
$hierarchy->lineage = module_invoke($config['module'], 'hierarchical_select_lineage', $selection, $config['params']);
}
else {
$hierarchy->lineage = array();
}
}
}
if ($config['enforce_deepest'] && !in_array($hierarchy->lineage[0], array(
'none',
'label_0',
))) {
$hierarchy->lineage = _hierarchical_select_hierarchy_enforce_deepest($hierarchy->lineage, $config['module'], $config['params']);
}
$end_lineage = microtime();
$start_levels = microtime();
$hierarchy->levels[0] = module_invoke($config['module'], 'hierarchical_select_root_level', $config['params']);
$hierarchy->levels[0] = _hierarchical_select_apply_entity_settings($hierarchy->levels[0], $config);
if ($config['editability']['status'] && module_hook($config['module'], 'hierarchical_select_create_item') && _hierarchical_select_create_new_item_is_allowed($config, 0)) {
$item_type = t($config['editability']['item_types'][0]);
$item_type = !empty($item_type) ? $item_type : t('item');
$option = theme('hierarchical_select_special_option', t('create new !item_type', array(
'!item_type' => $item_type,
)));
$hierarchy->levels[0] = array(
'create_new_item' => $option,
) + $hierarchy->levels[0];
}
$first_case = !$required;
$second_case = $config['enforce_deepest'];
$third_case = $dropbox && count($dropbox->lineages) > 0;
if ($first_case || $second_case || $third_case) {
$option = theme('hierarchical_select_special_option', t('none'));
$hierarchy->levels[0] = array(
'none' => $option,
) + $hierarchy->levels[0];
}
$max_depth = count($hierarchy->lineage) - 1;
for ($depth = 1; $depth <= $max_depth; $depth++) {
$hierarchy->levels[$depth] = module_invoke($config['module'], 'hierarchical_select_children', $hierarchy->lineage[$depth - 1], $config['params']);
$hierarchy->levels[$depth] = _hierarchical_select_apply_entity_settings($hierarchy->levels[$depth], $config);
}
if ($config['enforce_deepest']) {
if ($config['editability']['status'] && module_hook($config['module'], 'hierarchical_select_create_item')) {
for ($depth = 1; $depth <= $max_depth; $depth++) {
$item_type = t($config['editability']['item_types'][$depth]);
$item_type = !empty($item_type) ? $item_type : t('item');
$option = theme('hierarchical_select_special_option', t('create new !item_type', array(
'!item_type' => $item_type,
)));
if (_hierarchical_select_create_new_item_is_allowed($config, $depth)) {
$hierarchy->levels[$depth] = array(
'create_new_item' => $option,
) + $hierarchy->levels[$depth];
}
}
}
if ($config['level_labels']['status'] && isset($config['level_labels']['labels'][0])) {
$hierarchy->levels[0] = array(
'label_0' => t($config['level_labels']['labels'][0]),
) + $hierarchy->levels[0];
}
}
else {
if (!$config['enforce_deepest']) {
for ($depth = 0; $depth <= $max_depth; $depth++) {
if ($depth > 0 && $config['editability']['status'] && module_hook($config['module'], 'hierarchical_select_create_item') && _hierarchical_select_create_new_item_is_allowed($config, $depth)) {
$item_type = t($config['editability']['item_types'][$depth]);
$item_type = !empty($item_type) ? $item_type : t('item');
$option = theme('hierarchical_select_special_option', t('create new !item_type', array(
'!item_type' => $item_type,
)));
$hierarchy->levels[$depth] = array(
'create_new_item' => $option,
) + $hierarchy->levels[$depth];
}
$label = $config['level_labels']['status'] && isset($config['level_labels']['labels'][$depth]) ? t($config['level_labels']['labels'][$depth]) : '';
$hierarchy->levels[$depth] = array(
'label_' . $depth => $label,
) + $hierarchy->levels[$depth];
}
if ($hierarchy->levels[0]['label_0'] == '' && isset($hierarchy->levels[0]['none'])) {
unset($hierarchy->levels[0]['label_0']);
if ($hierarchy->lineage[0] == 'label_0') {
$hierarchy->lineage[0] = 'none';
}
}
$parent = $hierarchy->lineage[$max_depth];
if (module_invoke($config['module'], 'hierarchical_select_valid_item', $parent, $config['params'])) {
$children = module_invoke($config['module'], 'hierarchical_select_children', $parent, $config['params']);
if (count($children)) {
$depth = $max_depth + 1;
$hierarchy->levels[$depth] = array();
if ($config['editability']['status'] && module_hook($config['module'], 'hierarchical_select_create_item') && _hierarchical_select_create_new_item_is_allowed($config, $depth)) {
$item_type = t($config['editability']['item_types'][$depth]);
$item_type = !empty($item_type) ? $item_type : t('item');
$option = theme('hierarchical_select_special_option', t('create new !item_type', array(
'!item_type' => $item_type,
)));
$hierarchy->levels[$depth] = array(
'create_new_item' => $option,
);
}
$hierarchy->lineage[$depth] = 'label_' . $depth;
$label = $config['level_labels']['status'] ? t($config['level_labels']['labels'][$depth]) : '';
$hierarchy->levels[$depth] = array(
'label_' . $depth => $label,
) + $hierarchy->levels[$depth] + $children;
$hierarchy->levels[$depth] = _hierarchical_select_apply_entity_settings($hierarchy->levels[$depth], $config);
}
}
}
}
if ($config['editability']['status'] && $config['editability']['allow_new_levels'] && ($config['editability']['max_levels'] == 0 || count($hierarchy->lineage) < $config['editability']['max_levels']) && module_invoke($config['module'], 'hierarchical_select_valid_item', end($hierarchy->lineage), $config['params']) && module_hook($config['module'], 'hierarchical_select_create_item')) {
$depth = $max_depth + 1;
$hierarchy->lineage[$depth] = 'label_' . $depth;
$label = $config['level_labels']['status'] ? t($config['level_labels']['labels'][$depth]) : '';
$item_type = t($config['editability']['item_types'][$depth]);
$item_type = !empty($item_type) ? $item_type : t('item');
$option = theme('hierarchical_select_special_option', t('create new !item_type', array(
'!item_type' => $item_type,
)));
$hierarchy->levels[$depth] = array(
'label_' . $depth => $label,
'create_new_item' => $option,
);
}
$end_levels = microtime();
$start_childinfo = microtime();
$hierarchy = _hierarchical_select_hierarchy_add_childinfo($hierarchy, $config);
$end_childinfo = microtime();
$hierarchy->build_time['total'] = ($end_childinfo - $start_lineage) * 1000;
$hierarchy->build_time['lineage'] = ($end_lineage - $start_lineage) * 1000;
$hierarchy->build_time['levels'] = ($end_levels - $start_levels) * 1000;
$hierarchy->build_time['childinfo'] = ($end_childinfo - $start_childinfo) * 1000;
return $hierarchy;
}
function _hierarchical_select_apply_entity_settings($level, $config) {
if (($config['entity_count'] || $config['require_entity']) && module_hook($config['module'], 'hierarchical_select_entity_count')) {
foreach ($level as $item => $label) {
if (!preg_match('/(none|label_\\d+|create_new_item)/', $item)) {
$entity_count = module_invoke($config['module'], 'hierarchical_select_entity_count', $item, $config['params']);
if ($config['require_entity'] && $entity_count == 0) {
unset($level[$item]);
}
elseif ($config['entity_count']) {
$level[$item] = "{$label} ({$entity_count})";
}
}
}
}
return $level;
}
function _hierarchical_select_hierarchy_add_childinfo($hierarchy, $config) {
foreach ($hierarchy->levels as $depth => $level) {
foreach (array_keys($level) as $item) {
if (!preg_match('/(none|label_\\d+|create_new_item)/', $item)) {
$hierarchy->childinfo[$depth][$item] = count(module_invoke($config['module'], 'hierarchical_select_children', $item, $config['params']));
}
}
}
return $hierarchy;
}
function _hierarchical_select_hierarchy_validate($selection, $module, $params) {
$valid = TRUE;
$selection_levels = count($selection);
for ($i = 0; $i < $selection_levels; $i++) {
if ($valid) {
$valid = module_invoke($module, 'hierarchical_select_valid_item', $selection[$i], $params);
if ($i > 0) {
$parent = $selection[$i - 1];
$child = $selection[$i];
$children = array_keys(module_invoke($module, 'hierarchical_select_children', $parent, $params));
$valid = $valid && in_array($child, $children);
}
}
if (!$valid) {
unset($selection[$i]);
}
}
if (empty($selection)) {
$selection = -1;
}
return $selection;
}
function _hierarchical_select_hierarchy_enforce_deepest($lineage, $module, $params) {
$parent = end($lineage);
$children = module_invoke($module, 'hierarchical_select_children', $parent, $params);
while (count($children)) {
$first_child = reset(array_keys($children));
$lineage[] = $first_child;
$parent = $first_child;
$children = module_invoke($module, 'hierarchical_select_children', $parent, $params);
}
return $lineage;
}
function _hierarchical_select_dropbox_generate($config, $selection) {
$dropbox = new stdClass();
$start = microtime();
$dropbox->title = !empty($config['dropbox']['title']) ? $config['dropbox']['title'] : t('All selections');
$dropbox->lineages = array();
$dropbox->lineages_selections = array();
foreach ($selection as $key => $item) {
if (!module_invoke($config['module'], 'hierarchical_select_valid_item', $item, $config['params'])) {
unset($selection[$key]);
}
}
if (!empty($selection)) {
$dropbox->save_lineage = $config['save_lineage'];
if ($config['save_lineage']) {
$dropbox->lineages = _hierarchical_select_dropbox_reconstruct_lineages_save_lineage_enabled($config['module'], $selection, $config['params']);
}
else {
foreach ($selection as $item) {
$dropbox->lineages[] = module_invoke($config['module'], 'hierarchical_select_lineage', $item, $config['params']);
}
foreach ($dropbox->lineages as $id => $lineage) {
foreach ($lineage as $level => $item) {
$dropbox->lineages[$id][$level] = array(
'value' => $item,
'label' => check_plain(module_invoke($config['module'], 'hierarchical_select_item_get_label', $item, $config['params'])),
);
}
}
}
usort($dropbox->lineages, '_hierarchical_select_dropbox_sort');
foreach ($dropbox->lineages as $id => $lineage) {
if ($config['save_lineage']) {
$dropbox->lineages_selections[$id] = array_map('_hierarchical_select_dropbox_lineage_item_get_value', $lineage);
}
else {
$dropbox->lineages_selections[$id][0] = $lineage[count($lineage) - 1]['value'];
}
}
}
$dropbox->build_time = (microtime() - $start) * 1000;
return $dropbox;
}
function _hierarchical_select_dropbox_reconstruct_lineages_save_lineage_enabled($module, $selection, $params) {
$lineages = array();
$root_level = module_invoke($module, 'hierarchical_select_root_level', $params);
foreach ($selection as $key => $item) {
if (array_key_exists($item, $root_level)) {
$lineages[][0] = array(
'value' => $item,
'label' => $root_level[$item],
);
unset($selection[$key]);
}
}
$at_least_one = TRUE;
for ($i = 0; $at_least_one; $i++) {
$at_least_one = FALSE;
$num = count($lineages);
for ($id = 0; $id < $num; $id++) {
$children = module_invoke($module, 'hierarchical_select_children', $lineages[$id][$i]['value'], $params);
$child_added_to_lineage = FALSE;
foreach (array_keys($children) as $child) {
if (in_array($child, $selection)) {
if (!$child_added_to_lineage) {
$lineages[$id][$i + 1] = array(
'value' => $child,
'label' => $children[$child],
);
$child_added_to_lineage = TRUE;
$at_least_one = TRUE;
}
else {
$lineage = $lineages[$id];
$lineage[$i + 1] = array(
'value' => $child,
'label' => $children[$child],
);
$lineages[] = $lineage;
}
}
}
}
}
return $lineages;
}
function _hierarchical_select_dropbox_sort($lineage_a, $lineage_b) {
$string_a = implode('', array_map('_hierarchical_select_dropbox_lineage_item_get_label', $lineage_a));
$string_b = implode('', array_map('_hierarchical_select_dropbox_lineage_item_get_label', $lineage_b));
return strcmp($string_a, $string_b);
}
function _hierarchical_select_dropbox_lineage_item_get_label($item) {
return t($item['label']);
}
function _hierarchical_select_dropbox_lineage_item_get_value($item) {
return $item['value'];
}
function _hierarchical_select_options($element) {
if (!isset($choices)) {
$choices = $element['#options'];
}
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
$value_is_array = is_array($element['#value']);
$options = '';
foreach ($choices as $key => $choice) {
$key = (string) $key;
if ($value_valid && (!$value_is_array && (string) $element['#value'] === $key || $value_is_array && in_array($key, $element['#value']))) {
$selected = ' selected="selected"';
}
else {
$selected = '';
}
if (!isset($element['#childinfo'][$key])) {
$class = preg_match('/label_\\d+/', $key) ? ' level-label' : '';
}
else {
$class = $element['#childinfo'][$key] == 0 ? 'has-no-children' : 'has-children';
}
$options .= '<option value="' . check_plain($key) . '" class="' . $class . '"' . $selected . '>' . check_plain($choice) . '</option>';
}
return $options;
}
function _hierarchical_select_get_hs_form_build_id() {
$hs_form_build_id = $_POST['hs_form_build_id'];
if (empty($hs_form_build_id)) {
foreach ($_POST as $key => $value) {
if (is_array($_POST[$key]) && !empty($_POST[$key]['hs_form_build_id'])) {
return $_POST[$key]['hs_form_build_id'];
}
}
}
return $hs_form_build_id;
}
if (!function_exists('array_smart_merge')) {
function array_smart_merge($array, $override) {
if (is_array($array) && is_array($override)) {
foreach ($override as $k => $v) {
if (isset($array[$k]) && is_array($v) && is_array($array[$k])) {
$array[$k] = array_smart_merge($array[$k], $v);
}
else {
$array[$k] = $v;
}
}
}
return $array;
}
}
function theme_hierarchical_select($element) {
$output = '';
$hsid = $element['hsid']['#value'];
$level_labels_style = variable_get('hierarchical_select_level_labels_style', 'none');
$classes = array(
'hierarchical-select-wrapper',
"hierarchical-select-level-labels-style-{$level_labels_style}",
'hierarchical-select-wrapper-for-name-' . $element['#id'],
isset($element['#config']['config_id']) ? 'hierarchical-select-wrapper-for-config-' . $element['#config']['config_id'] : NULL,
);
$element['#attributes']['class'] .= ' ' . implode(' ', $classes);
$element['#attributes']['id'] = "hierarchical-select-{$hsid}-wrapper";
$element['#id'] = "hierarchical-select-{$hsid}-wrapper";
$output .= theme('form_element', array(
'#title' => $element['#title'],
'#description' => $element['#description'],
'#id' => $element['#id'],
'#required' => $element['#required'],
'#error' => $element['#error'],
), '<div ' . drupal_attributes($element['#attributes']) . '>' . $element['#children'] . '</div>');
return $output;
}
function theme_hierarchical_select_selects_container($element) {
$output = '';
$output .= '<div class="hierarchical-select clear-block">';
$output .= drupal_render($element);
$output .= '</div>';
return $output;
}
function theme_hierarchical_select_select($element) {
$select = '';
$size = $element['#size'] ? ' size="' . $element['#size'] . '"' : '';
$class = array(
'form-select',
);
if (form_get_error($element) === '') {
$class = array_merge($class, array(
'error',
));
}
_form_set_class($element, $class);
$multiple = isset($element['#multiple']) && $element['#multiple'];
return '<select name="' . $element['#name'] . '' . ($multiple ? '[]' : '') . '"' . ($multiple ? ' multiple="multiple" ' : '') . drupal_attributes($element['#attributes']) . ' id="' . $element['#id'] . '" ' . $size . '>' . _hierarchical_select_options($element) . '</select>';
}
function theme_hierarchical_select_special_option($option) {
return '<' . $option . '>';
}
function theme_hierarchical_select_textfield($element) {
$size = $element['#size'] ? ' size="' . $element['#size'] . '"' : '';
$class = array(
'form-text',
);
$extra = '';
$output = '';
if ($element['#autocomplete_path']) {
drupal_add_js('misc/autocomplete.js');
$class[] = 'form-autocomplete';
$extra = '<input class="autocomplete" type="hidden" id="' . $element['#id'] . '-autocomplete" value="' . check_url(url($element['#autocomplete_path'], NULL, NULL, TRUE)) . '" disabled="disabled" />';
}
_form_set_class($element, $class);
if (isset($element['#field_prefix'])) {
$output .= '<span class="field-prefix">' . $element['#field_prefix'] . '</span> ';
}
$output .= '<input type="text" maxlength="' . $element['#maxlength'] . '" name="' . $element['#name'] . '" id="' . $element['#id'] . '" ' . $size . ' value="' . check_plain($element['#value']) . '"' . drupal_attributes($element['#attributes']) . ' />';
if (isset($element['#field_suffix'])) {
$output .= ' <span class="field-suffix">' . $element['#field_suffix'] . '</span>';
}
return $output . $extra;
}
function theme_hierarchical_select_dropbox_table($element) {
$output = '';
$class = 'dropbox';
if (form_get_error($element) === '') {
$class .= ' error';
}
$title = $element['title']['#value'];
$separator = $element['separator']['#value'];
$is_empty = $element['is_empty']['#value'];
$separator_html = '<span class="hierarchical-select-item-separator">' . $separator . '</span>';
$output .= '<div class="' . $class . '">';
$output .= '<table>';
$output .= '<caption class="dropbox-title">' . $title . '</caption>';
$output .= '<tbody>';
if (!$is_empty) {
$lineage_count = count(element_children($element['lineages']));
for ($x = 0; $x < $lineage_count; $x++) {
$db_entry = $element['lineages'][$x];
$zebra = $db_entry['#zebra'];
$first = $db_entry['#first'];
$last = $db_entry['#last'];
$deepest_level = count(element_children($db_entry)) - 1;
$output .= '<tr class="dropbox-entry ' . $first . ' ' . $last . ' ' . $zebra . '">';
$output .= '<td>';
for ($depth = 0; $depth < $deepest_level; $depth++) {
$output .= drupal_render($db_entry[$depth]);
if ($depth < $deepest_level - 1) {
$output .= $separator_html;
}
}
$output .= '</td>';
$output .= '<td class="dropbox-remove">' . drupal_render($db_entry['remove']) . '</td>';
$output .= '</tr>';
}
}
else {
$output .= '<tr class="dropbox-entry first last dropbox-is-empty"><td>';
$output .= t('Nothing has been selected.');
$output .= '</td></tr>';
}
$output .= '</tbody>';
$output .= '</table>';
$output .= '</div>';
return $output;
}
function theme_hierarchical_select_selection_as_lineages($selection, $config) {
$output = '';
$selection = !is_array($selection) ? array(
$selection,
) : $selection;
$selection = array_keys($selection);
$dropbox = _hierarchical_select_dropbox_generate($config, $selection);
foreach ($dropbox->lineages as $id => $lineage) {
if ($id > 0) {
$output .= '<br />';
}
$items = array();
foreach ($lineage as $level => $item) {
$items[] = $item['label'];
}
$output .= implode('<span class="hierarchical-select-item-separator">›</span>', $items);
}
drupal_add_css(drupal_get_path('module', 'hierarchical_select') . '/hierarchical_select.css');
return $output;
}