You are here

fb_social.module in Facebook social plugins integration 6.2

Same filename and directory in other branches
  1. 6 fb_social.module
  2. 7.2 fb_social.module

File

fb_social.module
View source
<?php

// Minimum CTools version needed.
define('FB_SOCIAL_REQUIRED_CTOOLS_API', '1.7.1');

// facebook developers site
define('FB_REF_BASE_URL', 'http://developers.facebook.com/docs/reference/plugins/');

// Drupal hooks

/**
 * Implementation of hook_menu
 */
function fb_social_menu() {
  $items = array();
  $items['fb_social/channel'] = array(
    'type' => MENU_CALLBACK,
    'description' => 'Facebook Custom Channel URL',
    'page callback' => 'fb_social_custom_channel_url',
    'access callback' => TRUE,
  );
  $items['admin/build/fbsocial'] = array(
    'type' => MENU_NORMAL_ITEM,
    'title' => 'Facebook social',
    'description' => 'Settings for facebook social plugins.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'fb_social_admin_settings_form',
    ),
    'file' => 'fb_social.admin.inc',
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer site configuration',
    ),
  );
  $items['admin/build/fbsocial/settings'] = array(
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'title' => 'Settings',
    'description' => 'Settings for facebook social plugins.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'fb_social_admin_settings_form',
    ),
    'file' => 'fb_social.admin.inc',
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer site configuration',
    ),
  );
  return $items;
}

/**
 * Implementation of hook_block
 */
function fb_social_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {
    $blocks = array();
    if ($presets = fb_social_get_presets()) {
      foreach ($presets as $preset) {
        if ($preset->settings['block']) {
          $blocks[$preset->name] = array(
            'info' => $preset->name . ' block',
            'cache' => DRUPAL_NO_CACHE,
          );
        }
      }
    }
    return $blocks;
  }
  elseif ($op == 'view') {
    if ($preset = fb_social_get_presets($name = $delta)) {
      $block['subject'] = t('');
      $block['content'] = fb_social_preset_view($preset);
      return $block;
    }
  }
}

/**
 * Implementation of hook_theme
 */
function fb_social_theme() {
  $path = drupal_get_path('module', 'fb_social');
  return array(
    'fb_social_plugin' => array(
      'template' => 'fb-social-plugin',
      'path' => "{$path}/theme",
      'arguments' => array(
        'plugin_type' => NULL,
        'options' => NULL,
      ),
    ),
  );
}

/**
 * Implements hook preprocess_hook
 * @param $variables
 */
function fb_social_preprocess_fb_social_plugin(&$variables) {
  global $_fb_script_init;
  $_fb_script_init = TRUE;
  $plugin = fb_social_fb_plugin_load($variables['plugin_type']);

  // delegate to plugin's preprocess function
  $function = ctools_plugin_get_function($plugin, 'hook_preprocess_fb_social_plugin');
  if ($function) {
    $function($variables);
  }

  // are we rendering html5 or xfbml
  $markup_type = variable_get('fb_social_markup_type', 'xfbml');
  $variables['tag_name'] = $markup_type == "xfbml" ? "fb:" . $plugin['html tag name'] : "div";
  if ($markup_type == 'html5') {
    foreach ($variables['options'] as $key => $value) {
      $variables['options']["data-" . $key] = $value;
      unset($variables['options'][$key]);
    }
    $variables['options'] = array(
      'class' => "fb-" . $plugin['html tag name'],
    ) + $variables['options'];
  }
}

/**
 * Implements of hook_nodeapi().
 */
function fb_social_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  switch ($op) {
    case 'view':
      if ($presets = fb_social_get_presets()) {
        foreach ($presets as $preset) {
          $plugin = fb_social_fb_plugin_load($preset->plugin_type);
          $function = ctools_plugin_get_function($plugin, 'hook_nodeapi_view');
          if ($function) {
            $function($preset, $node, $op, $a3, $a4);
          }
        }
      }
      break;
  }
}

/**
 * Implementation of hook_content_extra_fields.
 */
function fb_social_content_extra_fields($type_name) {
  $extras = array();
  if ($presets = fb_social_get_presets()) {
    foreach ($presets as $preset) {
      $plugin = fb_social_fb_plugin_load($preset->plugin_type);
      $function = ctools_plugin_get_function($plugin, 'hook_content_extra_fields');
      if ($function) {
        $extras = $function($preset, $type_name);
      }
    }
  }
  return $extras;
}

/**
 *Implementation of hook_link
 */
