Wiki source for RyeBreadDraftsEventNotification


Show raw source

===== Event Notification Handler =====

<<[[Ticket:56]]<<

Believe it or not, I wrote this code before I found out about PageWatches but I think my approach is a little different.

Basically, I wanted something that would email people in my office whenever somebody posted a comment on a page of interest. I thought I would make it a little more robust however. This should be a framework that will allow wikka to automatically react to a variety of page events (i.e. commenting a page, editing a page etc) and trigger some response (i.e. emailing a user, sending an http request to a server etc.)

This isn't finished, yet it is currently running in my office, so I know it works.

Steps:
1) Create new event watching table.
1) Create a handler to register an event for a page to watch.
1) Create a response function (i.e. email notification).
1) Add code to look for and process a page event. Then call a response function.
1) Make handler easily accessible for users.

===== 1.) Create Table =====

%%(sql)
CREATE TABLE `wikka_watches` (
`page_tag` VARCHAR(75) NOT NULL,
`watcher` VARCHAR(75) NOT NULL,
`comment` ENUM('Y','N') DEFAULT 'N' NOT NULL,
`edit` ENUM('Y','N') DEFAULT 'N' NOT NULL
)
TYPE = myisam;

ALTER TABLE `wikka_watches` ADD UNIQUE (`page_tag`,`watcher`)

ALTER TABLE `wikka_watches` ADD INDEX (`page_tag`)

ALTER TABLE `wikka_watches` ADD INDEX (`watcher`)
%%

This will create a table that will store a page_tag and watcher pair. The watcher isn't restricted to being a username. It could be the name of a wikipingserver or something like that. Each column after that corresponds to a particular page event with a simple indication of whether or not that event is being watched for.

===== 2.) Create 'addwatch' handler =====

Create a file called addwatch.php in your handlers directory. Add this code:

%%(php)
<?php

/**
* Creates a watch on this page for a watcher.
*
* Usage: append /addwatch to the URL of the page
*
* This handler registers a watch in the database on this page
* for a watcher. Watches can be used to generate events when
* certain things are done to a page. (i.e. email a user when a page
* is commented on.)
*
* @package Handlers
* @subpackage
* @name addwatch
*
* @author {@link http://wikka.jsnx.com/RyeBread RyeBread} - original idea and code - Dec.06.2005
* @copyright Copyright © 2005, Ryan Jarvis
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @version 0.1
* @since Wikka 1.1.6.X
*
* @todo
* 1. Allow handler to take in params specifying what kind of watch should be made
* 2. Enable setting of watcher that isn't a user (i.e. a wikiping server).
*/

do {

if (!$this->page) {
$this->SetRedirectMessage("Found no page for this handler.");
break;
}

if (!$this->GetUser()) {
$this->SetRedirectMessage("You must be registered to add a watch.");
break;
}

//TODO: get type of watch from a param
//passed into the handler.
//
//get type of watch
$type = "comment";

//check if watch type is valid
$validity = $this->Query("SHOW COLUMNS FROM " . $this->config["table_prefix"] . "watches LIKE '" . $type . "'");
if (mysql_num_rows($validity) == 0) {
$this->SetRedirectMessage("Watch type is invalid.");
break;
}

//get page name
$tag = $this->GetPageTag();

//TODO: optionally specify the id of the
//watcher instead of assuming user name.
//
//get watcher
$watcher = $this->GetUserName();

//register watch in database
$existing = $this->Query(
"SELECT * FROM " . $this->config["table_prefix"] . "watches " .
"WHERE page_tag = '" . mysql_real_escape_string($tag) . "'" .
"AND watcher = '" . mysql_real_escape_string($watcher) . "'");

if (mysql_num_rows($existing) == 0 ) {
$this->Query(
"INSERT INTO " . $this->config["table_prefix"] . "watches SET ".
"page_tag = '" . mysql_real_escape_string($tag) . "', " .
"watcher = '" . mysql_real_escape_string($watcher) . "', " .
$type . " = 'Y'");

$this->SetRedirectMessage("You are now watching this page for " . $type . "s.");
break;
}

if (mysql_result($existing, 0, $type) == 'Y') {
$this->SetRedirectMessage("You are already watching this page for " . $type . "s.");
} else {
$this->Query(
"UPDATE " . $this->config["table_prefix"] . "watches SET ".
"page_tag = '" . mysql_real_escape_string($tag) . "', " .
"watcher = '" . mysql_real_escape_string($watcher) . "', " .
$type . " = 'Y'");
$this->SetRedirectMessage("You are now watching this page for " . $type . "s.");
}

mysql_free_result($existing);

} while (0);

$this->Redirect($this->Href());

?>
%%

As it stands right now, when a registered user invokes this handler on a page, the wikka_watches table will be updated to indicate that this user wants to be notified whenever this page is commented on.

===== 3.) Create 'notify' base function =====

In wikka.php, I added this function at line 972 before MAINTENANCE

%%(php)
//COMMUNICATION
function Notify($to = "", $subject = "", $body = "", $altbody = "")
{
<insert your specific mailing code here>
}
%%

Obviously, how you send mail is dependent on your server setup. I don't use the default mail() function. Instead, I have phpmailer setup, and I use it on an SMTP configuration. If somebody wants to see what I wrote for this function that uses phpmailer, let me know.

Also, it should probably be called '""NotifyOnEmail""' as there might be additional notify functions created that belong to this family.

===== 4.) Invoke Event Processing somewhere =====

Keeping in mind that I want people to be notified of comments made on pages, I decided to invoke the event processing in the 'addcomment.php' action.

Firstly, I have no idea if this is the best place for it to go (as opposed to being added directly in the ""SaveComment()"" function). Secondly, there needs to be a generic event-processing-wrapper of some kind that takes a callback function (such as notify) as a parameter. I'm working on that.

Add the following to 'addcomment.php', line 18, right after STORE NEW COMMENT

%%(php)
//trigger watches
$watches_table = $this->config["table_prefix"] . "watches";
$users_table = $this->config["table_prefix"] . "users";
$watch_query = "SELECT " . $users_table . ".email " .
"FROM " . $watches_table . "," . $users_table . " " .
"WHERE " . $watches_table . ".page_tag = '" . $this->tag . "' " .
"AND " . $watches_table . ".watcher = " . $users_table . ".name";
$watches = $this->LoadAll($watch_query);
foreach ($watches as $email) {
if ($email["email"] == '') {
continue;
}

$this->Notify($email["email"], $this->tag . " commented by " . $this->GetUserName(), $body);

}
%%

===== 5.) Make handler visible =====

Obviously, I want to make it easy for my users to add watches, so I just hacked the following. It adds a link to the footer.

Add the following to footer.php, line 5 after the 'Edit Page'

%%(php)
echo $this->GetUser() ? "<a href=\"".$this->href("addwatch")."\" title=\"Click to watch this page\">Watch page</a> ::\n" : "";
%%

Now I don't really want to hack footer directly, plus, I want to be able to support adding watches of different types, so I need to eventually construct a separate menu altogether.

~& How about a ""{{watch}}"" action instead? --NilsLindenberg

===== Conclusion =====

Whenever a user in my wiki comes across a particular page of interest, he or she can click on the "Watch page" link at the bottom, and it will record the request to be notified. Thereafter, whenever somebody leaves a comment on that page, the user will receive an email containing the comment in the body of the message.

===== TODO: =====

- Create an "removewatch" handler.
- Create a form in the user settings page that will allow people to manage their watches and add/remove/edit at will.

Comments/feedback highly desired. Thank you.
:)

----
CategoryUserContributions
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki