You are here

function redhen_relation_connection_form in RedHen CRM 7

Return a form array for adding/editing a connection.

Parameters

array $form: Form array.

array $form_state: Form state array.

RedhenContact|RedhenOrg $entity: Entity object.

Relation $relation: Relation entity.

Return value

mixed Form array.

1 string reference to 'redhen_relation_connection_form'
redhen_relation_menu in modules/redhen_relation/redhen_relation.module
Implements hook_menu().

File

modules/redhen_relation/includes/redhen_relation.forms.inc, line 23
Form definition and handling for redhen relations.

Code

function redhen_relation_connection_form($form, &$form_state, $entity, $relation = NULL) {

  // Is this editing an existing relation?
  $edit = !empty($relation->rid) ? TRUE : FALSE;
  $new = NULL;
  $entity_label = NULL;

  // New relation.
  if (!$edit) {
    $relation_types = redhen_relation_get_available_types($entity
      ->entityType(), $entity
      ->bundle(), 'both');

    // There are no valid relation types for this entity, so exit w/message.
    if (empty($relation_types)) {
      $form['message'] = array(
        '#markup' => t('%label has no valid relation types so a connection cannot be made.', array(
          '%label' => $entity
            ->label(),
        )),
      );
      return $form;
    }

    // Instantiate new relation based on default or submitted relation type.
    $relation_type = isset($form_state['values']['relation_type']) ? $form_state['values']['relation_type'] : reset($relation_types)->relation_type;
    $relation = relation_create($relation_type, array());
  }
  else {

    // Edit existing, so we know the entity type.
    $entity_type_to_relate = $entity
      ->entityType();
    $default_entity_type = $entity
      ->bundle();
    $info = entity_get_info($entity_type_to_relate);
    $entity_label = $info['label'];
  }

  // Store contact and relation entities for use on submit.
  $form_state['entity'] = $entity;
  $form_state['relation'] = $relation;
  $form['relation_settings'] = array(
    '#type' => 'fieldset',
    '#id' => 'redhen_relation_fields',
    '#title' => t('Connection'),
  );

  // Attach any fields.
  field_attach_form('relation', $relation, $form['relation_settings'], $form_state);

  // Wrapper used for the Org or Contact entity itself.
  $form['relation_settings']['entity_info'] = array(
    '#type' => 'fieldset',
    '#weight' => 9,
    '#prefix' => '<div id="related-entity">',
    '#suffix' => '</div>',
    '#title' => $entity_label,
  );
  if (!$edit) {

    // Load all available relation types.
    $options = array();
    foreach ($relation_types as $type) {
      list($endpoint_entity_type) = explode(':', $type->source_bundles[0]);
      $reverse = $type->directional & $endpoint_entity_type == $entity
        ->entityType();
      $options[$type->relation_type] = relation_get_type_label($type, $reverse);
    }
    $form['relation_type'] = array(
      '#title' => t('Connection type'),
      '#type' => 'select',
      '#options' => $options,
      '#default_value' => isset($relation) ? $relation->relation_type : NULL,
      '#ajax' => array(
        'callback' => 'redhen_relation_form_refresh',
        'wrapper' => 'redhen_relation_fields',
        'method' => 'replace',
        'effect' => 'fade',
        'progress' => array(
          'type' => 'throbber',
          'message' => t('Retrieving fields for this connection type.'),
        ),
      ),
      '#weight' => -99,
    );

    // Determine the entity type we're going to relate to.
    $active_relation_type = $relation_types[$relation_type];
    $entity_type_to_relate = '';
    if (!empty($active_relation_type->target_bundles)) {
      list($tgt_entity_type) = explode(':', $active_relation_type->target_bundles[0]);
      if ($entity
        ->entityType() != $tgt_entity_type) {
        $entity_type_to_relate = $tgt_entity_type;
      }
    }
    if (empty($entity_type_to_relate)) {
      list($entity_type_to_relate) = explode(':', $active_relation_type->source_bundles[0]);
    }
    $info = entity_get_info($entity_type_to_relate);
    $plural_label = isset($info['plural label']) ? $info['plural label'] : $info['label'] . 's';
    $form['relation_settings']['entity_info']['#title'] = $info['label'];
    $new = isset($form_state['values']['new_or_existing']) ? $form_state['values']['new_or_existing'] : 1;
    $form['relation_settings']['new_or_existing'] = array(
      '#title' => t('New or existing @type', array(
        '@type' => drupal_strtolower($info['label']),
      )),
      '#type' => 'select',
      '#options' => array(
        1 => 'New',
        0 => 'Existing',
      ),
      '#default_value' => $new,
      '#weight' => 9,
      '#required' => TRUE,
      '#ajax' => array(
        'callback' => 'redhen_relation_form_related_entity_refresh',
        'wrapper' => 'related-entity',
      ),
    );
    if ($new == 0) {
      $form['relation_settings']['entity_info']['entity_to_relate'] = array(
        '#title' => $plural_label,
        '#type' => 'textfield',
        '#required' => $active_relation_type->min_arity == 1 ? FALSE : TRUE,
        '#access' => $active_relation_type->max_arity == 1 ? FALSE : TRUE,
        '#autocomplete_path' => 'redhen/relation/autocomplete/' . $relation->relation_type . '/' . $entity_type_to_relate . '/' . $entity
          ->entityType() . '/' . $entity
          ->internalIdentifier(),
        '#weight' => 10,
      );
    }
  }
  if ($new == 1 || $edit) {

    // Get entity callbacks and variables.
    $entity_types = array();
    switch ($entity_type_to_relate) {
      case 'redhen_contact':
        module_load_include('inc', 'redhen_contact', 'includes/redhen_contact.forms');
        $entity_types = redhen_contact_get_types();
        $create_function = 'redhen_contact_create';
        $entity_form_callback = 'redhen_contact_contact_form';
        break;
      case 'redhen_org':
        module_load_include('inc', 'redhen_org', 'includes/redhen_org.forms');
        $entity_types = redhen_org_get_types();
        $create_function = 'redhen_org_create';
        $entity_form_callback = 'redhen_org_org_form';
        break;
    }
    if (!$edit) {
      foreach ($entity_types as $type_name => $type) {
        $entity_type_options[$type_name] = $type->label;
      }
      $default_entity_type = key($entity_type_options);
      $form['relation_settings']['entity_info']['entity_type'] = array(
        '#type' => 'select',
        '#title' => t('Select @type type', array(
          '@type' => drupal_strtolower($info['label']),
        )),
        '#options' => $entity_type_options,
        '#default_value' => $default_entity_type,
        '#ajax' => array(
          'callback' => 'redhen_relation_form_related_entity_info_refresh',
          'wrapper' => 'entity-form',
        ),
        '#id' => 'entity-type',
      );
    }
    $entity_type = isset($form_state['input']['entity_type']) ? $form_state['input']['entity_type'] : $default_entity_type;
    if (!is_null($entity_type)) {
      $target_entity = $edit ? $entity : $create_function(array(
        'type' => $entity_type,
      ));

      // This either needs to be a new connection or user needs to have
      // permission to edit the related entity.
      if (!$edit || entity_access('edit', $entity_type_to_relate, $target_entity)) {
        $entity_form = $entity_form_callback(array(), $form_state, $target_entity);
        unset($entity_form['actions']);
      }
      else {
        $entity_form = array(
          '#markup' => entity_label($entity_type_to_relate, $target_entity),
        );
      }
    }
    else {
      $entity_form = array();
    }
    $entity_form['#prefix'] = '<div id="entity-form">';
    $entity_form['#suffix'] = '</div>';
    $form['relation_settings']['entity_info']['entity_form'] = $entity_form;
  }

  // Hide the endpoints field widget. @TODO: Find out why appearing.
  $form['relation_settings']['endpoints']['#access'] = FALSE;
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save connection'),
    '#weight' => 29,
  );
  $form_state['entity_to_relate_type'] = $entity_type_to_relate;
  return $form;
}