You are here

disqus.module in Disqus 6

Same filename and directory in other branches
  1. 8 disqus.module
  2. 5 disqus.module
  3. 7 disqus.module

File

disqus.module
View source
<?php

/**
 * Implementation of hook_help().
 */
function disqus_help($path, $arg) {
  switch ($path) {
    case 'admin/help#disqus':
      $output = '<p>' . t('Uses the <a href="@disqus">Disqus</a> comment system to enhance comments.', array(
        '@disqus' => 'http://disqus.com',
      )) . '</p>';
      $output .= '<h3>' . t('Installation') . '</h3>';
      $output .= '<ol><li>' . t('Register your site information at <a href="http://disqus.com">Disqus</a>') . '</li>';
      $output .= '<li>' . t('In the <a href="@configuration">Disqus configuration</a>, set the domain to what you registered with Disqus, and what node types you would like to have comments', array(
        '@configuration' => url('admin/settings/disqus'),
      )) . '</li>';
      $output .= '<li>' . t('Visit the <a href="@permissions">permissions</a>, and set which users you would like to have the ability to view Disqus threads (recommended for role)', array(
        '@permissions' => url('admin/user/permissions', array(
          'fragment' => 'module-disqus',
        )),
      )) . '</li></ol>';
      return $output;
    case 'admin/settings/disqus':
      return '<p>' . t('The following provides the general configuration options for the <a href="@disqus">Disqus</a> comment web service.', array(
        '@disqus' => 'http://disqus.com',
      )) . '</p>';
  }
}

/**
 * Implementation of hook_perm().
 */
function disqus_perm() {
  return array(
    'administer disqus',
    'view disqus comments',
    'display disqus comments on profile',
    'toggle disqus comments',
  );
}

/**
 * Implementation of hook_menu().
 */
function disqus_menu() {
  $items = array();
  $items['admin/settings/disqus'] = array(
    'title' => 'Disqus',
    'description' => 'Provides configuration options for the Disqus comment system.',
    'access arguments' => array(
      'administer disqus',
    ),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'disqus_admin_settings',
    ),
    'file' => 'disqus.admin.inc',
  );
  $items['admin/settings/disqus/general'] = array(
    'title' => 'General',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'description' => 'Provides general configuration options for the Disqus comment system.',
    'weight' => -10,
  );
  $items['disqus/closewindow'] = array(
    'title' => 'Please wait',
    'description' => 'Once the user logs in through the Disqus login workflow, they are redirected here to automatically close the popup window.',
    'access arguments' => array(
      'view disqus comments',
    ),
    'page callback' => 'disqus_closewindow',
    'file' => 'disqus.admin.inc',
    'type' => MENU_CALLBACK,
  );

  /*
  $items['disqus/oauth_callback'] = array(
    'title' => 'Authentication Callback',
    'description' => 'Menu callback after a user has authenticated for exporting via the API',
    'access arguments' => array('administer disqus'),
    'page callback' => '_disqus_oauth_callback',
    'file' => 'disqus.admin.inc',
    'type' => MENU_CALLBACK,
  );
  */
  return $items;
}

/**
 * Implementation of hook_nodeapi().
 */
