Subversion Repositories travelsized

Rev

Rev 438 | Blame | Compare with Previous | Last modification | View Log | RSS feed

<?PHP
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * This file is part of Travelsized CMS
 *              A content management system with modules, based on wiki syntax
 *
 * Author: Dan Jensen <admin@leinir.dk>
 * Copyright 2003/2004
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * The GNU General Public License is available at: http://www.gnu.org/copyleft/
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


/**
 * Function to send a message to a user, with the subject and message as defined
 *
 * @param     username       The user id to send the message to
 * @param     subject        The subject of the message
 * @param     message        The message body
 * @param     from           The username for the sender
 * @param     messagetype    The type of message to send the user
 *
 * @return    bool           Will return true if the message was sent successfully
 */

function sendMessage($username, $subject, $message, $from, $messagetype = "email") {
        switch( $messagetype )
        {
        default: // Email
                if( mail( getUserInfo( $username, "email" ), $subject, $message, "From: " . getUserInfo( $from, "name") . " <" . getUserInfo( $from, "email" ) . ">" . "\r\n" . "X-Mailer: PHP/" . phpversion() ) )
                        return true;
        }
       
       
        return false; // If we get to here, that means the message was not accepted for delivery
}

/**
 * The subscription handler
 *
 * Global IDs should be in the form contenttype/internalID/internalSubID
 *
 * For example:
 * discuss/sectionID/forumID/threadID
 * gallery/galleryname/subgalleryname/imagename
 * gallery/galleryname/subgalleryname
 * user/username
 * user/username/blog
 *
 * This format is used to see, if a parent is subscribed to, and reacted to in the renderSubscribeControl function
 */

class subscriptionsManager extends lockableClass
{
        var $subscriptions;                ///< @var Array in the format [globalID][username][messagetype] = true
        var $updates;                      ///< @var
       
        var $filename = "";
        var $updatesFilename = "";
       
        /**
        * The subscriptionsManager constructor
        */

        function subscriptionsManager()
        {
                global $setup_folder;
                $this->lockfile = "$setup_folder/subscriptions.lock";
                $this->filename = "$setup_folder/subscriptions.php";
                $this->updatesFilename = "$setup_folder/updates.php";
               
                $this->load();
               
                if( array_key_exists( "globalID", $_REQUEST ) )
                {
                        if( array_key_exists( "subscribe", $_REQUEST ) && $_REQUEST["subscribe"] == "yes" )
                                $this->subscribe( currentUser(), $_REQUEST["globalID"] );
                        else if( array_key_exists( "subscribe", $_REQUEST ) && $_REQUEST["subscribe"] == "no" )
                                $this->unsubscribe( currentUser(), $_REQUEST["globalID"] );
                }
        }
       
        function load()
        {
                if( file_exists( $this->filename ) )
                        include $this->filename;
                if( ! is_array( $subscriptions ) )
                        $this->subscriptions = array();
                else
                        $this->subscriptions = $subscriptions;
               
                if( file_exists( $this->updatesFilename ) )
                        include $this->updatesFilename;
                if( ! is_array( $updates ) )
                        $this->updates = array();
                else
                        $this->updates = $updates;
               
                return true;
        }
       
        /**
        * Saves the subscriptions
        *
        * @return    bool           Wether the subscriptions were saved successfully
        */

        function save()
        {
                if( file_exists( $this->filename ) )
                        unlink( $this->filename );
               
                $returnval = fileSave( $this->filename, array_export( $this->subscriptions, "subscriptions" ) );
               
                if( file_exists( $this->updatesFilename ) )
                        unlink( $this->updatesFilename );
               
                $returnval = fileSave( $this->updatesFilename, array_export( $this->updates, "updates" ) );
               
                return $returnval;
        }
       
        /**
        * Checks wether the user is subscribed to a globalID
        *
        * @param     username       The user id to check subscription for
        * @param     globalID       The globalID to check subscription for
        *
        * @return    bool           Wether the user is subscribed
        */

        function isSubscribed( $username, $globalID )
        {
                if( array_key_exists( $globalID, $this->subscriptions ) )
                        if( array_key_exists( $username, $this->subscriptions[$globalID] ) )
                                return true;
               
                return false;
        }
       
        /**
        * Check wether the user is subscribed to the parent
        *
        * @param     username       The user id of the user to check
        * @param     globalID       The globalID to check the parent of
        *
        * @return    bool           Returns true if the parent is subscribed to
        */

        function parentSubscribed( $username, $globalID )
        {
                if( $globalID == "" )
                        return false;
               
                $parentID = substr( $globalID, 0, strrpos( $globalID, "/" ) );
                if( $this->isSubscribed( $username, $parentID ) )
                        return true;
               
                return $this->parentSubscribed( $username, $parentID );
        }
       