function fb_social_link($type, $object, $teaser = FALSE) {
  $links = array();
  if ($presets = fb_social_get_presets()) {
    foreach ($presets as $preset) {
      $plugin = fb_social_fb_plugin_load($preset->plugin_type);
      $function = ctools_plugin_get_function($plugin, 'hook_link');
      if ($function) {
        $links += $function($preset, $type, $object, $teaser);
      }
    }
  }
  return $links;
}

/**
 * Implementation of hook init
 */
function fb_social_init() {

  // Add simple OpenGraph metatags
  $data = "";
  if (variable_get('fb_social_opengraph', 1)) {
    $content = drupal_set_title();
    $content = $content ? strip_tags($content) : variable_get('site_name', 'Drupal');

    //add fbml header meta information
    $data = '<meta property="og:title" content="' . $content . '"/>' . "\n";
    $data .= '<meta property="og:site_name" content="' . variable_get('site_name', '') . '"/>' . "\n";

    // @todo maybe look for images/imagefields uploaded/attached to the node ?
    // $data .= '<meta property="og:image" content="http://ia.media-imdb.com/rock.jpg"/>';
  }

  /**
   * from facebook ..
   * If your site has many comments boxes, we strongly recommend you specify a Facebook app id
   * as the administrator (all administrators of the app will be able to moderate comments).
   * Doing this enables a moderator interface on Facebook where comments from all plugins
   * administered by your app id can be easily moderated together.
   */
  $data .= '<meta property="fb:app_id" content="' . check_plain(variable_get('fb_social_appid', '')) . '"/>' . "\n";
  drupal_set_html_head($data);
}

// ctools hooks / api

/**
 * Implementation of hook_ctools_plugin_api().
 */
function fb_social_ctools_plugin_api($module, $api) {
  if ($module == 'fb_social' && $api == 'fb_plugin') {
    return array(
      'version' => 1,
    );
  }

  //boxes
  if ($module == 'boxes' && $api == 'plugins') {
    return array(
      'version' => 1,
    );
  }
}

/**
 * Implementation of hook_ctools_plugin_directory().
 */
function fb_social_ctools_plugin_directory($module, $type) {

  // Safety: go away if CTools is not at an appropriate version.
  if (!module_invoke('ctools', 'api_version', FB_SOCIAL_REQUIRED_CTOOLS_API)) {
    return;
  }
  if ($module == 'fb_social' && $type == 'fb_plugin') {
    return 'plugins/fb_plugin';
  }
  elseif ($type == 'export_ui') {
    return 'plugins/export_ui';
  }
}

/**
 * Implementation of hook_ctools_plugin_TYPE 
 * (type = 'fb_plugin')
 * This is to tell ctools that by default each 
 * plugin has some default functions named consistently 
 * after the plugin name
 * @see _fb_social_ctools_plugin_fb_plugin_process()
 */
function fb_social_ctools_plugin_fb_plugin() {
  return array(
    // we need some default functions
    'process' => '_fb_social_ctools_plugin_fb_plugin_process',
  );
}

/**
 * Helper function for ctools plugin 'process' 
 * @param $plugin
 * @param $info
 * @see fb_social_ctools_plugin_fb_plugin()
 */
function _fb_social_ctools_plugin_fb_plugin_process(&$plugin, $info) {
  $plugin['default values'] = $plugin['name'] . '_defaults';
  $plugin['fb plugin form'] = $plugin['name'] . '_fb_settings';
  $plugin['drupal settings form'] = $plugin['name'] . '_drupal_settings';
}

// ctools wrapper functions for 'fb_plugin"

/**
 * load a specific fb_plugin or all of them
 */
function fb_social_fb_plugin_load($type = NULL) {
  ctools_include('plugins');
  $plugins = ctools_get_plugins('fb_social', 'fb_plugin');
  if (isset($type)) {
    return $plugins[$type];
  }
  return $plugins;
}

/**
 * Return the default vaules of a certain plugin 
 * type as defined by facebook
 * @param $type the plugin type/name (i.e. like).
 */
function fb_social_fb_plugin_defaults($type) {
  $plugin = fb_social_fb_plugin_load($type);
  $function = ctools_plugin_get_function($plugin, 'default values');
  if ($function) {
    return $function();
  }
  return array();
}

/**
 * Return the facebook plugin form for a given type
 * @param $type the plugin type/name (i.e. like).
 */