function disqus_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {

  // See if Disqus is active on this node.
  $types = variable_get('disqus_nodetypes', array());
  if (!empty($types[$node->type])) {
    switch ($op) {
      case 'presave':

        // For programmatic insertion of nodes via node_save.
        if (!isset($node->disqus['status'])) {
          $node->disqus['status'] = TRUE;
        }
        break;
      case 'load':

        // Check which Disqus domain to use.
        $domain = variable_get('disqus_domain', '');
        if (!empty($domain)) {

          // Save the data to the node object.
          $node->disqus = array(
            'domain' => $domain,
          );

          // Apply the Disqus status to the node.
          $status = db_fetch_object(db_query("SELECT status FROM {disqus} WHERE nid = %d", $node->nid));
          $node->disqus['status'] = isset($status->status) ? (bool) $status->status : TRUE;

          // Build the absolute URL without the alias for the disqus_url flag.
          $node->disqus['url'] = url("node/{$node->nid}", array(
            'absolute' => TRUE,
          ));

          // Build the title.
          $node->disqus['title'] = check_plain(strip_tags($node->title));

          // Provide the identifier.
          $node->disqus['identifier'] = 'node/' . $node->nid;

          // The developer flag must always be set when the node is unpublished.
          if ($node->status == 0) {
            $node->disqus['developer'] = 1;
          }
          elseif ($developer = variable_get('disqus_developer', FALSE)) {
            $node->disqus['developer'] = intval($developer);
          }
        }
        break;
      case 'delete':
        db_query('DELETE FROM {disqus} WHERE nid = %d', $node->nid);
        break;
      case 'insert':
        $data = array(
          'nid' => $node->nid,
          'status' => isset($node->disqus['status']) ? $node->disqus['status'] : TRUE,
        );
        drupal_write_record('disqus', $data);
        break;
      case 'update':

        // Write the status to the table, taking the node ID as the update key.
        db_query('DELETE FROM {disqus} WHERE nid = %d', $node->nid);
        $data = array(
          'nid' => $node->nid,
          'status' => isset($node->disqus['status']) ? $node->disqus['status'] : TRUE,
        );
        drupal_write_record('disqus', $data);
        break;
      case 'view':

        // See if we are to display Disqus in the current context.
        if (!$a3 && $a4 && isset($node->disqus) && user_access('view disqus comments') && $node->disqus['status'] == 1) {

          // Inject Disqus into the node object.
          switch (variable_get('disqus_location', 'content_area')) {
            case 'content_area':

              // Inject into the node content.
              $node->content['disqus'] = array(
                '#value' => theme('disqus_comments', $node->disqus),
                '#weight' => variable_get('disqus_weight', 50),
              );
              break;
            case 'variable':

              // Inject it into a variable.
              $node->disqus_comments = theme('disqus_comments', $node->disqus);
              break;
          }
        }
        break;
    }
  }
}

/**
 * Implementation of hook_form_alter().
 */
function disqus_form_alter(&$form, $form_state, $form_id) {
  $types = variable_get('disqus_nodetypes', array());
  if (isset($form['type']) && isset($form['#node']) && !empty($types[$form['type']['#value']]) && $form['type']['#value'] . '_node_form' == $form_id) {

    // Add the Disqus settings into the Comment settings fieldset if it exists.
    if (!isset($form['comment_settings'])) {
      $form['comment_settings'] = array(
        '#type' => 'fieldset',
        '#access' => user_access('toggle disqus comments'),
        '#title' => t('Comment settings'),
        '#collapsible' => TRUE,
        '#collapsed' => TRUE,
        '#weight' => 30,
      );
    }
    else {
      if (isset($form['comment_settings']['comment'])) {
        $form['comment_settings']['comment']['#access'] = $form['comment_settings']['#access'];
        $form['comment_settings']['#access'] = true;
      }
    }
    $node = $form['#node'];
    $form['comment_settings']['disqus'] = array(
      '#tree' => TRUE,
      'status' => array(
        '#type' => 'checkbox',
        '#title' => t('Enable Disqus comments'),
        '#default_value' => isset($node->disqus['status']) ? $node->disqus['status'] : TRUE,
        '#access' => user_access('toggle disqus comments'),
      ),
    );
  }
}

/**
 * Implementation of hook_user().
 */
function disqus_user($op, &$edit, &$account, $category = NULL) {
  switch ($op) {
    case 'load':

      // Only show on the profile if desired. Don't show on the administrator's profile.
      if (user_access('display disqus comments on profile', $account) && $account->uid != 1) {

        // Check which Disqus domain to use.
        $domain = variable_get('disqus_domain', NULL);
        if (!empty($domain)) {

          // Save the data to the user object.
          $account->disqus = array(
            'domain' => $domain,
          );
        }

        // Build the absolute URL without the alias for the disqus_url flag.
        $account->disqus['url'] = url("user/{$account->uid}", array(
          'absolute' => TRUE,
        ));

        // Build the title.
        $account->disqus['title'] = check_plain(strip_tags($account->name));

        // Provide the identifier.
        $account->disqus['identifier'] = 'user/' . $account->uid;

        // Inject the script.
        if ($developer = variable_get('disqus_developer', FALSE)) {
          $account->disqus['developer'] = $developer;
        }
      }
      break;
    case 'view':
      if (isset($account->disqus) && user_access('view disqus comments')) {

        // Inject Disqus into the user object.
        switch (variable_get('disqus_location', 'content_area')) {
          case 'content_area':

            // Inject into the user content.
            $account->content['disqus'] = array(
              '#value' => theme('disqus_comments', $account->disqus),
              '#weight' => variable_get('disqus_weight', 50),
            );
            break;
          case 'variable':

            // Inject it into a variable.
            $account->disqus_comments = theme('disqus_comments', $account->disqus);
            break;
        }
      }
      break;
  }
}

