Extending Elgg Notifications

In this topic I will be discussing and explaining extending the elgg-notify modification of the elgg notifications plugin. The modification provides an ajax menu of new incoming events in realtime. The plugin itself does not need to be extended, but its functionality needs to be extended into the various plugins you may use with your site. What my main focus will be is to define the information thats needed to implement the functions as well as give examples of implementation in plugins that i've already modified. If you've figured out the implementation of any plugins and would care to explain your method, the community would greatly appreciate it ;)

 

Plugins extended (still need to write up explanations on these)

-messages (send and reply)

-messageboard

-walltowall

 

  • I believe the first thing to be noted is that different plugins place their notification functions in different areas of the plugin's structure. One case i've stumbled upon is the messages plugin, which contains its actual message sending code inside its start.php, which I've been unable to override. The main method I think the notifications mod relies on to extend other plugins is that they're using actions to trigger notifications. What it will do is override these other plugins actions with ones similar with just a few added lines to give the notifications plugin the right information.

    In this case i've copied the relevant function from the messages plugin start.php

            /**
                 * Send an internal message
                 *
                 * @param string $subject The subject line of the message
                 * @param string $body The body of the mesage
                 * @param int $send_to The GUID of the user to send to
                 * @param int $from Optionally, the GUID of the user to send from
                 * @param int $reply The GUID of the message to reply from (default: none)
                 * @param true|false $notify Send a notification (default: true)
                 * @param true|false $add_to_sent If true (default), will add a message to the sender's 'sent' tray
                 * @return true|false Depending on success
                 */
                function messages_send($subject, $body, $send_to, $from = 0, $reply = 0, $notify = true, $add_to_sent = true) {
                  
                        global $messagesendflag;
                        $messagesendflag = 1;
                      
                        global $messages_pm;
                        if ($notify) {
                            $messages_pm = 1;
                        } else {
                            $messages_pm = 0;
                        }
                      
                    // If $from == 0, set to current user
                            if ($from == 0)
                                $from = (int) get_loggedin_user()->guid;
                              
                    // Initialise a new ElggObject
                            $message_to = new ElggObject();
                            $message_sent = new ElggObject();
                    // Tell the system it's a message
                            $message_to->subtype = "messages";
                            $message_sent->subtype = "messages";
                    // Set its owner to the current user
                            $message_to->owner_guid = $send_to;
                            $message_to->container_guid = $send_to;
                            $message_sent->owner_guid = $from;
                            $message_sent->container_guid = $from;
                    // For now, set its access to public (we'll add an access dropdown shortly)
                            $message_to->access_id = ACCESS_PUBLIC;
                            $message_sent->access_id = ACCESS_PUBLIC;
                    // Set its description appropriately
                            $message_to->title = $subject;
                            $message_to->description = $body;
                            $message_sent->title = $subject;
                            $message_sent->description = $body;
                    // set the metadata
                            $message_to->toId = $send_to; // the user receiving the message
                            $message_to->fromId = $from; // the user receiving the message
                            $message_to->readYet = 0; // this is a toggle between 0 / 1 (1 = read)
                            $message_to->hiddenFrom = 0; // this is used when a user deletes a message in their sentbox, it is a flag
                            $message_to->hiddenTo = 0; // this is used when a user deletes a message in their inbox
                            $message_sent->toId = $send_to; // the user receiving the message
                            $message_sent->fromId = $from; // the user receiving the message
                            $message_sent->readYet = 0; // this is a toggle between 0 / 1 (1 = read)
                            $message_sent->hiddenFrom = 0; // this is used when a user deletes a message in their sentbox, it is a flag
                            $message_sent->hiddenTo = 0; // this is used when a user deletes a message in their inbox
                          
                            $message_to->msg = 1;
                            $message_sent->msg = 1;
                          
                        // Save the copy of the message that goes to the recipient
                            $success = $message_to->save();
                          
                        // Save the copy of the message that goes to the sender
                            if ($add_to_sent) $success2 = $message_sent->save();
                          
                            $message_to->access_id = ACCESS_PRIVATE;
                            $message_to->save();
                          
                            if ($add_to_sent) {
                                $message_sent->access_id = ACCESS_PRIVATE;
                                $message_sent->save();
                            }
                          
                        // if the new message is a reply then create a relationship link between the new message
                        // and the message it is in reply to
                            if($reply && $success){
                                $create_relationship = add_entity_relationship($message_sent->guid, "reply", $reply);                      
                            }
                                         
                            global $CONFIG;
                            $message_contents = strip_tags($body);
                            if ($send_to != get_loggedin_user() && $notify)
                            notify_user($send_to, get_loggedin_user()->guid, elgg_echo('messages:email:subject'),
                                sprintf(
                                            elgg_echo('messages:email:body'),
                                            get_loggedin_user()->name,
                                            $message_contents,
                                            $CONFIG->wwwroot . "pg/messages/" . $user->username,
                                            get_loggedin_user()->name,
                                            $CONFIG->wwwroot . "mod/messages/send.php?send_to=" . get_loggedin_user()->guid
                                        )
                            );        
                            $messagesendflag = 0;  
                            return $success;             
                }

    and have pasted inside a copy of mod/messages/actions/send.php

    I can then place this copy in mod/notifications/actions/messages/

    Next I added the results necessary for the live notifications handler to work, and not give me that horrible "not configured" error message ;) in this example i've modified the results to give me a different notification message depending on the elgg messages status as a reply.


                    // if the new message is a reply then create a relationship link between the new message
                    // and the message it is in reply to
                    // also notify user whether it is reply or not -trk
                    if($reply && $success){
                        $create_relationship = add_entity_relationship($message_sent->guid, "reply", $reply);                       
                        $message_status = "reply";
                        }
                        global $CONFIG;
                        //Check for status as a reply -trk
                        if ($message_status != "reply") {
                        $message_status_message = " sent you a ";
                        } else {
                        $message_status_message = " replied to your ";
                        }
                        //build notification message -trk
                        $notifyMessage = "has" . $message_status_message . "<a href=\"" . $CONFIG->wwwroot . "pg/messages/" . $message_to->getOwnerEntity()->username . "/read/" . $message_to->guid . "\">private message </a>";
                        $message_contents = strip_tags($body);
                        if ($send_to != get_loggedin_user() && $notify)
                        notify_user($send_to, get_loggedin_user()->guid, $subject = elgg_echo('messages:email:subject'),
                            $message = sprintf(
                                        elgg_echo('messages:email:body'),
                                        get_loggedin_user()->name,
                                        $message_contents,
                                        $CONFIG->wwwroot . "pg/messages/" . $user->username,
                                        get_loggedin_user()->name,
                                        $CONFIG->wwwroot . "mod/messages/send.php?send_to=" . get_loggedin_user()->guid
                                    ),
                        //send notification message -trk
                        $live = $notifyMessage
                        );
                        $messagesendflag = 0;   
                        return $success;
            }

    the last thing for this file is to rename our function from messages_send to something a little more descriptive and also so it doesnt conflict with the previous messages_send function that we're unable to completely override because it resides in the start.php. I chose:

            function messages_send_live
           

    Next I open up /mod/notifications/start.php

    and add the code that will override the normal send action with my own.
       
            // Register action
            global $CONFIG;
            //unregister_notification_handler($site);
            register_action("comments/add",false,$CONFIG->pluginspath . "notifications/actions/comments/add.php");
            register_action("messageboard/add",false,$CONFIG->pluginspath . "notifications/actions/messageboard/add.php");
            register_action("notificationsettings/reset",false,$CONFIG->pluginspath . "notifications/actions/reset.php");
            register_action("notificationsettings/save",false,$CONFIG->pluginspath . "notifications/actions/save.php");
            register_action("notificationsettings/groupsave",false,$CONFIG->pluginspath . "notifications/actions/groupsave.php");
            //new messages send action
            register_action("messages/send",false,$CONFIG->pluginspath . "notifications/actions/messages/send.php");
           
           

    the final icing on the cake is making an ajax endpoint within the messages plugin for the notifications plugin to load.
    if you've installed the notifications mod already, you'll notice an endpoint was already added to the messageboard plugin, for the example the author wrote.
    you can just make a copy of this folder in the /mod/messages folder and open up load.php for editing
    the main thing to do to with this file is just change what says "messageboard" to say "messages"
    here is my example

        <?php

        /**
         * Elgg message board widget ajax logic page
         *
         * @package ElggMessageBoard
         * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
         * @author Curverider Ltd <info@elgg.com>
         * @copyright Curverider Ltd 2008-2010 - 2009
         * @link http://elgg.com/
         */

        // Load Elgg engine will not include plugins
         require_once(dirname(dirname(dirname(dirname(__FILE__)))) . "/engine/start.php");
       
        //get the required info
       
        //the actual message
        $message = get_input('message');
        //the number of messages to display
        $numToDisplay = get_input('numToDisplay');   
        //get the full page owner entity
        $user = get_entity($_POST['pageOwner']);
       
        //stage one - if a message was posted, add it as an annotation   
        if($message){
           
           // If posting the comment was successful, send message
               if ($user->annotate('messages',$message,$user->access_id, $_SESSION['user']->getGUID())) {
                       
                global $CONFIG;
                       
                if ($user->getGUID() != $_SESSION['user']->getGUID())
                    notify_user($user->getGUID(), $_SESSION['user']->getGUID(), elgg_echo('messages:email:subject'),
                    sprintf(
                        elgg_echo('messages:email:body'),
                        $_SESSION['user']->name,
                        $message,
                        $CONFIG->wwwroot . "pg/messages/" . $user->username,
                        $_SESSION['user']->name,
                        $_SESSION['user']->getURL()
                        ),
                            $live = "has" . $message_status_message . " <a href=\"" . $CONFIG->wwwroot . "pg/messages/" . $user->username . "read/" . $message_to->guid .  "\"> private message </a>"
                    );
                  
               
               }else{
                   register_error(elgg_echo("messages:failure"));
            }
           
        } else {
           
            echo elgg_echo('messages:somethingwentwrong');
           
        }
       
        //step two - grab the latest messageboard contents, this will include the message above, unless an issue
        //has occurred.
        $contents = $user->getAnnotations('messageboard', $numToDisplay, 0, 'desc');
       
        //step three - display the latest results
        if($contents){
           
            foreach($contents as $content) {
                   
                echo elgg_view("messages/message", array('annotation' => $content));
                   
            }
           
        }

       
    ?>




    That should be the final step to live private message notifications, notice in this last step I also removed the add_to_river, which normally isnt used by the messages plugin.

    Any questions, comments or improvements are welcome!

  •  esto es compatible con elgg 1.7 ? y si puedes subir una versión de este plugin se agradece 

  • , esto se hizo en Elgg 1.7. Cuando llego a este integrado en todos los plugins de base que yo uso para mi sitio, voy a subir un plugin

  • been working on the friend_request plugin, will have something on that very soon.

  • Hello Trackhed,

    I am rather interested in this plugin and making it work on elgg v1.7.1 + and adding new notifications , can you provide me ur modded version of elgg-notify , so I can make it work on my elgg 1.7.5 and then start setting up new notifications!

     

    Regards,

    Aimash

  • Hey all,

    I am more than intersted in this plugin. It has such potential - and will really help users to realise all of the activity on their content.

    Any development trackhed?

  • +1 for pluggin fix ,this could be aweso,e

     

  • The plugin is already fixed , it just needs to be extended to account for all types of events

  • Any update on friends_request fixes ?

  • Hi all, i've sort of been falling behind on this, but I will be picking up the slack very soon. If you would like to email me at T(dot)is(dot)for(dot)trackhed@gmail.com I can provide a copy of the partially finished work i've done to give you an idea on the type of modifications needed to make extend the plugin.