Jesus Larrubia
Web developer (Drupal)
By: Jesus Larrubia
To make the challenge more difficult and enhance the enjoyment:
In drupal.org we can find different contrib modules that provide a "like" functionality:
Flag & DLike
Like button
Like & Dislike
*THE CHOSEN*
Why?
More reasons...
Advantages
Disadvantages
Disadvantages
The modules provide the necessary functionality, through their UI, to:
Requirement 2. Liked content/comments list
Two views configured through UI:
Requirement 3. Received likes
Two blocks (views-block display):
/**
* Implements hook_field_extra_fields().
*/
...
// Includes the pseudo field mylike for every comment/content type.
foreach ($entities as $entity) {
$extra[$entity][$bundle] = array(
'display' => array(
'mylike' => array(
'label' => t('My like'),
'description' => t('Custom like button.'),
'weight' => -5,
),
),
);
}
...
/**
* Implements hook_entity_view().
*
*/
...
if ($view_mode == 'full') {
$entity->content['mylike'] = array(
'#markup' => mylike_create_link($entity, $type),
);
}
}
/**
* It creates a renderable mylike link.
*/
function mylike_create_link($entity, $type) {
...
// Creates the like/unlike link.
$link_wrapper['content']['link'] = array(
'#type' => 'link',
'#title' => t('My Like (@likes_number)', array('@likes_number' => $likes_number)),
'#href' => "mylike/$type/" . $entity_id . "/like",
);
...
mylike.install
/**
* Implements hook_schema().
*/
function mylike_schema() {
$schema['mylike'] = array(
'fields' => array(
'mlid' => array(
'description' => 'The unique mylike ID.',
...
'entity_type' => array(
'description' => 'The liked entity type, "node" or "comment".',
...
'entity_id' => array(
'description' => 'The unique ID of the liked entity, (cid, or nid).',
...
'uid' => array(
'description' => 'The user ID who likes the entity.',
...
Created table to save the necessary information:
Workflow
User "likes" x
(clic mylike link)
Send request
Handle request
(hook_menu)
Save mylike in DB
(callback function )
like/unlike action
Return page
New mylike link
(count +1)
Client side
Server side
// Creates the like/unlike link with the AJAX property enabled.
if (!$user_likes) {
$link_wrapper['content']['link'] = array(
'#type' => 'link',
'#title' => t('My Like (@likes_number)', array('@likes_number' => $likes_number)),
'#href' => "mylike/$type/" . $entity_id . "/like/nojs",
'#ajax' => array(
'wrapper' => "link-$type-$entity_id",
'method' => 'html',
),
);
}
Source (Spanish): http://www.ladrupalera.com/drupal/desarrollo/drupal7/eventos-ajax-en-elementos-de-pagina-distintos-de-formulario
/**
* Ajax callback. It manages actions (clics) in mylike links.
*/
function mylike_link($entity_type, $entity_id, $op, $type = 'ajax') {
...
// Deliver Ajax response.
if ($type == 'ajax') {
$commands = array();
$ajax_link = mylike_create_link($entity, $entity_type);
$commands[] = ajax_command_replace("#link-$entity_type-$entity_id", $ajax_link);
$commands[] = ajax_command_append("#link-$entity_type-$entity_id", $messaje_output);
$page = array('#type' => 'ajax', '#commands' => $commands);
ajax_deliver($page);
}
/**
* Implements hook_permission().
*/
function mylike_permission() {
return array(
// It allows users to like other users content/comments.
'access mylike link' => array(
'title' => t('Access mylike link'),
'description' => t('Access mylike link'),
),
/**
* Access function callback. Return true if the current user can like an entity.
*/
function mylike_link_access($entity_type, $entity_id) {
...
// Only users with the permission 'access mylike link' (authenticated users)
// and differents to the user author can access to the link.
if (user_access('access mylike link') && $entity->uid != $user->uid) {
return TRUE;
}
/**
* Menu function callback. Display a liked entity history (content and comments).
*/
function mylike_user_content_liked($user, $type) {
...
$query = db_select('mylike', 'ml')
->condition('ml.entity_type', $entity_type, '=')
...
$entities = $query->execute()->fetchAll();
foreach ($entities as $id_info) {
$node_view = node_view(node_load($id_info->entity_id), $view_mode);
$row['data'] = array(render($node_view));
// Return properly styled output.
return array(
'#theme' => 'table',
'#rows' => $rows,
);
}
/**
* Implements hook_block_info().
*/
function mylike_block_info() {
$blocks = array();
// Total user received likes for content.
$blocks['mylike_user_content_likes'] = array(
'info' => t('User, content received likes'),
);
// Total user received likes for comments.
$blocks['mylike_user_comment_likes'] = array(
'info' => t('User, comment received likes'),
);
/**
* Implements hook_user_view().
*/
function mylike_user_view($account, $view_mode) {
// It includes the total of likes received by the user for comments/content
// in the profile summary.
$likes = mylike_count_user_received_likes('both', $account->uid);
$account->content['summary']['mylike'] = array(
'#type' => 'user_profile_item',
'#title' => t('Your total count'),
'#markup' => t('Received likes: @likes', array('@likes' => $likes)),
'#attributes' => array('class' => array('blog')),
);
}
By Jesus Larrubia
Drupal tasks - like functionality