/**
 * Implementation of hook_link().
 */
function disqus_link($type, $node = NULL, $teaser = FALSE) {
  $links = array();

  // Only show the Disqus links on node teasers.
  if ($type == 'node' && $teaser == TRUE && $node->disqus['status'] == 1) {

    // Make sure the context is correct.
    $types = variable_get('disqus_nodetypes', array());
    $domain = variable_get('disqus_domain', NULL);
    if (!empty($types[$node->type]) && user_access('view disqus comments') && !empty($domain)) {

      // Construct the path and inject it into the links area.
      $path = url("node/{$node->nid}", array(
        'alias' => TRUE,
        'absolute' => TRUE,
      ));
      $links['disqus_comments'] = array(
        'title' => theme('disqus_comments_num', $domain, $path, t('Comments'), "node/{$node->nid}"),
        'html' => TRUE,
      );
    }
  }
  return $links;
}

/**
 * Implementation of hook_block().
 */
function disqus_block($op = 'list', $delta = 0, $edit = array()) {
  switch ($op) {
    case 'list':
      return array(
        'disqus_recent_comments' => array(
          'info' => t('Disqus: Recent Comments'),
          'cache' => BLOCK_CACHE_GLOBAL,
        ),
        'disqus_popular_threads' => array(
          'info' => t('Disqus: Popular Threads'),
          'cache' => BLOCK_CACHE_GLOBAL,
        ),
        'disqus_top_commenters' => array(
          'info' => t('Disqus: Top Commenters'),
          'cache' => BLOCK_CACHE_GLOBAL,
        ),
        'disqus_combination_widget' => array(
          'info' => t('Disqus: Combination Widget'),
          'cache' => BLOCK_CACHE_GLOBAL,
        ),
        'disqus_comments' => array(
          'info' => t('Disqus: Comments'),
          'cache' => BLOCK_NO_CACHE,
        ),
      );
    case 'configure':
      $form = array();
      $form[$delta . '_items'] = array(
        '#type' => 'select',
        '#title' => t('Number of items to show'),
        '#options' => array(
          1 => 1,
          2,
          3,
          4,
          5,
          6,
          7,
          8,
          9,
          10,
          11,
          12,
          13,
          14,
          15,
          16,
          17,
          18,
          19,
          20,
        ),
        '#default_value' => variable_get($delta . '_items', 5),
        '#access' => $delta != 'disqus_comments',
      );
      $form[$delta . '_showavatars'] = array(
        '#type' => 'select',
        '#title' => t('Show avatars'),
        '#options' => array(
          FALSE => t('No'),
          TRUE => t('Yes'),
        ),
        '#default_value' => variable_get($delta . '_showavatars', TRUE),
        '#access' => $delta == 'disqus_recent_comments' || $delta == 'disqus_top_commenters',
      );
      $form[$delta . '_avatarsize'] = array(
        '#type' => 'select',
        '#title' => t('Avatar size'),
        '#options' => array(
          24 => t('X-Small (24px)'),
          32 => t('Small (32px)'),
          48 => t('Medium (48px)'),
          92 => t('Large (92px)'),
          128 => t('X-Large (128px)'),
        ),
        '#default_value' => variable_get($delta . '_avatarsize', 32),
        '#access' => $form[$delta . '_showavatars']['#access'],
      );
      $form[$delta . '_colortheme'] = array(
        '#type' => 'select',
        '#title' => t('Color Theme'),
        '#options' => array(
          'blue' => t('Blue'),
          'grey' => t('Grey'),
          'green' => t('Green'),
          'red' => t('Red'),
          'orange' => t('Orange'),
        ),
        '#default_value' => variable_get($delta . '_colortheme', 'blue'),
        '#access' => $delta == 'disqus_combination_widget',
      );
      $form[$delta . '_defaulttabview'] = array(
        '#type' => 'select',
        '#title' => t('Default Tab View'),
        '#options' => array(
          'people' => t('People'),
          'recent' => t('Recent'),
          'popular' => t('Popular'),
        ),
        '#default_value' => variable_get($delta . '_defaulttabview', 'people'),
        '#access' => $delta == 'disqus_combination_widget',
      );
      return $form;
    case 'save':
      if ($delta != 'disqus_comments') {
        variable_set($delta . '_items', $edit[$delta . '_items']);
        variable_set($delta . '_showavatars', $edit[$delta . '_showavatars']);
        variable_set($delta . '_avatarsize', $edit[$delta . '_avatarsize']);
        variable_set($delta . '_colortheme', $edit[$delta . '_colortheme']);
        variable_set($delta . '_defaulttabview', $edit[$delta . '_defaulttabview']);
      }
      break;
    case 'view':
      $num_items = variable_get($delta . '_items', 5);
      $avatars = variable_get($delta . '_showavatars', TRUE) ? '&amp;avatar_size=' . variable_get($delta . '_avatarsize', 32) : '&amp;hide_avatars=1';
      $color = variable_get($delta . '_colortheme', 'blue');
      $default_tab = variable_get($delta . '_defaulttabview', 'people');
      $domain = variable_get('disqus_domain', '');
      if (!empty($domain)) {
        $subject = '';
        $content = '';
        switch ($delta) {
          case 'disqus_recent_comments':
            $content = <<<EOT
<div id="dsq-recentcomments" class="dsq-widget"><script type="text/javascript" src="//disqus.com/forums/{<span class="php-variable">$domain</span>}/recent_comments_widget.js?num_items={<span class="php-variable">$num_items</span>}{<span class="php-variable">$avatars</span>}"></script></div>
EOT;
            $subject = t('Recent Comments');
            break;
          case 'disqus_popular_threads':
            $subject = t('Popular Threads');
            $content = <<<EOT
<div id="dsq-popthreads" class="dsq-widget"><script type="text/javascript" src="//disqus.com/forums/{<span class="php-variable">$domain</span>}/popular_threads_widget.js?num_items={<span class="php-variable">$num_items</span>}"></script></div>
EOT;
            break;
          case 'disqus_top_commenters':
            $subject = t('Top Commenters');
            $content = <<<EOT
<div id="dsq-topcommenters" class="dsq-widget"><script type="text/javascript" src="//disqus.com/forums/{<span class="php-variable">$domain</span>}/top_commenters_widget.js?num_items={<span class="php-variable">$num_items</span>}{<span class="php-variable">$avatars</span>}"></script></div>
EOT;
            break;
          case 'disqus_combination_widget':
            $subject = t('Comments');
            $content = <<<EOT
<script type="text/javascript" src="//disqus.com/forums/{<span class="php-variable">$domain</span>}/combination_widget.js?num_items={<span class="php-variable">$num_items</span>}&amp;color={<span class="php-variable">$color</span>}&amp;default_tab={<span class="php-variable">$default_tab</span>}"></script>
EOT;
            break;
          case 'disqus_comments':
            if (variable_get('disqus_location', 'content_area') == 'block' && user_access('view disqus comments')) {
              $item = menu_get_item();
              switch ($item['path']) {
                case 'node/%':
                  if ($disqus = isset($item['page_arguments'][0]->disqus) ? $item['page_arguments'][0]->disqus : FALSE) {

                    // Only present the comments if they are enabled on the node.
                    if ($disqus['status']) {
                      $content = theme('disqus_comments', $disqus);
                    }
                  }
                  break;
                case 'user/%':
                  if ($disqus = isset($item['page_arguments'][0]->disqus) ? $item['page_arguments'][0]->disqus : FALSE) {
                    $content = theme('disqus_comments', $disqus);
                  }
                  break;
              }
            }
            break;
        }
        return array(
          'subject' => $subject,
          'content' => $content,
        );
      }
      break;
  }
}

