WikiPageWatch
By Chumang Sango 2009 for V1.1.6.2
Ported IanHayhurst 2018 for V1.3.7 pluginsystem
postfix/sendmail[29013]: fatal: open /etc/postfix/main.cf: Permission denied
Fix with:
Ported IanHayhurst 2018 for V1.3.7 pluginsystem
ToDo:
- code assumes table prefix wikka_ in parts and needs $prefix = $this->GetConfigValue('table_prefix'); inserting in some of the sql
- Functions in Wikka.class.php not really in a plugin friendly place not sure what best practice should be here
Troubleshooting:
SELinux Http can't send mail
var/log/maillog shows:postfix/sendmail[29013]: fatal: open /etc/postfix/main.cf: Permission denied
Fix with:
setsebool -P httpd_can_sendmail=1
Yet another email notification plugin allows users to watch / unwatch a page by opting in or out of email notification for page changes or comments. Uses an additional table to track pages and watchers. I'm including it here as I modified the original work by Chumang Sango to use the plugin system.
Files Added / Modified
WikiRoot
|-- libs
| \-- Wakka.class.php
|-- plugins
|-- actions
| |-- watchlink
| \-- watchlink.php
|-- config
| \-- options_menu.inc
| |-- options_menu.user.inc
| |-- options_menu.admin.inc
|-- handlers
\-- addcomment
| \--addcomment.php
|--edit
| \-- edit.php
|--pagewatch
| \--pagewatch.php
|-- unpagewatch
\-- unpagewatch.php
Database
A new table was added to the underlying database. The table name is wikka_page_watch and it will serve as the watch list. The structure of the table is shown below:Field | Type | Null |
---|---|---|
page_tag | VARCHAR(75) | No |
user_name | VARCHAR(75) | No |
The PRIMARY key for the table is a combination of page_tag and user_name. Examples of page_tag values include WelcomePage, RecentChanges, etc. Examples of user_name values include JohnSmith, JohnDoe, etc. When a user subscribes to a page, his name and the tag of the page will be added to this table. The opposite happens when a user decides to unsubscribe.
My table Prefix was wikka_ The table is referred to in the code
CREATE TABLE 'wikka_page_watch' (
'page_tag' varchar(75) NOT NULL,
'user_name' varchar(75) NOT NULL,
PRIMARY KEY ('page_tag','user_name') )
ENGINE=MyISAM DEFAULT CHARSET utf8 COLLATE utf8_unicode_ci;
'page_tag' varchar(75) NOT NULL,
'user_name' varchar(75) NOT NULL,
PRIMARY KEY ('page_tag','user_name') )
ENGINE=MyISAM DEFAULT CHARSET utf8 COLLATE utf8_unicode_ci;
Functions
Two new functions are added to the Wakka.Class.php file. These functions are :WatchWiki ( ): This function constructs a module that will be displayed on a wiki page. This module has a link in it which will allow a user to watch the page (if the user does not already exist in the watch list of the page), or to stop watching a page (if the user is already watching the page). altered just to return bool if page is watched or not
NotifyWatchers ($tag, $type=''): This function will send out an email message to all users that are on the watch list of a page when a change is made on the page. The $tag parameter is used to specify the tag of the page whose watchers need to be notified. The $type parameter is used to specify the type of notification. There are currently two types of notification – ‘comment’ (used when a new comment is made on a page) and ‘edit’ (used when page content is changed). The $type parameter is option, and a generic change message will be generated if it is not specified.
Append the following functions to wikiroot/libs/Wakka.class.php just before the final closing } (which you can delete as it is included in the insert )
AppendTo-Wakka.class.php
/**
* Function to produce a module that allows a user to watch/unwatch a wiki.
* Watching a wiki involves subscribing to receive email notifications when
* the wiki changes i.e. page edits and comments
*
* @name WatchWiki
* @param None
* @author <chumang.sango@syngenta.com> Chumang Sango
* @access public
* @return string
* @version 0.0.2 Beta
*
* History
* ---------------------------------------------------------------------
* Date | Changed By | Description
* ---------------------------------------------------------------------
* 09/12/2009 | C.Sango | Created
* 12/07/2018 | I.Hayhurst | Return changed to bool. Handler redirect moved to watchlink menu action
*
*/
function WatchWiki()
{
$user = $this->GetUserName();
$tag = $this->GetPageTag();
$url = $this->Href();
$table = "page_watch";
$where = "user_name = '".$user."'
and page_tag = '".$tag."' ";
$count = $this->getCount($table, $where);
if($count == 0) {return false;}
else {return true;}
}
/**
* Function to send an email to the list of all the users watching a particular wiki
* This function should be used in handlers and actions that modify a page i.e. page edits and comments
*
* @name NotifyWatchers
* @@param string $tag The tag of the page whose watchers you want to notify
* @author <chumang.sango@syngenta.com> Chumang Sango
* @access public
* @version 0.0.1 Beta
* @@return void
*
* History
* ---------------------------------------------------------------------
* Date | Changed By | Description
* ---------------------------------------------------------------------
* 09/12/2009 | C.Sango | Created
* 15/12/2009 | C.Sango | Added code to set sender's email
*/
function NotifyWatchers($tag, $type=''){
$url = $this->Href();
$subject = "WikiWatch Alert for $tag";
// Load the email of the person sending the email
$senderQuery = "
select u.email
from wikka_users u
where u.name = '".$this->GetUserName()."'";
$res = $this->LoadSingle($senderQuery);
$sender = $res['email'];
// construct email message based on change type
switch($type){
case 'comment': {
$message = '
<div id="mail" style="font-family: Calibri;">
<p> Hi </p>
<p>
<span style="width: 100%"> A new comment was made on the <strong>'.$tag.'</strong> wiki.</span>
<span> Follow the link below to view it. </span>
</p>
<p> '.$url.'</p>
</div>';
break;
}
case 'edit': {
$message = '
<div id="mail" style="font-family: Calibri;">
<p> Hi </p>
<p>
<span> The wiki page <strong>'.$tag.'</strong> has been recently edited. </br></span>
<span> Follow the link below to view the new content. </span>
</p>
<p> '.$url.'</p>
</div>';
break;
}
default: {
$message = '
<div id="mail" style="font-family: Calibri;">
<p> Hi </p>
<p>
<span> Content on the <strong>'.$tag.'</strong> wiki has been recently updated. </br></span>
<span> Follow the link below to view it. </span>
</p>
<p> '.$url.'</p>
</div>';
}
}
// select watch list of page from database
$watchListQuery = "
select u.email
from wikka_users u,
wikka_page_watch w
where w.user_name = u.name
and w.page_tag = '".$tag."' ";
$result = $this->LoadAll($watchListQuery);
// send email to list
for ($i = 0; $i < sizeof($result); ++$i) {
$email = $result[$i]['email'];
$headers = "From: WikiWatch <$sender>\r\n";
$headers .= "Content-type: text/html\r\n";
mail($email, $subject, $message, $headers);
}
}
}
?>
* Function to produce a module that allows a user to watch/unwatch a wiki.
* Watching a wiki involves subscribing to receive email notifications when
* the wiki changes i.e. page edits and comments
*
* @name WatchWiki
* @param None
* @author <chumang.sango@syngenta.com> Chumang Sango
* @access public
* @return string
* @version 0.0.2 Beta
*
* History
* ---------------------------------------------------------------------
* Date | Changed By | Description
* ---------------------------------------------------------------------
* 09/12/2009 | C.Sango | Created
* 12/07/2018 | I.Hayhurst | Return changed to bool. Handler redirect moved to watchlink menu action
*
*/
function WatchWiki()
{
$user = $this->GetUserName();
$tag = $this->GetPageTag();
$url = $this->Href();
$table = "page_watch";
$where = "user_name = '".$user."'
and page_tag = '".$tag."' ";
$count = $this->getCount($table, $where);
if($count == 0) {return false;}
else {return true;}
}
/**
* Function to send an email to the list of all the users watching a particular wiki
* This function should be used in handlers and actions that modify a page i.e. page edits and comments
*
* @name NotifyWatchers
* @@param string $tag The tag of the page whose watchers you want to notify
* @author <chumang.sango@syngenta.com> Chumang Sango
* @access public
* @version 0.0.1 Beta
* @@return void
*
* History
* ---------------------------------------------------------------------
* Date | Changed By | Description
* ---------------------------------------------------------------------
* 09/12/2009 | C.Sango | Created
* 15/12/2009 | C.Sango | Added code to set sender's email
*/
function NotifyWatchers($tag, $type=''){
$url = $this->Href();
$subject = "WikiWatch Alert for $tag";
// Load the email of the person sending the email
$senderQuery = "
select u.email
from wikka_users u
where u.name = '".$this->GetUserName()."'";
$res = $this->LoadSingle($senderQuery);
$sender = $res['email'];
// construct email message based on change type
switch($type){
case 'comment': {
$message = '
<div id="mail" style="font-family: Calibri;">
<p> Hi </p>
<p>
<span style="width: 100%"> A new comment was made on the <strong>'.$tag.'</strong> wiki.</span>
<span> Follow the link below to view it. </span>
</p>
<p> '.$url.'</p>
</div>';
break;
}
case 'edit': {
$message = '
<div id="mail" style="font-family: Calibri;">
<p> Hi </p>
<p>
<span> The wiki page <strong>'.$tag.'</strong> has been recently edited. </br></span>
<span> Follow the link below to view the new content. </span>
</p>
<p> '.$url.'</p>
</div>';
break;
}
default: {
$message = '
<div id="mail" style="font-family: Calibri;">
<p> Hi </p>
<p>
<span> Content on the <strong>'.$tag.'</strong> wiki has been recently updated. </br></span>
<span> Follow the link below to view it. </span>
</p>
<p> '.$url.'</p>
</div>';
}
}
// select watch list of page from database
$watchListQuery = "
select u.email
from wikka_users u,
wikka_page_watch w
where w.user_name = u.name
and w.page_tag = '".$tag."' ";
$result = $this->LoadAll($watchListQuery);
// send email to list
for ($i = 0; $i < sizeof($result); ++$i) {
$email = $result[$i]['email'];
$headers = "From: WikiWatch <$sender>\r\n";
$headers .= "Content-type: text/html\r\n";
mail($email, $subject, $message, $headers);
}
}
}
?>
Plugin Integration
- Enable wiki for use of plugins detailed here: InstallingPlugins
- This will make wiki check the plugin version of any action / handler etc. before the supplied one
Actions
- Add menulet action to the wikiroot/plugin/actions/watchlink/watchlink.php
- Displays Watch Page link or Un Watch page as appropriate
watchlink.php
/**
* Watch / Unwatch link menulet
*
* Displays a link to watch / unwatch the current page (depending on user privileges).
*
* Syntax: {{watchlink}}
*
* @package Actions
* @subpackage Menulets
* @name Watch link
*
* @author {@link Chumang Sango, Ian Hayhurst}
*/
if ($this->WatchWiki()){
echo '<a href="'.$this->Href('unpagewatch').'" title="'.T_("Click to stop receiving email on page edits or comments").'">'.T_("[Unwatch this page]").'</a>'; #i18n
}
else {
echo '<a href="'.$this->Href('pagewatch').'" title="'.T_("Click to receive email on page edits or comments").'">'.T_("[Watch this page]").'</a>'; #i18n
}
?>
* Watch / Unwatch link menulet
*
* Displays a link to watch / unwatch the current page (depending on user privileges).
*
* Syntax: {{watchlink}}
*
* @package Actions
* @subpackage Menulets
* @name Watch link
*
* @author {@link Chumang Sango, Ian Hayhurst}
*/
if ($this->WatchWiki()){
echo '<a href="'.$this->Href('unpagewatch').'" title="'.T_("Click to stop receiving email on page edits or comments").'">'.T_("[Unwatch this page]").'</a>'; #i18n
}
else {
echo '<a href="'.$this->Href('pagewatch').'" title="'.T_("Click to receive email on page edits or comments").'">'.T_("[Watch this page]").'</a>'; #i18n
}
?>
Config
- Add menu action {{watchlink}} to wikiroot/plugin/config/option_menu.inc, option_menu.user.inc and option_menu.admin.inc Which need to be copied fromwikiroot/config/ to wikiroot/plugin/config
Handlers
The addcomment.php and edit.php handlers are modified to include a call to the Notify Watchers function of the main class. This is necessary to ensure that watchers are notified of changes the moment they are made.- Copy file from wikiroot/handlers/addcomment/addcomment.php to wikiroot/plugin/handlers/addcomment/addcomment.php
- Copy file from wikiroot/handlers/edit/edit.php to wikiroot/plugin/handlers/edit/edit.php
- Edit the plugin version of addcomment.php to include our notify line $this->NotifyWatchers($this->tag, 'comment'); at the point where the comment is ready to be stored (about line 58)
addcomment.php (line 53)
- // all is kosher: store new comment
- else
- {
- $this->SaveComment($this->GetPageTag(), $body, $parent_id);
- // notify watchers of new content
- $this->NotifyWatchers($this->tag, 'comment');
- }
- Edit the plugin version of editt.php to include our notify line $this->NotifyWatchers($this->tag, 'edit');
edit.php (line 138)
- {
- // only save if new body differs from old body
- if ($body != $this->page['body']) {
- // add page (revisions)
- $this->SavePage($this->GetPageTag(), $body, $note);
- // now we render it internally so we can write the updated link table.
- // if we no longer do link tracking for header and footer why are we creating dummy output?
- $this->ClearLinkTable();
- $this->StartLinkTracking();
- $dummy .= $this->Format($body);
- $this->StopLinkTracking();
- $dummy .= $this->Footer(); // @@@
- $this->WriteLinkTable();
- $this->ClearLinkTable();
- }
- // notify page watchers of recent change
- $this->NotifyWatchers($this->tag, 'edit');
- // forward
- $this->Redirect($this->Href());
- Create pagewatch.php in wikiroot/plugins/handlers/pagewatch
pagewatch.php
<?php
/**
* This handler will add the current user to the watch list for the
* page he is currently on
*
* @author <chumang.sango@syngenta.com>
*
* Date: 09 Decemeber 2009
* CHANGES
* 20180710 Ian M. Hayhurst wrap in check for logged on user
*/
$user = $this->GetUserName();
$tag = $this->GetPageTag();
$redirectmessage = "";
if ($this->GetUser())
{
$watch_cmd = "
insert into wikka_page_watch (user_name, page_tag)
values ('".$user."', '".$tag."') ";
$success = mysql_query($watch_cmd, $this->dblink);
$redirectmessage = "You are now watching this page.";
}
else
{$redirectmessage = "You need to be logged in!";
}
// redirect to parent page
$this->Redirect($this->Href(), $redirectmessage);
?>
/**
* This handler will add the current user to the watch list for the
* page he is currently on
*
* @author <chumang.sango@syngenta.com>
*
* Date: 09 Decemeber 2009
* CHANGES
* 20180710 Ian M. Hayhurst wrap in check for logged on user
*/
$user = $this->GetUserName();
$tag = $this->GetPageTag();
$redirectmessage = "";
if ($this->GetUser())
{
$watch_cmd = "
insert into wikka_page_watch (user_name, page_tag)
values ('".$user."', '".$tag."') ";
$success = mysql_query($watch_cmd, $this->dblink);
$redirectmessage = "You are now watching this page.";
}
else
{$redirectmessage = "You need to be logged in!";
}
// redirect to parent page
$this->Redirect($this->Href(), $redirectmessage);
?>
- Create upagewatch.php in wikiroot/plugins/handlers/unpagewatch
unpagewatch.php
<?php
/**
* This handler will remove the current user from the watch list for the
* page he is currently on
*
* @author <chumang.sango@syngenta.com>
*
* Date: 09 Decemeber 2009
*/
$user = $this->GetUserName();
$tag = $this->GetPageTag();
$redirectmessage = "";
$unwatch_cmd = "
delete from wikka_page_watch
where user_name = '".$user."'
and page_tag = '".$tag."' ";
$success = mysql_query($unwatch_cmd, $this->dblink);
$redirectmessage = "You are no longer watching this page.";
// redirect to parent page
$this->Redirect($this->Href(), $redirectmessage);
?>
/**
* This handler will remove the current user from the watch list for the
* page he is currently on
*
* @author <chumang.sango@syngenta.com>
*
* Date: 09 Decemeber 2009
*/
$user = $this->GetUserName();
$tag = $this->GetPageTag();
$redirectmessage = "";
$unwatch_cmd = "
delete from wikka_page_watch
where user_name = '".$user."'
and page_tag = '".$tag."' ";
$success = mysql_query($unwatch_cmd, $this->dblink);
$redirectmessage = "You are no longer watching this page.";
// redirect to parent page
$this->Redirect($this->Href(), $redirectmessage);
?>
CategoryUserContributions