function fb_social_fb_plugin_fb_settings_form($type, $options) {
  $form = array();
  $plugin = fb_social_fb_plugin_load($type);
  $url = FB_REF_BASE_URL . $plugin['html tag name'];
  $l = l("facebook documentation page", $url, array(
    'attributes' => array(
      'target' => '_blank',
    ),
  ));
  $desc = t("For more information about this plugin and its attributes please check out the !facebookdoc", array(
    '!facebookdoc' => $l,
  ));
  $form['help'] = array(
    '#value' => "<div>" . $desc . "</div>",
  );
  $function = ctools_plugin_get_function($plugin, 'fb plugin form');
  if ($function) {
    $form += $function($options);
  }
  return $form;
}

/**
 * Return the drupal settings form for a given plugin type
 * @param $type the plugin type/name (i.e. like).
 */
function fb_social_fb_plugin_drupal_settings_form($type, $options) {
  $form = array();
  $plugin = fb_social_fb_plugin_load($type);
  $function = ctools_plugin_get_function($plugin, 'drupal settings form');
  if ($function) {
    $form = $function($options);
  }
  return $form;
}

// ctools wrapper functions for "fb social preset"

/**
 * load the preset
 * @param $name
 *    the preset name
 * @param $reset
 */
function fb_social_preset_load($name = NULL, $reset = FALSE) {
  ctools_include('export');
  if ($reset) {
    ctools_export_load_object_reset('fb_social_preset');
  }
  $presets = ctools_export_load_object('fb_social_preset', 'all');
  if (isset($name)) {
    return isset($presets[$name]) ? $presets[$name] : FALSE;
  }
  return $presets;
}

/**
 * Get all presets or a preset by name. By default
 * it returns only enabled presets.
 * 
 * @param $name
 *    the preset name
 * @param $enabled
 *    
 * @param $reset
 */
function fb_social_get_presets($name = NULL, $enabled = TRUE, $reset = FALSE) {
  $presets = fb_social_preset_load($name, $reset);
  if (empty($presets)) {
    return FALSE;
  }
  if (is_object($presets)) {
    $presets = array(
      $presets->name => $presets,
    );
  }
  if ($enabled) {
    $presets = array_filter($presets, '_fb_social_enabled_presets_filter');
  }
  if (isset($name)) {
    return isset($presets[$name]) ? $presets[$name] : FALSE;
  }
  return $presets;
}

/**
 * filter presets based on come conditions $args
 * @see ctools_export_load_object()
 */
function _fb_social_enabled_presets_filter($preset) {
  return isset($preset->disabled) && $preset->disabled ? FALSE : TRUE;
}
function fb_social_get_presets_by_type($type, $en = TRUE) {
  $result = array();
  $presets = fb_social_get_presets($name = NULL, $enabled = $en);
  if (!empty($presets)) {
    foreach ($presets as $preset) {
      if ($preset->plugin_type == $type) {
        $result[] = $preset;
      }
    }
  }
  return $result;
}

// boxes integration

/**
 * Implementation of hook_boxes_plugins().
 */
function fb_social_boxes_plugins() {
  $info = array();
  $path = drupal_get_path('module', 'fb_social') . '/plugins/boxes';
  $info['fb_social_default'] = array(
    'handler' => array(
      'class' => 'fb_social_default',
      'file' => 'fb_social_default.inc',
      'path' => $path,
      'parent' => 'box',
    ),
  );
  $info['fb_social_like'] = array(
    'title' => 'facebook like',
    'handler' => array(
      'class' => 'fb_social_like',
      'file' => 'fb_social_like.inc',
      'path' => $path,
      'parent' => 'fb_social_default',
    ),
  );
  $info['fb_social_likebox'] = array(
    'title' => 'facebook likebox',
    'handler' => array(
      'class' => 'fb_social_likebox',
      'file' => 'fb_social_likebox.inc',
      'path' => $path,
      'parent' => 'fb_social_default',
    ),
  );
  $info['fb_social_send'] = array(
    'title' => 'facebook send',
    'handler' => array(
      'class' => 'fb_social_send',
      'file' => 'fb_social_send.inc',
      'path' => $path,
      'parent' => 'fb_social_default',
    ),
  );
  $info['fb_social_facepile'] = array(
    'title' => 'facebook facepile',
    'handler' => array(
      'class' => 'fb_social_facepile',
      'file' => 'fb_social_facepile.inc',
      'path' => $path,
      'parent' => 'fb_social_default',
    ),
  );
  $info['fb_social_livestream'] = array(
    'title' => 'facebook livestream',
    'handler' => array(
      'class' => 'fb_social_livestream',
      'file' => 'fb_social_livestream.inc',
      'path' => $path,
      'parent' => 'fb_social_default',
    ),
  );
  $info['fb_social_comments'] = array(
    'title' => 'facebook comments',
    'handler' => array(
      'class' => 'fb_social_comments',
      'file' => 'fb_social_comments.inc',
      'path' => $path,
      'parent' => 'fb_social_default',
    ),
  );

  // Truncate the name of the plugin because the delta column in the blocks
  // table is limited to 32 characters.
  $info['fb_social_recommend'] = array(
    'title' => 'facebook recommendations',
    'handler' => array(
      'class' => 'fb_social_recommendations',
      'file' => 'fb_social_recommendations.inc',
      'path' => $path,
      'parent' => 'fb_social_default',
    ),
  );
  $info['fb_social_activityf'] = array(
    'title' => 'facebook activity',
    'handler' => array(
      'class' => 'fb_social_activityfeed',
      'file' => 'fb_social_activityfeed.inc',
      'path' => $path,
      'parent' => 'fb_social_default',
    ),
  );
  return $info;
}

