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

Biggest issue here is that this module present a CRSF vunerability, there is no verification when accessing the like action callback, It should be a form to prevent abuse. Here is how to do things properly: Create forms in a safe way to avoid cross-site request forgeries (CSRF).

Usually we should stop here and fix the thing (or better, as was said earlier, use flag module and be done with it).

But let’s take it all the way, this is a vulgarization article so I’d rather people learn the right things (if not in the article, in the comments):

  1. There ought to be a custom permission for this, access content is way to permissive and un-customizable. Combine that with the CRSF issue and watch your DB melt.
  2. As far as I can see all anonymous users gets one vote and step on each others, clearly a bug (anon users have the user ID 0).
  3. User text is not translatable, the t() function needs to be used.
  4. Also, it would be great to use Drupal coding standards when writing Drupal code:
  • Indentation is 2 spaces.
  • else on a new line.
  1. There is no need to use $base_url, that’s what the l() function is for.

  2. There is a straight up bug in the JS, try displaying several likes on the page and things will get messed up. It is also neither using Drupal JS API nor JS standards.

// wrote the code without running it, should work but no guarantees.
(function ($) {
  "use strict";
  // jQuery ready doesn't work for content added through ajax,
  // always use Drupal.behaviors.
  Drupal.behaviors.likeLink = {
    attach: function (context) {
      // The jquery once plugin make sure initialization happens only once.
      // It is completely different from jQuery.one()
      $(context).find('likepost').once('like-link').each(function () {
        var $likepost = $(this);
        $likepost.find('a.like-link').click(function (event) {
          $.ajax({
            type: 'POST',
            url: this.href,
            dataType: 'json',
            success: function (data) {
              var $like = $(event.target);
              if (data.like_status === 0) {
                $like.html('Like');
              }
              else {
                $like.html('Delete Like');
              }
              $likepost.find('.total_count').html(data.total_count);
            },
            data: 'js=1'
          });

          return false;
        });
      });
    },
    // When removing the content during ajax calls, clean up things.
    detach: function (context, settings, trigger) {
      if (trigger === 'unload') {
        $(context).find('likepost').removeOnce('like-link')
          .find('a.like-link').off('click');
      }
    }
  };
})(jQuery);

On the plus side, using a theme function is good and special thumbs up for using #attached instead of the dirty drupal_add_js lots of kudos from me there :smile:.

There ought to be at least a tiny amount of peer review to avoid code presenting security vulnerability make it on sitepoint.com. Wouldn’t want people to complain about Drupal when it’s only fault may be hard to find documentation.