/**
 * Implementation of hook_footer().
 *
 * @param $options
 *   The options to pass off to the Disqus comments.
 */
function disqus_footer($main = 0, $options = NULL) {

  // Adds the JavaScript required to constuct a Disqus thread.
  static $added = FALSE;
  if (!$added && isset($options)) {
    $added = TRUE;
    $domain = variable_get('disqus_domain', '');
    if (!empty($domain)) {

      // Add the Disqus Drupal behavior.
      drupal_add_js(drupal_get_path('module', 'disqus') . '/disqus.js');

      // Construct the Disqus settings.
      $settings = array(
        'url' => $options['url'],
        'title' => $options['title'],
        'identifier' => $options['identifier'],
        'shortname' => $domain,
      );

      // Inject the developer flag if we are debugging.
      if (isset($options['developer'])) {
        $settings['developer'] = 1;
      }

      // See if we are to inject the user's name and email address.
      global $user;
      if (variable_get('disqus_inherit_login', TRUE) && $user->uid > 0) {
        $settings['name'] = $user->name;
        $settings['email'] = $user->mail;
      }

      // Provide alternate language support if desired.
      if (variable_get('disqus_localization', FALSE)) {
        global $language;
        $settings['language'] = $language->language;
      }

      // Check if we are to provide Single Sign-On access.
      if (variable_get('disqus_sso', FALSE)) {
        $data = array();

        // Inject the user data if it's available.
        if ($user->uid > 0) {
          $data['id'] = $user->uid;
          $data['username'] = $user->name;
          $data['email'] = $user->mail;
          $data['url'] = url('user/' . $user->uid, array(
            'absolute' => TRUE,
          ));

          // Load the user's avatar.
          $user_picture_default = variable_get('user_picture_default', '');
          if (isset($user->picture) && !empty($user->picture)) {
            $data['avatar'] = url($user->picture, array(
              'absolute' => TRUE,
            ));
          }
          elseif (!empty($user_picture_default)) {
            $data['avatar'] = url($user_picture_default, array(
              'absolute' => TRUE,
            ));
          }
        }

        // Give Disqus information about the site.
        $settings['sso'] = array(
          'name' => variable_get('site_name', t('Drupal')),
          // The login window must be closed once the user logs in.
          'url' => url('user/login', array(
            'query' => array(
              'destination' => 'disqus/closewindow',
            ),
          )),
          // The logout link must redirect back to the original page.
          'logout' => url('logout', array(
            'query' => array(
              'destination' => $_GET['q'],
            ),
          )),
          'width' => 800,
          'height' => 600,
        );
        if ($logo = theme_get_setting('logo')) {
          $settings['sso']['button'] = $logo;
        }
        else {
          $settings['sso']['button'] = url('misc/druplicon.png', array(
            'absolute' => TRUE,
          ));
        }
        if ($favicon = theme_get_setting('favicon')) {
          $settings['sso']['icon'] = $favicon;
        }

        // Encode the data to be sent off to Disqus.
        $message = base64_encode(json_encode($data));
        $timestamp = time();
        $hmac = hash_hmac('sha1', "{$message} {$timestamp}", variable_get('disqus_secretkey', ''));

        // Stick the authentication requirements and data in the settings.
        $settings['remote_auth_s3'] = "{$message} {$hmac} {$timestamp}";
        $settings['api_key'] = variable_get('disqus_publickey', '');
      }

      // Add the JavaScript.
      drupal_add_js(array(
        'disqus' => $settings,
      ), 'setting');
    }
  }
}