        /**
        * Subscribe the user username to an item with the global ID globalID
        *
        * @param     username       The user id of the user who wishes to subscribe
        * @param     globalID       The global ID of the item the user wishes to subscribe to
        * @param     subscriptiontype Optional. The type of subscription. If nothing is defined, default is email subscription
        *
        * @return    bool           Wether the subscription succeeded or not
        */

        function subscribe( $username, $globalID, $subscriptiontype = "email" )
        {
                $returnval = false;
                if( $this->lock() )
                {
                        $this->load();
                        $this->subscriptions[$globalID][$username][$subscriptiontype] = true;
                        $returnval = $this->save();
                        $this->unlock();
                }
                return $returnval;
        }
       
        /**
        * Removes the user username's subscription to an item with the global ID globalID
        *
        * @param     username       The user id of the user who wishes to unsubscribe
        * @param     globalID       The global ID of the item the user wishes to subscribe to
        * @param     subscriptiontype The type of subscription. If undefined, all subscriptions
        *                           for this user will be removed for this globalID
        *
        * @return    bool           Wether the information was successfully unsubscribed
        */

        function unsubscribe( $username, $globalID, $subscriptiontype = "" )
        {
                $returnval = false;
                if( $this->lock() )
                {
                        if( $subscriptiontype == "" )
                                unset( $this->subscriptions[$globalID][$username] );
                        else
                                unset( $this->subscriptions[$globalID][$username][$subscriptiontype] );
                       
                        foreach( $this->subscriptions as $globalID => $value )
                        {
                                if( count( $value ) < 1 )
                                        unset( $this->subscriptions[$globalID] );
                        }
                        $returnval = $this->save();
                        $this->unlock();
                }
               
                return $returnval;
        }
       
        /**
        * Clears all subscriptions from user username
        *
        * @param     username       The username you wish to remove all subscriptions from
        *
        * @return    bool           Wether
        */

        function unsubscribeAll( $username )
        {
                $returnval = false;
                if( $this->lock() )
                {
                        foreach( $this->subscriptions as $key => $value )
                        {
                                if( array_key_exists( $username, $value ) )
                                        unset( $this->subscriptions[$key][$username] );
                        }
                        $returnval = $this->save();
                        $this->unlock();
                }
                return $returnval;
        }
       
        /**
        * Lists all subscriptions for the user username
        *
        * @param     username       The user id of the user you wish to receive a list of subscriptions for
        *
        * @return    array          An array containing the global IDs for all the user username's subscribed items, in the format [globalID][subscriptiontype]
        */

        function listUserSubscriptions( $username )
        {
                $theSubscriptions = array();
               
                foreach( $this->subscriptions as $key => $value )
                {
                        if( array_key_exists( $username, $value ) )
                        {
                                foreach( $value[$username] as $subscriptiontype => $irrelevant )
                                {
                                        $theSubscriptions[$globalID][] = $subscriptiontype;
                                }
                        }
                }
               
                return $theSubscriptions;
        }
       
        /**
        * Renames a globalID
        *
        * @param    renameFrom      The existing globalID name
        * @param    renameTo        The new name of the global ID
        *
        * @return   bool            Wether the renaming was successful
        */

        function renameGlobalID( $renameFrom, $renameTo )
        {
                $returnval = false;
                if( $this->lock() )
                {
                        $this->load();
                       
                        if( array_key_exists( $renameFrom, $this->subscriptions ) )
                        {
                                $tempSubscriptions = $this->subscriptions[$renameFrom];
                                unset( $this->subscriptions[$renameFrom] );
                                $this->subscriptions[$renameTo] = $tempSubscriptions;
                        }
                       
                        foreach( $this->updates as $key => $value )
                                if( $value["globalID"] == $renameFrom )
                                        $this->updates[$key]["globalID"] = $renameTo;
                       
                        $returnval = $this->save();
                        $this->unlock();
                }
                return $returnval;
        }
       
        /**
        * Remove a globalID, optionally notifying all users of the removal
        *
        * @param     globalID       The globalID to remove everything of
        * @param     notify         Wether to notify users of the removal - if it is undefined, no message is sent, otherwise, if it is a string, that string is sent as a message to all the subscribed users
        *
        * @return    bool           Wether the removal was successful
        */

        function removeGlobalID( $globalID, $notify = false )
        {
                $returnval = false;
                if( $this->lock() )
                {
                        if( is_string( $notify ) )
                        {
                                foreach( $this->subscriptions[$globalID] as $username => $user )
                                {
                                        foreach( $user as $subscriptiontype => $irrelevant )
                                                sendMessage( $username, i18n("Subscription item removed"), i18n("The item ##0## has been removed, and your subscription removed. Message as follows: ##1##", array( $globalID, $notify ) ), "admin", $subscriptiontype );
                                }
                        }
                       
                        unset( $this->subscriptions[$globalID] );
                       
                        foreach( $this->updates as $key => $value )
                                if( $value["globalID"] == $globalID )
                                        unset($this->updates[$key]);
                       
                        $returnval = $this->save();
                        $this->unlock();
                }
                return $returnval;
        }
       