/**
 * returns the fbml content of the plugin
 */
function fb_social_preset_view($preset) {
  $plugin_type = $preset->plugin_type;
  $options = $preset->fb_attrs;
  $output = theme('fb_social_plugin', $plugin_type, $options);

  // if this is a "comment" plugin, get comments from facebook and print them
  // behind the iframe
  if ($plugin_type == 'comments' && isset($preset->settings['plugin_comments_seo']) && $preset->settings['plugin_comments_seo']['seo']) {
    $cache_length = $preset->settings['plugin_comments_seo']['cache_length'];
    $nr_comments = $preset->settings['plugin_comments_seo']['nr_comments'];
    $url = empty($options['href']) ? fb_social_url($_GET['q']) : $options['href'];
    module_load_include('inc', 'fb_social', 'plugins/fb_plugin/comments');
    $output .= _fb_social_comments_seo($url, $nr_comments, $cache_length);
  }
  return $output;
}

/**
 * returns the fbml content of the plugin
 */
function fb_social_box_view($box) {
  $plugin_type = $box->fb_plugin_name;
  $options = $box->options;
  $output = theme('fb_social_plugin', $plugin_type, $options);
  if ($plugin_type == 'comments') {
    $cache_length = 720;
    $nr_comments = 100;
    $url = empty($options['href']) ? fb_social_url($_GET['q']) : $options['href'];
    module_load_include('inc', 'fb_social', 'plugins/fb_plugin/comments');
    $output .= _fb_social_comments_seo($url, $nr_comments, $cache_length);
  }
  return $output;
}

/**
 * Implementation of hook_footer
 */
function fb_social_footer($main = 0) {
  global $language, $_fb_script_init, $base_url;

  //If their is no fb plugin enabled on this page, do not load fb script then
  if (!$_fb_script_init) {
    return;
  }
  $languages = _map_active_languages();
  if (fb_social_auto_language()) {
    if (array_key_exists($language->language, $languages)) {
      $fb_locale = $languages[$language->language];
    }
    else {
      drupal_set_message("There is no mapping for the current language. Using the default locale.");
    }
  }
  else {
    $fb_locale = variable_get('fb_social_locale', 'en_US');
  }
  $appid = variable_get('fb_social_appid', '');
  $channel_url = $base_url . "/fb_social/channel";
  $output = '<div id="fb-root"></div>';
  $output .= "<script type=\"text/javascript\">\n     window.fbAsyncInit = function() {\n       FB.init({\n         appId: " . drupal_to_js($appid) . ",\n         status: true, \n         cookie: true,\n         xfbml: true,\n         oauth : true,\n         channelUrl: " . drupal_to_js($channel_url) . "\n       });\n       \n       ";

  // let each module subscribe to different events
  $output .= implode("\n", module_invoke_all('fb_social_event_subscribe'));
  $output .= "\n       \n         \n     };\n     (function() {\n       var e = document.createElement('script'); \n       e.async = true;\n       e.src = document.location.protocol + '//connect.facebook.net/" . $fb_locale . "/all.js';\n       document.getElementById('fb-root').appendChild(e);\n     }());\n  </script>";
  return $output;
}
function fb_social_auto_language() {
  return variable_get('fb_social_locale_auto', 0);
}
function _map_active_languages() {
  $languages = language_list();
  $mapped = array();
  foreach ($languages as $key => $language) {
    $mapped[$language->language] = variable_get('fb_social_language_' . $language->language, '');
  }
  return $mapped;
}

/**
 * The Custom Channel URL that FB.init has as an option
 */