/**
 * Implementation of hook_theme().
 */
function disqus_theme() {
  return array(
    'disqus_comments' => array(
      'arguments' => array(
        'options' => NULL,
      ),
    ),
    'disqus_comments_num' => array(
      'arguments' => array(
        'domain' => NULL,
        'path' => NULL,
      ),
    ),
  );
}

/**
 * Renders the JavaScript to display the Disqus thread for the current page.
 * @param $options
 *   An array containing the following items:
 *     - "domain": The domain associated with this Disqus account.
 *     - "title": The title of the thread.
 *     - "message": The teaser of the thread.
 *     - "developer": Whether or not testing is enabled.
 *     - "url": The disqus_url variable (http://disqus.com/docs/help/#faq-16).
 */
function theme_disqus_comments($options = array()) {
  disqus_footer(0, $options);
  return '<div id="disqus_thread"></div><noscript><div class="disqus-noscript"><a href="http://' . $options['domain'] . '.disqus.com/?url=' . urlencode($options['url']) . '">' . t('View the discussion thread.') . '</a></div></noscript>';
}

/**
 * Renders the JavaScript to change all Disqus comment links to the correct number of comments.
 *
 * @param $domain
 *   The Disqus domain associated with this account.
 * @param $path
 *   (optional) The path of the full article of who's comments you want to display.
 * @param $text
 *   (optional) The text to be displayed in the link.
 * @return
 *   If $path is given, will provide a rendered HTML link for the comments.
 */
