You are here

function _hierarchical_select_process_get_db_selection in Hierarchical Select 7.3

Same name and namespace in other branches
  1. 5.3 hierarchical_select.module \_hierarchical_select_process_get_db_selection()
  2. 6.3 hierarchical_select.module \_hierarchical_select_process_get_db_selection()

Get the current (flat) selection of the dropbox.

This selection is not updatable by the user, because the values are retrieved from the hidden values in $element['dropbox']['hidden']['lineages_selections']. This selection can only be updated by the server, i.e. when the user clicks the "Add" button. But this selection can still be reduced in size if the user has marked dropbox entries (lineages) for removal.

Parameters

$element: A hierarchical_select form element.

$form_state: The $form_state array. We need to look at $form_state['storage']['hs'][$hsid]['dropbox_lineages_selections'] to know what to remove.

Return value

An array (bag) containing the ids of the selected items in the dropbox.

1 call to _hierarchical_select_process_get_db_selection()
_hierarchical_select_process_calculate_selections in ./hierarchical_select.module
Calculates the flat selections of both the hierarchical select and the dropbox.

File

./hierarchical_select.module, line 1048
This module defines the "hierarchical_select" form element, which is a greatly enhanced way for letting the user select items in a hierarchy.

Code

function _hierarchical_select_process_get_db_selection($element, $hsid, &$form_state) {
  $db_selection = array();
  if (!empty($form_state['storage']['hs'][$hsid]['dropbox_lineages_selections'])) {

    // Check which lineages have been marked for removal by the user.
    $remove_from_db_selection = array();
    if (isset($element['#value']['dropbox']['visible']['lineages'])) {
      foreach ($element['#value']['dropbox']['visible']['lineages'] as $x => $remove_value) {
        if ($remove_value['remove'] === '1') {

          // $x is of the form "lineage-<number>". Extract the number.
          $remove_from_db_selection[] = substr($x, 8);

          // By removing the input (POST) reference to the remove checkbox,
          // we make sure that on a form rebuild the same remove checkbox,
          // which is accessed by index, is not set, preventing a double removal.
          // @see https://www.drupal.org/node/1566878#comment-9226261
          $elm =& $form_state['input'];
          foreach ($element['#parents'] as $parent) {
            $elm =& $elm[$parent];
          }
          unset($elm['dropbox']['visible']['lineages'][$x]['remove']);
        }
      }
    }

    // Add all selections to the dropbox selection, except for the ones that
    // are scheduled for removal.
    foreach ($form_state['storage']['hs'][$hsid]['dropbox_lineages_selections'] as $x => $selection) {
      if (!in_array($x, $remove_from_db_selection)) {
        $db_selection = array_merge($db_selection, $selection);
      }
    }

    // Ensure that the last item of each selection that was scheduled for
    // removal is completely absent from the dropbox selection.
    // In case of a tree with multiple parents, the same item can exist in
    // different entries, and thus it would stay in the selection. When the
    // server then reconstructs all lineages, the lineage we're removing, will
    // also be reconstructed: it will seem as if the removing didn't work!
    // This will not break removing dropbox entries for hierarchies without
    // multiple parents, since items at the deepest level are always unique to
    // that specific lineage.
    // Easier explanation at http://drupal.org/node/221210#comment-733715.
    foreach ($remove_from_db_selection as $key => $x) {
      $item = end($form_state['storage']['hs'][$hsid]['dropbox_lineages_selections'][$x]);
      $position = array_search($item, $db_selection);
      if ($position) {
        unset($db_selection[$position]);
      }
    }
    $db_selection = array_unique($db_selection);
  }
  return $db_selection;
}