You are here

function relation_add_block_block_form in Relation add 7

The relation add block form.

1 string reference to 'relation_add_block_block_form'
relation_add_block_block_view in modules/relation_add_block/relation_add_block.module
Implements hook_block_view().

File

modules/relation_add_block/relation_add_block.module, line 36
Relation Add Block module file.

Code

function relation_add_block_block_form($form, &$form_state) {
  $form['#attached']['css'] = array(
    drupal_get_path('module', 'relation_add') . '/relation_add.css',
  );

  // This stuff is only relevant if we're NOT in an AJAX call.
  if (!isset($form_state['triggering_element']['#ajax'])) {

    // Get the entity for the current page. This fails for taxonomy entities.
    // Need a better way. Also, this will never really work for comments, or
    // files, or other entities that don't have their own page.
    $all_entities = array_keys(entity_get_info());
    $path = menu_get_item();
    if (count($path['map']) >= 2 && in_array($path['map'][0], $all_entities) && is_object($path['map'][1])) {
      $entity_type = $path['map'][0];
      $entity = $path['map'][1];
    }
    elseif (count($path['map']) >= 3 && $path['map'][0] == 'taxonomy' && is_object($path['map'][2])) {
      $entity_type = 'taxonomy_term';
      $entity = $path['map'][2];
    }
    elseif ($path['original_map'][0] == 'colorbox') {
      $entity_info = explode('/', $path['map'][1]);
      $entities = entity_load($entity_info[0], array(
        $entity_info[1],
      ));
      $entity = $entities[$entity_info[1]];
      $entity_type = $entity_info[0];
    }
    else {
      $entity_info = module_invoke_all('relation_add_load_entity');
      if (is_array($entity_info) && count($entity_info) > 1) {
        list($entity_type, $entity) = $entity_info;
      }
    }
    if (!isset($entity)) {
      $form['explanation']['#markup'] = t("No entity found, can't create a relation!");
      return $form;
    }
    else {

      // If we have an $entity, then we have an $entity_type.
      $entity_label = entity_label($entity_type, $entity);
      list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
      $label = $entity_label . ' [' . $entity_type . ':' . $id . ']';
      $relation_types = relation_get_available_types($entity_type, $bundle);
      $reverse_types = relation_get_available_types($entity_type, $bundle, 'target');
      $form_state['relation_add'] = $label;
    }
    if (empty($relation_types) && empty($reverse_types)) {

      // Act as helper block if no relation types are defined.
      $form['explanation']['#markup'] = t("Before you can create relations from entities of this bundle type (!bundle), you need to create one or more !link that include the bundle in the allowed bundles list.\n        Once you've done that, visit any page displays an entity, and use this block to add a new relation from that entity.", array(
        '!bundle' => $entity_type . ':' . $bundle,
        '!link' => l(t('relation types'), 'admin/structure/relation'),
      ));
      return $form;
    }
    $form['current_entity'] = array(
      '#type' => 'textfield',
      '#title' => t('Create a relation from'),
      '#value' => $label,
      '#disabled' => TRUE,
    );

    // Relation type selector. On change, rest of form is loaded via ajax.
    $types = array();
    foreach ($relation_types as $relation_type) {
      $types[$relation_type->relation_type] = $relation_type->label;
    }
    foreach ($reverse_types as $relation_type) {
      if ($relation_type->directional && $relation_type->max_arity == 2) {

        // Directional n-ary relations are f@*#ing stupid.
        // Machine name doesn't have colons, so we add a suffix for reverse
        // relations, which we explode off later.
        $types[$relation_type->relation_type . ':reverse'] = $relation_type->reverse_label ? $relation_type->reverse_label : 'reverse ' . $relation_type->reverse_label;
      }
    }
    ksort($types);
    $form_state['types'] = $types;

    // End non-AJAX part.
  }
  if (count($form_state['types']) > 1) {
    $form['relation_type'] = array(
      '#type' => 'select',
      '#title' => t('Relation type'),
      '#options' => $form_state['types'],
      '#empty_value' => '',
      '#empty_option' => t('Select a relation type'),
      '#ajax' => array(
        'callback' => 'relation_add_block_block_ajax',
        'wrapper' => 'block-relation-add-options',
        'method' => 'replace',
        'effect' => 'fade',
      ),
    );
  }
  else {
    $form['relation_type'] = array(
      '#type' => 'value',
      // Key of the first option.
      '#value' => key($form_state['types']),
    );
    $form['relation_type_item'] = array(
      '#type' => 'item',
      '#title' => t('Relation type'),
      '#markup' => current($form_state['types']),
    );

    // Pretend we've already returned from the AJAX callback.
    $form_state['values']['relation_type'] = $form['relation_type']['#value'];
  }
  $type = '';
  if (!empty($form_state['values']['relation_type'])) {

    // Remove ':reverse' suffix if it exists, and set reverse flag.
    $type_array = explode(':', $form_state['values']['relation_type']);
    $type = $type_array[0];
    $form_state['relation_reverse'] = isset($type_array[1]) && $type_array[1] == 'reverse';
  }
  $form['relation_options'] = array(
    '#prefix' => '<div id="block-relation-add-options">',
    '#suffix' => '</div>',
  );

  // AJAXification.
  if (!empty($form_state['values']['relation_type'])) {
    $relation_type = relation_type_load($type);
    $relation = (object) relation_create($type, array());

    // Create one autocomplete for each endpoint beyond the first.
    $direction = $form_state['relation_reverse'] ? '/source' : '/target';
    for ($i = 2; $i <= $relation_type->max_arity; $i++) {
      $form['relation_options']['targets']['target_' . $i] = array(
        '#type' => 'textfield',
        '#title' => t('Endpoint @num', array(
          '@num' => $i,
        )),
        '#autocomplete_path' => 'relation_add/autocomplete/' . $type . $direction . '/none' . '/all',
      );
    }
    field_attach_form('relation', $relation, $form['relation_options'], $form_state);
    unset($form['relation_options']['endpoints']);
    $form['relation_options']['save'] = array(
      '#type' => 'submit',
      '#weight' => 100,
      '#value' => t('Create relation'),
      '#submit' => array(
        'relation_add_save',
      ),
    );
  }
  else {
    $form['relation_options']['explanation'] = array(
      '#prefix' => '<div id=\'relation-add-explanation\'>',
      '#markup' => t('This block allows you to create a relation from the current entity (the one displayed on this page), to another one. Please select a relation type.'),
      '#suffix' => '</div>',
    );
  }
  return $form;
}