Sunday, March 18, 2012

Social Engine 4 Hook Example

Introduction

Following up on my previous post about SE4 hooks. On this post we create a simple hook. For example we want to create a reward system. We reward a user a point  per log-in per day i.e. a user gets a point if he logs in in a particular day but the point is only rewarded once per day. We encapsulate this feature in a theoretical plugin called "point-module."

Letting SE4 Know

We need to let SE4 know that we plan on hooking to an event. In particular the event when the user successfully logged in. SE4 has an aptly named event "onUserLoginBefore" which is triggered when the user successfully logs in but before the lastlogin_date field is updated.  On our module's manifest--the file application/modules/<module_name>/settings/manifest.php we put
 
array (
    'type' => 'module',
    'name' => 'point',
    'version' => '4.0.0',
    'path' => 'application/modules/Point',
    'title' => 'Points',
    'description' => 'Points',
    'author' => 'Marco Enrico',
    'callback' => 
    array (
      'class' => 'Engine_Package_Installer_Module',
    ),
    'actions' => 
    array (
      0 => 'install',
      1 => 'upgrade',
      2 => 'refresh',
      3 => 'enable',
      4 => 'disable',
    ),
    'directories' => 
    array (
      0 => 'application/modules/Point',
    ),
    'files' => 
    array (
      0 => 'application/languages/en/point.csv',
    ),
  ),
  // Hooks ---------------------------------------------------------------------
  'hooks' => array(
    array(
      'event' => 'onUserLoginBefore',
      'resource' => 'Point_Plugin_Core'
    )
  )
);

This lets SE4 know that we plan on handling the "onUserLoginBefore" event with an instance of the class Point_Plugin_Core.

The Handler

Next we create the handler for the event. In application/modules/Point/Plugin/Core.php:


class Point_Plugin_Core extends Core_Plugin_Abstract
{
  public function onUserLoginBefore($event)
  {
    $user = $event->getPayload();

    if (date('d', strtotime($user->lastlogin_date)) != date('d')) {
      // user's first time to login today
      // add points...
      // ...
      $this->addPoints(1);
    }
  }

  public function addPoints($points, $user = null)
  {
    //...
    
  }

}

Summary

This example illustrates that it's pretty simple to implement a social engine hook. All you really have to know is which hook best serves the task you're trying to accomplish. "What if none of the hooks apply to a customization I'm trying to accomplish?", you ask. There are other ways which is a subject of another post.

6 comments:

  1. Hi Mate,
    I tried the same way..as i know it should work...and now i found this blog and i am now pretty much sure that i did it should work,....but its not running that hook :(

    The hook name is : onRenderLayoutDefault
    Resource is : Advuserpoints_Plugin_Core

    I did like this :

    class Advuserpoints_Plugin_Core extends Core_Plugin_Abstract
    {
    public function onRenderLayoutDefault($event)
    {
    echo "m i here";exit;
    }
    }

    Before i did not use extends but now after viewing your post I used extend class.

    In the manifest I already registered it like :
    // Hooks ---------------------------------------------------------------------
    'hooks' => array(
    array(
    'event' => 'onRenderLayoutDefault',
    'resource' => 'Advuserpoints_Plugin_Core',
    ),
    ),

    Can you help me why it is not working or what can be the possibilities?

    Waiting for positive response.

    regards

    ReplyDelete
    Replies
    1. Hello,

      Sorry I didn't realize someone left a comment. I'm pretty sure your figured this out by now. But just in case. Make sure the hook key is not inside the package array. This is almost always a mistake I make. So the array in the manifest should be array('package' => array(....), 'hooks' => array(...), 'items' => array(....)).

      One way to test if your hook is registered is by not providing the handler. In your case comment out the onRenderLayoutDefault method. If your hook is registered it should complain about an undefined method.

      Hope this helps.

      Delete
  2. Hi Marco, i am developing a website using SE and i a bit confused by it because they only have few forum and a lot of it is not really active,

    so my problem is i want to make a module,this module have to check the user ID and after that save into a database,,

    for example :
    when user create a Topic or post a comment,it automatically save into their table,,i want it save into another table to,, i am searching on their folder modul/(modulname)/plugin/core.php but didnt find how they save,

    can you help me with this? thank you

    ReplyDelete
  3. If you want to save the user id of the user who created a post you can use the onItemCreateAfter/Before. Similar to the example above. All you need to do is check if the payload is the correct item.

    ReplyDelete
  4. Hi Marco,

    im back and still have a question about this

    here is my code on core hooks
    "
    // comment
    } else if ($item->getType() == 'core_comment' || $item->getType() == 'activity_comment'){

    $api = Engine_Api::_()->hebadge()->getRequireClass('comment');
    if ($api){
    $api->check($viewer, $item->getIdentity());
    }

    //likeActivities
    } else if ($item->getType() == 'activity_like'){

    $api = Engine_Api::_()->hebadge()->getRequireClass('likeactivities');
    if ($api){
    $api->check($viewer, $item->getIdentity());
    }
    //shareActivities
    } else if ($item->getType() == 'activity_share'){

    $api = Engine_Api::_()->hebadge()->getRequireClass('shareactivities');
    if ($api){
    $api->check($viewer, $item->getIdentity());
    }
    "

    for likeactivities i just copy it from the comment above (comment is from default SE4),this like activities used for when people like in home area or news feed,it worked though, but when i worked on shareactivities below it,it not work

    i have a couple question for you,but i think i will ask it one by one, so i understandd the flow of SE4,

    first question:
    in this code " ($item->getType() == 'activity_like') " it get 'activity_like' type, where it came from? when i am working in like activities i think i know where it come from,but when i worked in sharedactivities(a couple days later after working in likeactivities)i can remember about it, can you please help me?

    ReplyDelete
  5. i am sorry,,,its not on core hooks,but it from
    core public function onItemCreateAfter($event)

    and this is my hooks
    'hooks' => array(
    array(
    'event' => 'onInviterSendInvite',
    'resource' => 'Hebadge_Plugin_Core'
    ),
    array(
    'event' => 'onUserLoginBefore',
    'resource' => 'Hebadge_Plugin_Core',
    ),
    array(
    'event' => 'onItemCreateAfter',
    'resource' => 'Hebadge_Plugin_Core'

    ReplyDelete