Home >Backend Development >PHP Tutorial >Drupal goes Social: Building a 'Liking' Module in Drupal
This article demonstrates how to build a Drupal module enabling users to "like" posts using jQuery AJAX calls for asynchronous data saving.
Key Features:
Module Creation:
likepost
folder within your Drupal installation's sites/all/modules/custom
directory.likepost
, create likepost.info
:<code>name = likepost description = Allows users to like Drupal posts. core = 7.x</code>
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>
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.
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!