        /**
        * Lists all users subscribed to an item with the global ID globalID
        *
        * @param     globalID       The global ID of the item you want all the users subscribed to
        *
        * @return    array          An array containing all the usernames of the users subscribed to the item with the global ID globalID
        */

        function listSubscribers( $globalID )
        {
                $theSubscribers = array();
               
                if( array_key_exists( $globalID, $this->subscriptions ) )
                {
                        foreach( $this->subscriptions[$globalID] as $username => $irellevant )
                                $theSubscribers[] = $username;
                }
               
                return $theSubscribers;
        }
       
        /**
        * Sends a message to all users subscribed to an item with the global ID globalID
        * This function should not be used, in stead use the handle function
        *
        * @param     globalID       The globalID to notify users of
        * @param     subject        The subject of the message you are sending
        * @param     message        The message to give to the users
        *
        * @return    bool           Wether the message was sent or not
        */

        function notifySubscribers( $globalID, $subject, $message )
        {
                $success = true;
               
                if( array_key_exists( $globalID, $this->subscriptions ) )
                {
                        foreach( $this->subscriptions[$globalID] as $username => $user )
                        {
                                foreach( $user as $subscriptiontype => $irrelevant )
                                        if( ! $this->parentSubscribed( $username, $globalID ) && ! sendMessage( $username, $subject, $message, "admin", $subscriptiontype ) )
                                                $success = false;
                        }
                }
               
                $parentID = substr( $globalID, 0, strrpos( $globalID, "/" ) );
                if( $parentID != "" )
                        $this->notifySubscribers( $parentID, $subject, $message );
               
                return $success;
        }
       
        /**
        * An event occured on the global ID globalID, optionally containing a subject and message
        *
        * @param     globalID       The global ID of the item that has had an event occur
        * @param     owner          Who owns the data being processed
        * @param     viewLevel      Who does the owner allow to view the data
        * @param     subject        Optional. The subject of the message to send about the globalID
        * @param     message        Optional. The message body
        *
        * @return    bool           Wether or not the messages were sent successfully
        */

        function handle( $globalID, $owner, $viewLevel, $subject = "", $message = "" )
        {
                $timestamp = time();
               
                if( $subject == "" )
                        $subject = i18n( "Update on ##0##", array( $globalID ) );
               
                if( $message == "" )
                        $message = i18n( "The item ##0## has been updated on ##1##", array( $globalID, formatTime( $timestamp ) ) );
               
                if( $this->lock() )
                {
                        $this->load();
                        $this->updates[] = array(
                                "timestamp" => $timestamp,
                                "globalID" => $globalID,
                                "subject" => $subject,
                                "message" => $message,
                                "owner" => $owner,
                                "viewLevel" => $viewLevel
                                );
                       
                        while( count( $this->updates ) > 10000 )
                                array_shift( $this->updates );
                       
                        $this->save();
                        $this->unlock();
                }
               
                return $this->notifySubscribers( $globalID, $subject, $message );
        }
       
        /**
        * Renders the command link for subscribing to a global ID
        *
        * @param     globalID       The global ID of the item to show a subscription command link for
        * @param     dataOnly       Optional, If true, return only the title, description and url in an array
        *                           This is used for example for making tabbar commands
        * @param     extraClass     Optional, Extra classes to add to the command
        *
        * @return    mixed          A string containing the rendered control, or an array containing the information
        */

        function renderSubscribeControl( $globalID, $dataOnly = false, $extraClass = "" )
        {
                if( $this->parentSubscribed( currentUser(), $globalID ) )
                        return "<span class=\"subscriptioncontrol command-disabled\">" . i18n("(Parent subscribed)") . "</span>";
                else
                {
                        if( $this->isSubscribed( currentUser(), $globalID ) )
                        {
                                $subscribe = "no";
                                $title = i18n("Unsubscribe");
                                $description = i18n("Unsubscribe from ##0##", array($globalID) );
                        }
                        else
                        {
                                $subscribe = "yes";
                                $title = i18n("Subscribe");
                                $description = i18n("Subscribe to ##0##", array($globalID) );
                        }
                       
                        $url = thisPageURL( false, true, array( "subscribe" => $subscribe ) );
                       
                        if( isAuth() )
                                $renderedControl = drawCommand( $title, $description, $url, $extraClass );
                       
                        return $dataOnly ? array( $title, $description, $url ) : "<span class=\"subscriptioncontrol\">" . $renderedControl . "</span>";
                }
        }
}
?>