function fb_social_custom_channel_url() {
  header("Cache-Control: public, s-maxage=31536000, max-age=31536000");
  header("Expires: Sun, 1 Oct 2079 00:00:00 GMT");
  global $language;
  $languages = _map_active_languages();
  $fb_locale = "en_US";
  if (fb_social_auto_language()) {
    if (array_key_exists($language->language, $languages)) {
      $fb_locale = $languages[$language->language];
    }
  }
  else {
    $fb_locale = variable_get('fb_social_locale', 'en_US');
  }
  print '<script src="http://connect.facebook.net/' . $fb_locale . '/all.js"></script>';
  exit;
}

// API functions / module hooks

/**
 * Implementation of hook_fb_social_event_subscribe
 */
function fb_social_like_fb_social_event_subscribe() {

  // integration with google analytics
  if (module_exists('googleanalytics')) {
    global $user;
    $id = variable_get('googleanalytics_account', '');
    if (!empty($id) && _googleanalytics_visibility_pages() && _googleanalytics_visibility_user($user)) {
      return array(
        'FB.Event.subscribe("edge.create", function(href, widget) {',
        '_gaq.push(["_trackEvent", "Facebook like", "Drupal", href]);',
        '});',
      );
    }
  }
}

/**
 *  Based on the user settings return the aliased / unaliased version
 *  of a given $url
 *
 *  If option is selected, the base URL is rewritten to the specified value.
 *  If option is selected, the language tag is stripped from the URL.
 */
function fb_social_url($url = NULL) {
  $aliased = variable_get('fb_social_urls_mode', 0);
  $base_url = variable_get('fb_social_base_url', '');
  $strip_lang = variable_get('fb_social_url_strip_lang', 0);
  $url = url($url, array_filter(array(
    'absolute' => TRUE,
    'alias' => $aliased,
    'base_url' => $base_url,
  )));
  if ($strip_lang) {

    // i.e.  'http://www.mysite.nl/nl/node/xx' becomes 'http://www.mysite.nl/node/xx'
    global $language;
    $lang_tag = "/\\/" . $language->language . "/";
    $url = preg_replace($lang_tag, '', $url, 1);
  }
  return $url;
}

// helper functions

/**
 * Does $preset should be shown on node of type $type
 */
function fb_social_preset_node_types($preset, $node_type) {
  $types = $preset->settings['node_types']['types'];
  if (!is_array($types)) {
    return FALSE;
  }
  return !empty($types[$node_type]);
}

/**
 * Implements hook_views_api().
 */
function fb_social_views_api() {
  return array(
    'api' => 2,
  );
}

Functions

Namesort descending Description
fb_social_auto_language
fb_social_block Implementation of hook_block
fb_social_boxes_plugins Implementation of hook_boxes_plugins().
fb_social_box_view returns the fbml content of the plugin
fb_social_content_extra_fields Implementation of hook_content_extra_fields.
fb_social_ctools_plugin_api Implementation of hook_ctools_plugin_api().
fb_social_ctools_plugin_directory Implementation of hook_ctools_plugin_directory().
fb_social_ctools_plugin_fb_plugin Implementation of hook_ctools_plugin_TYPE (type = 'fb_plugin') This is to tell ctools that by default each plugin has some default functions named consistently after the plugin name
fb_social_custom_channel_url The Custom Channel URL that FB.init has as an option
fb_social_fb_plugin_defaults Return the default vaules of a certain plugin type as defined by facebook
fb_social_fb_plugin_drupal_settings_form Return the drupal settings form for a given plugin type
fb_social_fb_plugin_fb_settings_form Return the facebook plugin form for a given type
fb_social_fb_plugin_load load a specific fb_plugin or all of them
fb_social_footer Implementation of hook_footer
fb_social_get_presets Get all presets or a preset by name. By default it returns only enabled presets.
fb_social_get_presets_by_type
fb_social_init Implementation of hook init
fb_social_like_fb_social_event_subscribe Implementation of hook_fb_social_event_subscribe
fb_social_link Implementation of hook_link
fb_social_menu Implementation of hook_menu
fb_social_nodeapi Implements of hook_nodeapi().
fb_social_preprocess_fb_social_plugin Implements hook preprocess_hook
fb_social_preset_load load the preset
fb_social_preset_node_types Does $preset should be shown on node of type $type
fb_social_preset_view returns the fbml content of the plugin
fb_social_theme Implementation of hook_theme
fb_social_url Based on the user settings return the aliased / unaliased version of a given $url
fb_social_views_api Implements hook_views_api().
_fb_social_ctools_plugin_fb_plugin_process Helper function for ctools plugin 'process'
_fb_social_enabled_presets_filter filter presets based on come conditions $args
_map_active_languages

Constants