You are here

fb_friend.module in Drupal for Facebook 6.2

Same filename and directory in other branches
  1. 6.3 contrib/fb_friend.module
  2. 7.3 contrib/fb_friend.module

This module implements several features specific to Facebook friend networks.

Blocks include

  • Invite friends to install the application.
  • Invite friends to visit the page currently being browsed.
  • Show which friends are already users of the current application.

The invite blocks work by building a structure, similar to a drupal form array, which reflects the (X)FBML markup which will be used. Then drupal_alter is called, allowing third-party modules to customize the markup. Implementing those alter hooks is the best way to change any aspects of the invite form.

File

contrib/fb_friend.module
View source
<?php

/**
 * @file
 * This module implements several features specific to Facebook friend networks.
 *
 * Blocks include 
 * - Invite friends to install the application.
 * - Invite friends to visit the page currently being browsed.
 * - Show which friends are already users of the current application.
 *
 * The invite blocks work by building a structure, similar to a drupal
 * form array, which reflects the (X)FBML markup which will be used.
 * Then drupal_alter is called, allowing third-party modules to
 * customize the markup.  Implementing those alter hooks is
 * the best way to change any aspects of the invite form.
 */
define('FB_FRIEND_DELTA_AUTHORIZED', 'fb_friend_authorized');
define('FB_FRIEND_DELTA_INVITE_PAGE', 'fb_friend_invite_page');
define('FB_FRIEND_DELTA_INVITE_APP', 'fb_friend_invite_app');
define('FB_FRIEND_PATH_AJAX_REQUEST_FORM', 'fb_friend/ajax/request-form');

/**
 * Implementation of hook_block().
 */
