Home >Backend Development >PHP Tutorial >Drupal goes Social: Building a 'Liking' Module in Drupal

Drupal goes Social: Building a 'Liking' Module in Drupal

William Shakespeare
William ShakespeareOriginal
2025-02-18 09:03:10965browse

This article demonstrates how to build a Drupal module enabling users to "like" posts using jQuery AJAX calls for asynchronous data saving.

Drupal goes Social: Building a

Key Features:

  • Asynchronous liking via jQuery AJAX.
  • Database storage of likes (per user, per post).
  • Real-time like count updates.
  • Clear UI indicating like/unlike status.

Module Creation:

  1. Create a likepost folder within your Drupal installation's sites/all/modules/custom directory.
  2. Inside likepost, create likepost.info:
<code>name = likepost
description = Allows users to like Drupal posts.
core = 7.x</code>
  1. Create likepost.module: (Initial hook_help implementation included below for completeness, but the core functionality is added later)
<code class="language-php">/**
 * @file
 * Main module file.
 */

/**
 * Implements hook_help().
 */
function likepost_help($path, $arg) {
  if ($path == 'admin/help#likepost') {
    $output = '<h3>' . t('About') . '</h3>';
    $output .= '<p>' . t('This module allows users to like posts in Drupal.') . '</p>';
    return $output;
  }
}</code>
  1. Create likepost.install to define the database schema:
<code class="language-php"><?php
/**
 * Implements hook_schema().
 */
function likepost_schema() {
  $schema['likepost_table_for_likes'] = array(
    'description' => t('Stores post likes.'),
    'fields' => array(
      'userid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => t('User ID'),
      ),
      'nodeid' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
        'description' => t('Node ID'),
      ),
    ),
    'primary key' => array('userid', 'nodeid'),
  );
  return $schema;
}</code>

Install the module. The likepost_table_for_likes table will be created.

Drupal goes Social: Building a

AJAX Handling (likepost.module):

Add the following functions to likepost.module:

<code class="language-php">/**
 * Implements hook_menu().
 */
function likepost_menu() {
  $items['likepost/like/%'] = array(
    'title' => 'Like',
    'page callback' => 'likepost_like',
    'page arguments' => array(2),
    'access arguments' => array('access content'),
    'type' => MENU_SUGGESTED_ITEM,
  );
  return $items;
}

function likepost_like($nodeid) {
  $nodeid = (int) $nodeid;
  global $user;

  $like = likepost_get_like($nodeid, $user->uid);

  if ($like) {
    db_delete('likepost_table_for_likes')
      ->condition('userid', $user->uid)
      ->condition('nodeid', $nodeid)
      ->execute();
    $like = 0;
  } else {
    db_insert('likepost_table_for_likes')
      ->fields(array(
        'userid' => $user->uid,
        'nodeid' => $nodeid,
      ))
      ->execute();
    $like = 1;
  }

  $total_count = likepost_get_total_like($nodeid);
  drupal_json_output(array(
    'like_status' => $like,
    'total_count' => $total_count,
  ));
}

function likepost_get_total_like($nid) {
  $total_count = db_query('SELECT COUNT(*) FROM {likepost_table_for_likes} WHERE nodeid = :nodeid', array(':nodeid' => $nid))->fetchField();
  return (int) $total_count;
}

function likepost_get_like($nodeid, $userid) {
  $like = db_query('SELECT COUNT(*) FROM {likepost_table_for_likes} WHERE nodeid = :nodeid AND userid = :userid', array(':nodeid' => $nodeid, ':userid' => $userid))->fetchField();
  return (int) $like;
}</code>

Displaying the Like Button (likepost.module):

<code class="language-php">/**
 * Implements hook_node_view().
 */
function likepost_node_view($node, $view_mode) {
  if ($view_mode == 'full') {
    $node->content['likepost_display'] = array(
      '#markup' => display_like_post_details($node->nid),
      '#weight' => 100,
    );
    $node->content['#attached']['js'][] = array(
      'data' => drupal_get_path('module', 'likepost') . '/likepost.js',
    );
    $node->content['#attached']['css'][] = array(
      'data' => drupal_get_path('module', 'likepost') . '/likepost.css',
    );
  }
}

function display_like_post_details($nid) {
  global $user;
  $totalLike = likepost_get_total_like($nid);
  $hasCurrentUserLiked = likepost_get_like($nid, $user->uid);
  return theme('like_post', array(
    'nid' => $nid,
    'totalLike' => $totalLike,
    'hasCurrentUserLiked' => $hasCurrentUserLiked,
  ));
}

/**
 * Implements hook_theme().
 */
function likepost_theme() {
  $themes = array(
    'like_post' => array(
      'arguments' => array('nid', 'totalLike', 'hasCurrentUserLiked'),
    ),
  );
  return $themes;
}

function theme_like_post($arguments) {
  $nid = $arguments['nid'];
  $totalLike = $arguments['totalLike'];
  $hasCurrentUserLiked = $arguments['hasCurrentUserLiked'];
  global $base_url;
  $output = '<div>';
  $output .= 'Total number of likes on the post are ';
  $output .= '<div class="total_count">' . $totalLike . '</div>';
  $linkText = ($hasCurrentUserLiked == 0) ? 'Like' : 'Unlike';
  $output .= l($linkText, $base_url . '/likepost/like/' . $nid, array('attributes' => array('class' => 'like-link')));
  $output .= '</div>';
  return $output;
}</code>

Styling (likepost.css):

<code class="language-css">.likepost {
  border-style: dotted;
  border-color: #98bf21;
  padding: 10px;
}

.total_count {
  font-weight: bold;
}

.like-link {
  color: red;
}

.like-link:hover {
  color: red;
}</code>

jQuery (likepost.js):

<code class="language-javascript">jQuery(document).ready(function($) {
  $('a.like-link').click(function(e) {
    e.preventDefault();
    $.ajax({
      type: 'POST',
      url: this.href,
      dataType: 'json',
      success: function(data) {
        $('a.like-link').text(data.like_status ? 'Unlike' : 'Like');
        $('.total_count').text(data.total_count);
      },
    });
  });
});</code>

Remember to clear Drupal's cache after making changes. This detailed explanation should allow for a more robust and understandable implementation of the liking module. The screenshots are placeholders; you'll see the actual module output in your Drupal site.

The above is the detailed content of Drupal goes Social: Building a 'Liking' Module in Drupal. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn