You are here

fb_registration.module in Drupal for Facebook 7.3

Same filename and directory in other branches
  1. 6.3 contrib/fb_registration.module

File

contrib/fb_registration.module
View source
<?php

/**
 * @file
 *
 * http://developers.facebook.com/docs/user_registration
 */
function _fb_registration_form_alter_fields(&$form) {

  // name, email and password require special treatment.
  if (isset($form['name'])) {
    $form['name']['#fb_registration_field'] = 'name';
  }
  if (isset($form['mail'])) {
    $form['mail']['#fb_registration_field'] = 'email';
  }

  /* user_login form needs this
       $form['pass']['#fb_registration_field'] = array(
       'name' => 'password',
       'view' => 'not_prefilled',
       );
    */
  if (isset($form['captcha'])) {
    $form['captcha']['#fb_registration_field'] = 'captcha';
  }

  // Because profile module may or may not nest fields in fieldsets, we must recurse.
  foreach (element_children($form) as $key) {
    _fb_registration_form_alter_fields($form[$key]);
  }
}

/**
 * Implements hook_form_alter().
 */
function fb_registration_form_alter(&$form, &$form_state, $form_id) {
  if (!isset($GLOBALS['_fb'])) {

    // Facebook app not configured.  Nothing to do.
    return;
  }
  if ($GLOBALS['user']->uid) {

    // No need to alter user add form.
    return;
  }
  if ($form_id == 'user_register_form') {

    // Replace regular form with fb_registration.
    $form['#fb_registration'] = TRUE;

    // Some fields of the registration form require special treatment.
    _fb_registration_form_alter_fields($form);
  }
  if (isset($form['#fb_registration'])) {

    // Registration has been enabled for this form.
    $sr = $GLOBALS['_fb']
      ->getSignedRequest();
    if ($sr && !empty($sr['registration'])) {
      $registration = $sr['registration'];

      // The form has been submitted.  We don't need to alter it.  Instead we
      // must submit the original form.
      // Captcha is a special case, we can't require it during drupal_execute.
      $form['captcha'] = NULL;
      if (!isset($form_state['fb_registration_avoid_recursion'])) {
        $state = array(
          'fb_registration_avoid_recursion' => TRUE,
          'values' => $registration,
          'fb_regisration_values' => $registration,
        );

        // Drupal expects strings for some values, not the arrays sent by facebook.
        foreach ($registration as $key => $value) {
          if (is_array($value) && $value['name']) {
            $state['values'][$key] = $value['name'];

            // Simply for drupal form api.
          }
          elseif ($key == 'email' && is_string($value)) {

            // Drupal expects 'mail', not 'email'.
            if (!isset($state['values']['mail'])) {
              $state['values']['mail'] = $value;
            }
          }
        }
        drupal_execute($form_id, $state);

        // If successful, user will be redirected to another page.
      }
      return;
    }
    $fb_fields = array();
    _fb_registration_extract_fb_fields($fb_fields, $form);
    $redirect_url = url(request_path(), array(
      'absolute' => TRUE,
    ));
    $fields = json_encode($fb_fields);
    if (FALSE) {

      // Use <fb:registration> XFBML.
      // In testing, I could never get this to work._
      $attrs = "fields='" . json_encode($fb_fields) . "' redirect-uri='" . $redirect_url . "'";
      $form['fb_registration'] = array(
        '#type' => 'markup',
        '#value' => '<fb:registration ' . $attrs . '></fb:registration>',
      );
    }
    else {

      // Use the iframe markup.
      $id = $GLOBALS['_fb_app']->id;
      $url = urlencode($redirect_url);
      $fields = urlencode($fields);
      $markup = "<iframe src=http://www.facebook.com/plugins/registration.php?client_id={$id}&redirect_uri={$url}&fields={$fields}\n        scrolling=\"auto\"\n        frameborder=\"no\"\n        style=\"border:none;\"\n        allowTransparency=\"true\"\n        width=\"100%\"\n        height=\"360px\">\n</iframe>";
      $form['fb_registration'] = array(
        '#type' => 'markup',
        '#value' => $markup,
      );
    }
  }
}
function _fb_registration_extract_fb_fields(&$fb_fields, &$form) {
  foreach (element_children($form) as $key) {
    $field = NULL;
    if (isset($form[$key]['#fb_registration_field'])) {
      if (is_string($form[$key]['#fb_registration_field'])) {

        // This field is a "built in field".
        $field = array(
          'name' => $form[$key]['#fb_registration_field'],
        );
      }
      elseif (is_array($form[$key]['#fb_registration_field'])) {
        $field = $form[$key]['#fb_registration_field'];
      }
    }
    else {

      // #fb_registration_field not specified, fallback to the following
      // code, which translates some drupal form elements into facebook
      // fields.
      if (!isset($form[$key]['#type'])) {
        _fb_registration_extract_fb_fields($fb_fields, $form[$key]);
      }
      elseif ($form[$key]['#type'] == 'fieldset') {
        _fb_registration_extract_fb_fields($fb_fields, $form[$key]);
        $form[$key] = NULL;

        // So the (now empty?) fieldset will not be rendered.
      }
      elseif ($form[$key]['#type'] == 'submit') {

        // We have to use the register button provided by facebook.
        $form[$key] = NULL;
      }
      elseif ($form[$key]['#type'] == 'textfield') {
        $field = array(
          'name' => $key,
          'type' => 'text',
          'description' => $form[$key]['#title'],
        );
      }
      elseif ($form[$key]['#type'] == 'textarea') {

        // Facebook does not offer multi-line text area.  Use single line instead.
        $field = array(
          'name' => $key,
          'type' => 'text',
          'description' => $form[$key]['#title'],
        );
      }
      elseif ($form[$key]['#type'] == 'checkbox') {
        $field = array(
          'name' => $key,
          'type' => 'checkbox',
          'description' => $form[$key]['#title'],
          'default' => isset($form[$key]['#default_value']) ? $form[$key]['#default_value'] : NULL,
        );
      }
      elseif ($form[$key]['#type'] == 'select') {
        $field = array(
          'name' => $key,
          'type' => 'select',
          'description' => $form[$key]['#title'],
          'options' => $form[$key]['#options'],
          'default' => $form[$key]['#default_value'],
        );
      }

      // @TODO do something intelligent with unknown element types.
    }
    if (count($field)) {

      // Use the facebook field...
      $fb_fields[] = $field;

      // and not the drupal field.
      $form[$key] = NULL;
    }
  }
}