function fb_friend_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {
    $items = array();

    // Blocks which use the current application.
    $items[FB_FRIEND_DELTA_INVITE_PAGE] = array(
      'info' => t('Invite Facebook friends to current page'),
    );
    $items[FB_FRIEND_DELTA_INVITE_APP] = array(
      'info' => t('Invite Facebook friends to install the current app'),
    );
    $items[FB_FRIEND_DELTA_AUTHORIZED] = array(
      'info' => t('Facebook friends who have authorized the current app'),
    );
    return $items;
  }
  elseif ($op == 'view') {
    try {

      // Calls to facebook can fail.
      // None of our blocks are shown if user is not logged in.
      $fbu = fb_facebook_user();
      if (!$fbu) {
        return;
      }

      // Our blocks use current application
      global $_fb, $_fb_app;
      if ($delta == FB_FRIEND_DELTA_INVITE_PAGE) {
        if ($xfbml = fb_friend_invite_page_fbml('fb_friend_invite_page')) {
          $content = drupal_render($xfbml);
          return array(
            'subject' => t('Invite friends to visit this page'),
            'content' => $content,
          );
        }
      }
      elseif ($delta == FB_FRIEND_DELTA_INVITE_APP) {

        // TODO: support canvas pages, in addition to connect pages.
        fb_connect_require_feature('XFBML');
        $app_url = url('<front>', array(
          'absolute' => TRUE,
        ));
        $page_url = url($_GET['q'], array(
          'absolute' => TRUE,
        ));
        $site_name = variable_get('site_name', t('application'));

        // Build the alterable data structure.
        // http://wiki.developers.facebook.com/index.php/Fb:request-form
        $fbml = fb_form_requestform(array(
          'type' => $site_name,
          'content' => array(
            'markup' => array(
              '#value' => t('You may like this site - <a href="!url">!site</a>.', array(
                '!url' => $app_url,
                '!site' => $site_name,
              )),
            ),
            'choice' => array(
              '#type' => 'fb_form_req_choice',
              '#attributes' => array(
                'url' => $app_url,
                'label' => t('Accept'),
              ),
            ),
          ),
          'invite' => TRUE,
          'action' => $page_url,
          'method' => 'POST',
        ));

        // Exclude users who have already installed.
        $rs = $_fb->api_client
          ->fql_query("SELECT uid FROM user WHERE has_added_app=1 and uid IN (SELECT uid2 FROM friend WHERE uid1 = {$fbu})");

        // FQL not SQL, no {curly_brackets}
        $arFriends = '';
        $exclude_ids = '';

        //  Build an delimited list of users...
        if ($rs) {
          $exclude_ids .= $rs[0]["uid"];
          for ($i = 1; $i < count($rs); $i++) {
            if ($exclude_ids != "") {
              $exclude_ids .= ",";
            }
            $exclude_ids .= $rs[$i]["uid"];
          }
        }
        $fbml['selector'] = fb_form_multi_selector(array(
          'actiontext' => t('Invite friends'),
          'exclude_ids' => $exclude_ids,
        ));

        // Allow third-party to modify the form
        drupal_alter('fb_friend_invite_app', $fbml);
        if ($fbml) {
          if (fb_is_fbml_canvas()) {
            $xfbml = array(
              'fbml' => $fbml,
            );
          }
          else {

            // Wrap in serverfbml for connect pages.
            $xfbml = array(
              '#type' => 'fb_form_serverfbml',
              'fbml' => $fbml,
            );
          }

          // Allow third-party to modify wrapper
          drupal_alter('fb_friend_invite_app_wrap', $xfbml);
          $content = drupal_render($xfbml);
          return array(
            'subject' => t('Invite friends to use !site', array(
              '!site' => $site_name,
            )),
            'content' => $content,
          );
        }
      }
      elseif ($delta == FB_FRIEND_DELTA_AUTHORIZED) {

        // TODO: handle both connect and canvas pages!
        fb_connect_require_feature('XFBML');
        if ($fbu = fb_facebook_user()) {

          // Get list of friends who have authorized this app.
          $rs = $_fb->api_client
            ->fql_query("SELECT uid FROM user WHERE has_added_app=1 AND uid IN (SELECT uid2 FROM friend WHERE uid1 = {$fbu})");

          // FQL not SQL, no {curly_brackets}
          if (isset($rs) && is_array($rs)) {
            foreach ($rs as $friend_data) {
              $friend_fbu = $friend_data['uid'];

              // TODO: make size and markup configurable
              $content .= "<fb:profile-pic uid={$friend_fbu} size=square></fb:profile-pic>";
            }
          }
          $subject = t('Friends who use !app', array(
            '!app' => $GLOBALS['_fb_app']->label,
          ));

          // TODO - fix title
          return array(
            'subject' => $subject,
            'content' => $content,
          );
        }
      }
    } catch (Exception $e) {

      // We reach this when Facebook Connect sessions are no longer valid.
      // Javascript should detect this and refresh.  Relatively harmless.
      if (fb_verbose() === 'extreme') {
        fb_log_exception($e, t('Failed to render fb_friend block.'));
      }
    }
  }
}
function fb_friend_invite_page_fbml($alter_hook = NULL) {
  $page_url = url($_GET['q'], array(
    'absolute' => TRUE,
  ));

  // Build the alterable data structure.
  // http://wiki.developers.facebook.com/index.php/Fb:request-form
  $fbml = fb_form_requestform(array(
    'type' => variable_get('site_name', t('page view')),
    //'style' => "width: 500px;",
    'content' => array(
      'markup' => array(
        '#value' => t('You may want to see this. <a href="!url">!title</a>', array(
          '!url' => $page_url,
          '!title' => drupal_get_title(),
        )),
      ),
      'choice' => array(
        '#type' => 'fb_form_req_choice',
        '#attributes' => array(
          'url' => $page_url,
          'label' => t('Accept'),
        ),
      ),
    ),
    'invite' => TRUE,
    'action' => $page_url,
    'method' => 'POST',
  ));
  $fbml['selector'] = fb_form_multi_selector(array(
    'actiontext' => t('Invite friends'),
  ));

  // Allow third-party to modify the form
  if (isset($alter_hook)) {
    drupal_alter($alter_hook, $fbml);
  }
  if ($fbml) {
    if (fb_is_fbml_canvas()) {
      $xfbml = array(
        'fbml' => $fbml,
      );
    }
    else {

      // Render in Facebook Connect page.
      fb_connect_require_feature('XFBML');

      // Wrap in serverfbml for connect pages.
      $xfbml = array(
        '#type' => 'fb_form_serverfbml',
        'fbml' => $fbml,
      );
    }

    // Allow third-party to modify wrapper
    if (isset($alter_hook)) {
      drupal_alter($alter_hook . '_wrap', $xfbml);
    }
    return $xfbml;
  }
}

Functions

Namesort descending Description
fb_friend_block Implementation of hook_block().
fb_friend_invite_page_fbml

Constants

Namesort descending Description
FB_FRIEND_DELTA_AUTHORIZED @file This module implements several features specific to Facebook friend networks.
FB_FRIEND_DELTA_INVITE_APP
FB_FRIEND_DELTA_INVITE_PAGE
FB_FRIEND_PATH_AJAX_REQUEST_FORM