You are here

function _webform_civicrm_webform_frontend_form_alter in Webform CiviCRM Integration 7.2

Same name and namespace in other branches
  1. 6.2 webform_civicrm_forms.inc \_webform_civicrm_webform_frontend_form_alter()
  2. 6 webform_civicrm_forms.inc \_webform_civicrm_webform_frontend_form_alter()
  3. 7 webform_civicrm_forms.inc \_webform_civicrm_webform_frontend_form_alter()

Alter front-end of webforms: Called by hook_form_alter() when rendering a civicrm-enabled webform Add custom prefix. Display messages. Block users who should not have access. Set webform default values.

1 call to _webform_civicrm_webform_frontend_form_alter()
webform_civicrm_form_alter in ./webform_civicrm.module
Implements hook_form_alter().

File

./webform_civicrm_forms.inc, line 19

Code

function _webform_civicrm_webform_frontend_form_alter(&$form, &$form_state) {
  webform_civicrm_add_js('webform_civicrm_webforms.js');
  $form['#validate'][] = 'webform_civicrm_form_validate';
  array_unshift($form['#submit'], 'webform_civicrm_storage');
  civicrm_initialize();
  $config = CRM_Core_Config::singleton();
  $node = $form['#node'];
  $settings = $node->webform_civicrm;
  $data = $settings['data'];
  $fields = webform_civicrm_get_fields();
  $id = $info = $args = array();

  // JS Cache eliminates the need for most ajax state/province callbacks
  foreach ($data['contact'] as $c) {
    if (!empty($c['number_of_address'])) {
      $dc = $config->defaultContactCountry;
      $js = '
        var stateProvinceDefault = ' . json_encode(webform_civicrm_get_options('state_province', $dc)) . ";\n        var stateProvinceCache = {\n          'default':stateProvinceDefault,\n          '{$dc}':stateProvinceDefault,\n          '':{'':'" . t('- first choose a country -') . "'}};\n        var webformSelectNa = '" . t('- N/A -') . "';\n        var webformSelectNone = '" . t('- None -') . "';\n        var webformSelectSelect = '" . t('- Select -') . "';";
      webform_civicrm_add_js($js, 'inline');
      break;
    }
  }

  // Early return if the form (or page) was already submitted
  if (webform_civicrm_aval($form_state, 'clicked_button:#id') == 'edit-previous' || empty($form_state['rebuild']) && !empty($form_state['storage'])) {
    webform_civicrm_fill_values($form['submitted'], array(), $fields, array());
    return;
  }

  // If this is an edit op, use the original IDs and return
  if (isset($form['#submission']->sid)) {
    if (isset($form['#submission']->civicrm)) {
      $form_state['storage']['civicrm']['id']['cid'] = $form['#submission']->civicrm['contact_id'];
      $form_state['storage']['civicrm']['id']['act'][1] = $form['#submission']->civicrm['activity_id'];
    }
    webform_civicrm_fill_values($form['submitted'], array(), $fields, array());
    return;
  }

  // If this form is already in-process, IDs will be stored
  if (!empty($form_state['storage'])) {
    $id = $form_state['storage']['civicrm']['id'];
  }
  else {
    $args = $_GET;
    if (isset($args['cid']) && empty($args['cid1'])) {
      $args['cid1'] = $args['cid'];
    }
    $count = count($data['contact']);
    for ($i = 1; $i <= $count; ++$i) {
      if (isset($args['cid' . $i]) && is_numeric($args['cid' . $i])) {
        $cid = (int) $args['cid' . $i];
        require_once 'CRM/Contact/BAO/Contact/Permission.php';
        if ($cid === 0 || CRM_Contact_BAO_Contact_Permission::validateChecksumContact($cid, CRM_Core_DAO::$_nullObject)) {
          $id['cid'][$i] = $cid;

          // Identify contact 1 as acting user if not already logged in
          if ($cid && $i == 1 && user_is_anonymous()) {
            CRM_Core_DAO::executeQuery('SET @civicrm_user_id = %1', array(
              1 => array(
                $cid,
                'Integer',
              ),
            ));
          }
        }
      }
    }
  }

  // If user is logged in, look up the CID
  if (!isset($id['cid'][1]) && $settings['contact_matching'] && $data['contact'][1]['contact'][1]['contact_type'] == 'individual' && ($cid = webform_civicrm_user_cid())) {
    $id['cid'][1] = $cid;
  }
  if (!empty($args['aid']) && !empty($id['cid']) && is_numeric($args['aid'])) {
    $result = webform_civicrm_api('activity', 'get', array(
      'activity_id' => $args['aid'],
      'return.target_contact_id' => 1,
      'return.assignee_contact_id' => 1,
    ));
    if (isset($result['values'][$args['aid']])) {
      $act = $result['values'][$args['aid']];
      $valid = FALSE;

      // Verify that this activity is the right type and that our contacts have some involvement in it
      if ($act['activity_type_id'] == $data['activity'][1]['activity'][1]['activity_type_id']) {
        foreach ($id['cid'] as $cid) {
          if ($act['source_contact_id'] == $cid || in_array($cid, $act['target_contact_id']) || in_array($cid, $act['assignee_contact_id'])) {
            $activity = array(
              'activity' => array(
                1 => $result['values'][$args['aid']],
              ),
            );
            $custom = webform_civicrm_get_custom($args['aid'], 'activity');
            $info['activity'] = array(
              1 => $activity + $custom,
            );
            $id['act'][1] = $args['aid'];
            break;
          }
        }
      }
    }
  }
  else {
    if (!empty($data['case'][1]['case'][1]['status_id']) && !empty($id['cid'][1])) {
      $result = webform_civicrm_api('case', 'get', array(
        'client_id' => $id['cid'][1],
      ));
      if (!empty($result['values'])) {
        foreach ($result['values'] as $case) {
          if ($case['status_id'] == $data['case'][1]['case'][1]['status_id'] && empty($case['is_deleted']) && $case['case_type_id'] == $data['case'][1]['case'][1]['case_type_id']) {
            $id['case'][1] = $case['id'];
            break;
          }
        }
      }
    }
    if (!empty($data['activity'][1]['existing_activity_status']) && !empty($id['cid'][1])) {
      $params = array(
        'contact_id' => $id['cid'][1],
        'activity_type_id' => $data['activity'][1]['activity'][1]['activity_type_id'],
        'status_id' => $data['activity'][1]['existing_activity_status'],
      );
      if (!empty($id['case'][1])) {
        $params['case_id'] = $id['case'][1];
      }
      if ($id['act'][1] = webform_civicrm_activity_find($params)) {
        $result = webform_civicrm_api('activity', 'get', array(
          'activity_id' => $id['act'][1],
        ));
        $activity = array(
          'activity' => array(
            1 => $result['values'][$id['act'][1]],
          ),
        );
        $custom = webform_civicrm_get_custom($id['act'][1], 'activity');
        $info['activity'] = array(
          1 => $activity + $custom,
        );
      }
    }
  }

  // Form alterations for unknown contacts
  if (empty($id['cid'][1])) {
    if ($settings['prefix_unknown']) {
      $form['#prefix'] = webform_civicrm_aval($form, '#prefix', '') . '<div class="webform-civicrm-prefix contact-unknown">' . nl2br($settings['prefix_unknown']) . '</div>';
    }
    if ($settings['block_unknown_users']) {
      $form['submitted']['#access'] = $form['actions']['#access'] = FALSE;
      drupal_set_message(t('Sorry, you do not have permission to access this form.'), 'warning', FALSE);
      return;
    }
  }
  $enabled = webform_civicrm_enabled_fields($node);

  // Check if events are open to registration and take appropriate action
  $events = array();
  $reg = webform_civicrm_aval($data, 'reg_options', array());
  if (!empty($data['participant_reg_type'])) {

    // Fetch events set in back-end
    $data += array(
      'participant' => array(),
    );
    foreach ($data['participant'] as $e => $par) {
      if (!empty($par['participant'])) {
        foreach ($par['participant'] as $n => $p) {
          if (!empty($p['event_id'])) {

            // Handle multi-valued event selection
            foreach ((array) $p['event_id'] as $eid) {
              if ($eid = (int) $eid) {
                $events[$eid]['ended'] = TRUE;
                $events[$eid]['title'] = t('this event');
                $events[$eid]['count'] = webform_civicrm_aval($events, "{$eid}:count", 0) + 1;
                $events[$eid]['form'][] = array(
                  'contact' => $e,
                  'num' => $n,
                  'eid' => NULL,
                );
              }
            }
          }
        }
      }
    }

    // Add events exposed to the form
    foreach ($enabled as $field => $fid) {
      if (strpos($field, 'participant_event_id')) {
        $options = webform_civicrm_str2array(webform_civicrm_aval($node->webform['components'][$fid], 'extra:items'));
        foreach ($options as $p => $label) {
          list($eid) = explode('-', $p);
          $events[$eid]['ended'] = TRUE;
          $events[$eid]['title'] = $label;
          list(, $e, , $n) = explode('_', $field);
          $events[$eid]['form'][] = array(
            'contact' => $e,
            'num' => $n,
            'eid' => $p,
          );
        }
      }
    }
    if ($events && (!empty($reg['show_remaining']) || !empty($reg['block_form']))) {
      webform_civicrm_event_info($events);
      foreach ($events as $eid => $event) {
        if ($event['ended']) {
          if (!empty($reg['show_remaining']) && empty($form_state[WEBFORM_CIVICRM_FAPI_INPUT]) && empty($form_state['storage'])) {
            drupal_set_message(t('Sorry, %event has ended.', array(
              '%event' => $event['title'],
            )), 'warning', FALSE);
          }
        }
        elseif ($event['full']) {
          if (!empty($reg['show_remaining']) && empty($form_state[WEBFORM_CIVICRM_FAPI_INPUT]) && empty($form_state['storage'])) {
            drupal_set_message('<em>' . $event['title'] . '</em>: ' . $event['full_message'], 'warning', FALSE);
          }
        }
        else {
          $reg['block_form'] = FALSE;
          if ($event['max_participants'] && empty($form_state[WEBFORM_CIVICRM_FAPI_INPUT]) && empty($form_state['storage']) && ($reg['show_remaining'] == 'always' || intval($reg['show_remaining']) >= $event['remaining'])) {
            drupal_set_message(format_plural($event['remaining'], '%event has 1 remaining space.', '%event has @count remaining spaces.', array(
              '%event' => $event['title'],
            )), 'status', FALSE);
          }
        }
      }
      if ($reg['block_form']) {
        $form['submitted']['#access'] = $form['actions']['#access'] = FALSE;
        return;
      }
    }
  }

  // Form alterations for known contacts
  $count = count($data['contact']);
  foreach ($data['contact'] as $c => $contact) {
    $info['contact'][$c] = array();
    $cid = 0;
    if (!empty($id['cid'][$c])) {
      $cid = $id['cid'][$c];
    }
    elseif ($contact['contact'][1]['contact_type'] == 'organization') {

      // Populate "current_employer" without setting it in $id
      // (this allows the user to change their current employer on the form)
      $employee = 0;
      for ($i = $c; $i <= $count; ++$i) {
        $con = $data['contact'][$i];
        if (!empty($con['relationship']) && ($con['contact'][1]['contact_type'] == 'individual' && !empty($id['cid'][$i]) || $i == $c)) {
          foreach ($con['relationship'] as $target => $rel) {
            if (webform_civicrm_aval($rel, 'relationship_type_id') == 'ce_b' && !empty($id['cid'][$target])) {
              $employee = $id['cid'][$target];
            }
            elseif (webform_civicrm_aval($rel, 'relationship_type_id') == 'ce_a' && $target == $c) {
              $employee = $id['cid'][$i];
            }
            if ($employee) {
              $result = webform_civicrm_api('contact', 'get', array(
                'contact_id' => $employee,
                'return.current_employer_id' => 1,
              ));
              if (!empty($result['values'][$employee]['current_employer_id'])) {
                $cid = $result['values'][$employee]['current_employer_id'];
                break;
              }
              else {
                $employee = 0;
              }
            }
          }
        }
      }
    }
    if (!$cid) {
      continue;
    }
    foreach (array(
      'contact',
      'address',
      'email',
      'phone',
      'website',
    ) as $field) {
      if (!empty($contact['number_of_' . $field]) || $field == 'contact') {
        $params = array(
          'contact_id' => $cid,
        );
        if ($field != 'contact') {
          $params['options'] = array(
            'sort' => 'is_primary DESC',
          );
        }
        $result = webform_civicrm_api($field, 'get', $params);
        if (!empty($result['values'])) {
          $result = array_merge(array(
            0,
          ), array_values($result['values']));
          unset($result[0]);
          if ($field == 'contact') {

            // Privacy fields
            foreach (array_keys(webform_civicrm_get_options('privacy')) as $key) {
              if (!empty($result[1][$key])) {
                $result[1]['privacy'][] = $key;
              }
            }
          }

          // Extra processing for addresses
          if ($field == 'address') {
            foreach ($result as &$address) {

              // Translate to abbr
              if (!empty($address['state_province_id'])) {
                $address['state_province_id'] = webform_civicrm_state_abbr($address['state_province_id']);
              }

              // Load custom data
              $custom = webform_civicrm_get_custom($address['id'], 'address');
              if (!empty($custom['address'])) {
                $address = $address + $custom['address'][1];
              }
            }
          }
          $info['contact'][$c][$field] = $result;
        }
      }
    }

    // Get custom contact data if needed
    foreach ($contact as $k => $v) {
      if (substr($k, 0, 12) == 'number_of_cg' && !empty($v)) {
        $custom = webform_civicrm_get_custom($cid);
        $info['contact'][$c] = $info['contact'][$c] + $custom;
        break;
      }
    }

    // Communication prefs are not fetched by default by the api
    if (isset($enabled['civicrm_' . $c . '_contact_1_contact_preferred_communication_method']) || isset($enabled['civicrm_' . $c . '_contact_1_contact_preferred_language'])) {
      $result = webform_civicrm_api('contact', 'get', array(
        'contact_id' => $cid,
        'return.preferred_communication_method' => 1,
        'return.preferred_language' => 1,
      ));
      $info['contact'][$c]['contact'][1] += $result['values'][$cid];
    }

    // Retrieve group and tag data
    $field = 'civicrm_' . $c . '_contact_1_other_';
    foreach (array(
      'tag' => 'entity_tag',
      'group' => 'group_contact',
    ) as $ent => $api) {
      if (isset($enabled['civicrm_' . $c . '_contact_1_other_' . $ent])) {

        // Add entity table param to workaround a bug in 4.1.0 api
        $result = webform_civicrm_api($api, 'get', array(
          'contact_id' => $cid,
          'entity_table' => 'civicrm_contact',
        ));
        foreach (webform_civicrm_aval($result, 'values') as $val) {
          $info['contact'][$c]['other'][1][$ent][] = $val[$ent . '_id'];
        }
      }
    }

    // Retrieve participant data
    if ($events && ($c == 1 || $data['participant_reg_type'] == 'separate')) {
      $select = array(
        'id',
        'event_id',
        'role_id',
        'status_id',
      );
      if (in_array('CiviCampaign', $config->enableComponents, TRUE)) {
        $select[] = 'campaign_id';
      }
      $dao =& CRM_Core_DAO::executeQuery('SELECT ' . implode(',', $select) . " FROM civicrm_participant WHERE contact_id = {$cid} AND event_id IN (" . implode(',', array_keys($events)) . ") AND status_id IN (SELECT id FROM civicrm_participant_status_type WHERE class <> 'Negative')");
      while ($dao
        ->fetch()) {
        $par = array();
        foreach ($select as $sel) {
          $par['participant'][1][$sel] = $dao->{$sel};
        }
        $par += webform_civicrm_get_custom($dao->id, 'Participant');
        foreach ($events[$dao->event_id]['form'] as $event) {
          if ($event['contact'] == $c) {
            $n = $event['contact'];
            $i = $event['num'];

            // Support multi-valued form elements
            $event_ids = webform_civicrm_aval($info, "participant:{$n}:participant:{$i}:event_id", array());
            if ($event['eid']) {
              $event_ids[] = $event['eid'];
            }
            foreach ($par as $k => $v) {
              $info['participant'][$n][$k][$i] = $v[1];
            }
            $info['participant'][$n]['participant'][$i]['event_id'] = $event_ids;
          }
        }
      }
    }
  }
  if (!empty($id['cid'][1])) {
    if ($settings['prefix_known']) {
      $form['#prefix'] = webform_civicrm_aval($form, '#prefix', '') . '<div class="webform-civicrm-prefix contact-known">' . nl2br(webform_civicrm_replace_tokens($settings['prefix_known'], $info['contact'][1]['contact'][1])) . '</div>';
    }
    if ($settings['message'] && empty($form_state[WEBFORM_CIVICRM_FAPI_INPUT]) && empty($form_state['storage'])) {
      webform_civicrm_set_message($settings['message'], $info['contact'][1]['contact'][1]);
    }
  }

  // Store ids
  $form_state['storage']['civicrm']['id'] = $id;

  // Set default values and other attributes for CiviCRM form elements
  // Passing $submitted helps avoid overwriting values that have been entered on a multi-step form
  $submitted = webform_civicrm_aval($form_state, 'values:submitted', array());
  webform_civicrm_fill_values($form['submitted'], $info, $fields, $submitted);
}