function theme_disqus_comments_num($domain, $path = NULL, $text = NULL, $identifier = NULL) {
  static $added = FALSE;
  if ($added == FALSE) {
    drupal_add_js(drupal_get_path('module', 'disqus') . '/disqus.js');
    drupal_add_js(array(
      'disqusCommentDomain' => $domain,
    ), 'setting');
    $added = TRUE;
  }
  $text = empty($text) ? t('Comments') : $text;
  if (isset($path)) {
    $attributes['class'] = 'comments disqus-comments';
    $attributes['title'] = t('Jump to the comments of this posting.');
    if (isset($identifier)) {
      $attributes['data-disqus-identifier'] = $identifier;
    }
    return l($text, $path, array(
      'attributes' => $attributes,
      'alias' => TRUE,
      'absolute' => TRUE,
      'fragment' => 'disqus_thread',
    ));
  }
}

/**
 * Implementation of hook_view_api().
 */
function disqus_views_api() {
  return array(
    'api' => 2,
  );
}

/**
 * Creates an instance of the Disqus PHP API.
 *
 * @param $user_api_key
 *   The User API Key.
 * @param $forum_api_key
 *   The Forum API key.
 *
 * @return
 *   The instance of the Disqus API.
 */
function disqus($user_api_key = NULL, $forum_api_key = NULL) {
  module_load_include('php', 'disqus', 'disqus');
  return new Disqus($user_api_key, $forum_api_key);
}

/**
 * Implement hook_cron
 *
 * We want to renew API access tokens before they expire. This ensures that a user will only have to go
 * through the authentication process once.
 */

/*
function disqus_cron() {
  $oauth_expires = variable_get('disqus_oauth_expires_on', '');
  if (!empty($oauth_expires)) {

    // Check to see if we should renew the access tokens yet
    $buffer = 259200; // 3 day buffer
    if (time() + $buffer > $oauth_expires) {
      // 3 days or less from now, the access token will expire. Lets renew it
      $parameters = array(
        'grant_type' => 'refresh_token',
        'client_id' => variable_get('disqus_publickey', ''),
        'client_secret' => variable_get('disqus_secretkey', ''),
        'refresh_token' => variable_get('disqus_oauth_refresh_token', ''),
      );

      module_load_include('admin.inc', 'disqus', 'disqus');
      _disqus_oath_request_access_token($parameters);
    }
  }
}
*/

Functions

Namesort descending Description
disqus Creates an instance of the Disqus PHP API.
disqus_block Implementation of hook_block().
disqus_footer Implementation of hook_footer().
disqus_form_alter Implementation of hook_form_alter().
disqus_help Implementation of hook_help().
disqus_link Implementation of hook_link().
disqus_menu Implementation of hook_menu().
disqus_nodeapi Implementation of hook_nodeapi().
disqus_perm Implementation of hook_perm().
disqus_theme Implementation of hook_theme().
disqus_user Implementation of hook_user().
disqus_views_api Implementation of hook_view_api().
theme_disqus_comments Renders the JavaScript to display the Disqus thread for the current page.
theme_disqus_comments_num Renders the JavaScript to change all Disqus comment links to the correct number of comments.