Extension:Chat

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manual - list
Crystal Clear action run.png
Chat

Release status: beta

Implementation Skin
Description Adds a Chat tab to every article that links to an embedded chatroom by the same name.
Author(s) User:Firebreather
Last version 0.3.8 (2010-09-03)
MediaWiki tested with 1.15.1, not tested with 1.16, should work from 1.9.3 on, might work on 1.6.8
License LGPL
Download get WikiChat.php code below and phpfreechat from PhpFreeChat
Example http://WikiChat.org

Check usage (experimental)

Chat adds a Chat tab to every wiki Article that switches to an embedded chatroom with the same name as the article title. It can be configured to have only one chatroom for the entire site, rather than one chatroom per article (the default). This extension uses PhpFreeChat.

WikiChat.org has a demo, you are welcome to contribute.


Contents

[edit] Usage

Once the extension is installed, a 'chat' tab will appear on every article. Clicking on the chat tab will switch to an embedded chatroom for the article.

[edit] Prerequiste

You MUST be using MySQL as the MediaWiki database for this extension to work.

[edit] Installation

Quick start instructions are below.

Detailed instructions can be found here on WikiChat.org

Just five easy steps:-

1. Download PhpFreeChat 1.2 and follow the installation instructions to install it into your wiki somewhere. I have mine under /wiki/phpfreechat. (NOTE: You MUST download exactly phpfreechat 1.2)
2. Create a file called "WikiChat.php" in your wiki extensions directory and copy the WikiChat.php source code into it.
3. Modify the directory path at the top of WikiChat.php to point to your PhpFreeChat installation directory:-
define('WC_PFC_DIRECTORY', 'phpfreechat');
4. Add this line to the end of LocalSettings.php:-
include( "$IP/extensions/WikiChat.php" );
5. You might need to change the access permissions on some of the directories...
# Give the web server write rights to phpfreechat-x.x/data/public and 
phpfreechat-x.x/data/private directories.

If you are using FTP:

CHMOD 777 phpfreechat-x.x/data/private

CHMOD 777 phpfreechat-x.x/data/public

If you are using SSH:

chmod 777 phpfreechat-x.x/data/*

Its probably more sensible to use 755 than 777.

The chat function should be working now. Refresh your main page (or any page) and you should see a "chat" tab at the top. Click on the tab to start chatting.

Please report any issues to Firebreather or add them to the discussion for this extension.

[edit] Chat not loading?

If you are still having problems you may need to manually "rehash" the chat cache. Make sure to read this discussion. For an explanation of rehashing see this page.

You may also like to read the known issues.

[edit] Optional Parameters

Most of the optional parameters in WikiChat.php are parameters to PhpFreeChat. You need to refer to the PhpFreeChat documentation for information about how to change the PhpFreeChat parameters.

WikiChat optional parameters are detailed below...

[edit] Disabling Anonymous Access

Anonymous users are allowed access to the chatroom by default and assume the nickname 'Guest'

If you would like to deny access to anonymous users change the appropriate define statements at the top of WikiChat.php:

define('WC_ALLOW_ANNOYMOUS_USERS', false);

define('WC_DENY_ACCESS_MESSAGE', 'whatever you want displayed to the user when denied access');

[edit] Making all tabs point to one chatroom

The default setting is to open a new chatroom tab for each article, with the name of the article as the title of the chatroom. This is set by the following line in WikiChat.php

define('WC_ROOM_PER_ARTICLE', true);

If you would like to have all articles share one room then you need to change that line to:-

define('WC_ROOM_PER_ARTICLE', false);

All articles will now put users entering through the chat tab, into the single site-wide chatroom.

[edit] Help with chat commands

Detailed help is available on WikiChat.org

[edit] Known issues

  • Sometimes when entering the chatroom you get a message saying you are not allowed that nickname (because it is in use). This occurs because a user of that name is already in the chat room. Note that when a user closes their browser to leave a chatroom it takes a long time before their chat session ends. This is a limitation of browsers as there is no way catch a window close event for all browsers and automatically end the chat user's session.

[edit] ChangeLog

0.3.8, 2010-09-03

  • fixed bug where MYSQL returned error 1071 caused by the index being >1024 bytes. Keys sizes have been reduced in the chathistory table.

0.3.7, 2010-02-01

  • fixed bug where chat didn't work on subpages i.e. /wiki/index.php/Page/SubPage

0.3.6, 2010-01-26

  • changed it so that anonymous users can pick their nickname when they join the chat. Will make it a configurable option in the future so that anonymous users can optionally be assigned a fixed nickname as it was in previous versions e.g. 'Guest'.
  • fixed a bug where the deny access message wasn't displayed when WikiChat was configured to deny access to anonymous users.
  • put the following code back in as it is needed so that phpfreechat can find itself in wiki installations that are below the web root e.g. http://example.com/abc/def/wiki. Check the discussion page if you have this kind of wiki installation and WikiChat is not working.
$params["data_public_url"] = "$wgPFC_Directory/data/public";
$params["data_public_path"] = "$wgPFC_Directory/data/public";

0.3.4, 2010-01-22

  • fixed bug where chat wouldn't work properly for pages with a space in the title
  • fixed bug where anonymous users wouldn't be prevented from access when configured to deny them
  • chat logging is now going into the database
  • refactored the code to make it easier to maintain
  • changed user configuration options to use define statements like MediaWiki does
  • fixed small security hole

0.3.2, 2010-01-21

  • fixed page title
  • made room per article function configurable through a configuration variable
  • made configuration a tiny bit easier by adding the $wgPFC_Directory variable

0.3.0, 2010-01-20

  • updated the code to work with PhpFreeChat 1.2
  • fixed the issue where "Chat loading" is displayed but the chat never finishes loading.
  • tested and working on MediaWiki 1.15.1
  • new source code below
  • Firebreather 09:48, 20 January 2010 (UTC)

0.2.2, 2007-07-25

  • changed the default setting for the "timeout" parameter to increase the amount time before a user is disconnected. The default setting is ridiculously low.

0.2.1, 2007-07-03

  • upgraded WikiChat.php to be compatible with phpfreechat-1.0-beta11. It now won't work with earlier versions of phpfreechat. Phpfreechat-1.0-beta11 has lots of bug fixes and is more stable with Internet Explorer. If you were having problems with IE or other connectivity issues, this release should fix them.

0.2, 2007-06-06

  • fixed the html and page title so they are now there
  • added an option to disable anonymous user access and display a wikitext message instead
  • added a small message at the bottom to 'type /help for a list of all commands'

0.11

  • fixed two bugs that could blow up Special:Version page

0.1

  • first release

[edit] Source code

First check which version of MediaWiki you are using.

For releases prior to 1.16 use MediaWiki prior to 1.16.

For releases beginning with 1.16 use MediaWiki 1.16 and later.

[edit] MediaWiki prior to 1.16

Save WikiChat.php in the "extensions" directory.

<?php
/**
* MediaWiki WikiChat extension
* See: http://www.mediawiki.org/wiki/Extension:Chat for installation
* Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
* Author: http://www.wikichat.org/User:Firebreather
*/
 
#set to the directory phpfreechat is installed in
define('WC_PFC_DIRECTORY', 'phpfreechat');
 
# set to false to deny access to anonymous users
define('WC_ALLOW_ANONYMOUS_USERS', true);
 
# message shown when denying anonymous users. Change if you want a different message. WikiText ok..
define('WC_DENY_ACCESS_MESSAGE', 'You must [[Special:Userlogin|login]] to be allowed into this chatroom');
 
# when true there will be a chat room per article. Set to false to have a single site-wide chat room.
define('WC_ROOM_PER_ARTICLE', true);
 
if (!defined('MEDIAWIKI')) die ('Not an entry point');
 
$wgPFC_Directory = WC_PFC_DIRECTORY;
 
require_once "$IP/$wgPFC_Directory/src/phpfreechat.class.php";
require_once "$IP/includes/DatabaseFunctions.php";
 
$wgRoomPerArticle = WC_ROOM_PER_ARTICLE;
$wgAllowAnonUsers = WC_ALLOW_ANONYMOUS_USERS;
$wgDenyAccessMessage = WC_DENY_ACCESS_MESSAGE;
 
/* Extension variables */
$wgExtensionFunctions[] = 'wfSetupWikiChat';
$wgExtensionCredits['other'][] = array(
    'name' => 'WikiChat',
    'version' => '0.3.8, 2010-09-03',
    'author' => '[http://www.wikichat.org/User:Firebreather  User:Firebreather]',
    'url' => 'http://www.wikichat.org/',
    'description' => 'Adds a tab to each article that switches to a chatroom',
);              
 
class WikiChat {
 
        // Constructor
        public function WikiChat() {
                global $wgHooks;
 
                # Add all our needed hooks
                $wgHooks['UnknownAction'][] = $this;
                $wgHooks['SkinTemplateTabs'][] = $this;
        }
 
        // main entry point
        public function onUnknownAction($action, $article) {
                global $wgOut, $wgCachePages, $wgTitle, $wgDBprefix, $wgDenyAccessMessage;
 
                $wgCachePages = false;
 
                if($action == 'chat') {
                        $wgOut->setPageTitle(str_replace('_', ' ', $wgTitle->getDBKey()));
 
                        if($this->isAnonDenied()) {
                                $wgOut->addWikiText($wgDenyAccessMessage);
                                return false;
                        }
 
                        $params = $this->configurePFC_Params();
 
                        $tblname = $wgDBprefix."chathistory";
 
                        $this->createChatHistoryDBTable($tblname);
 
                        $this->configurePFC_DB_Params($tblname, $params);
 
                        $this->configureNick($params);
 
                        $this->showChat($params);
 
                        return false;
                }
                else {
                        return true;
                }
        }
 
        private function isAnonDenied() {
                global $wgUser, $wgAllowAnonUsers;
 
                return !$wgAllowAnonUsers && $wgUser->isAnon();
        }
 
        private function configureNick(&$params) {
                global $wgUser, $wgOut, $wgAllowAnonUsers, $wgDenyAccessMessage, $wgTitle;
 
                $nick = "";
 
                if($wgUser->isAnon()) {
                }
                else {
                        $nick = $wgUser->getName();
                }
 
                $params["nick"]          = $nick; // setup the initial nickname
 
                return $nick;
        }
 
        private function configurePFC_Params() {
                global $wgTitle, $wgRoomPerArticle, $wgPFC_Directory;
                global $wgOut;
 
                $params["title"]         = "WikiChat";
 
                // apply room per page or site-wide room configuration option
                if($wgRoomPerArticle) {
                        //replace slashes in the page db key to ensure chat works for subpages
                        $params["serverid"]      = str_replace('/', '##', $wgTitle->getDBKey());
                }
                else {
                        $params["serverid"]      = md5(__FILE__);
                }
 
                $params["data_public_url"] = "$wgPFC_Directory/data/public";
                $params["data_public_path"] = "$wgPFC_Directory/data/public";
 
                $params["server_script_url"] = $_SERVER['REQUEST_URI'];
                $params["openlinknewwindow"] = true;
                $params["channels"] = array(str_replace('_', ' ', $wgTitle->getDBKey()));
                $params["frozen_nick"]    = true;     // do not allow to change the nickname
                $params["shownotice"]     = 0;        // 0 = nothing, 1 = just nickname changes, 2 = connect/quit, 3 = nick + connect
                $params["max_nick_len"]   = 30;       // nickname length could not be longer than 10 caracteres
                $params["max_text_len"]   = 300;      // a message cannot be longer than 50 caracteres
                $params["max_channels"]   = 3;        // limit the number of joined channels tab to 3
                $params["max_privmsg"]    = 1;        // limit the number of private message tab to 1
                $params["refresh_delay"]  = 2000;    // chat refresh speed is 2 secondes (2000ms)
                $params["max_msg"]        = 30;       // max message in the history is 15 (message seen when reloading the chat)
                $params["height"]         = "230px";  // height of chat area is 230px
                $params["debug"]          = false;     // activate debug console
                $params["timeout"]        = 600000;   // msecs until user is disconnected
 
                return $params;
        }
 
        private function createChatHistoryDBTable($tblname) {
                $dbr =& wfGetDB( DB_SLAVE );
 
                $sql = "show tables like '$tblname'";
                $res = $dbr->query ( $sql ) ;
                $num_rows = $dbr->numRows($res) + 0;
                $dbr->freeResult( $res );
 
                //create the chathistory table if it doesn't exist
                if($num_rows == 0) {
                        $sql =
                          "CREATE TABLE IF NOT EXISTS `$tblname` (
                            `server` varchar(32) NOT NULL default '',
                            `group` varchar(64) NOT NULL default '',
                            `subgroup` varchar(64) NOT NULL default '',
                            `leaf` varchar(64) NOT NULL default '',
                            `leafvalue` text NOT NULL,
                            `timestamp` int(11) NOT NULL default 0,
                            PRIMARY KEY  (`server`,`group`,`subgroup`,`leaf`),
                            INDEX (`server`,`group`,`subgroup`,`timestamp`)
                          ) ENGINE=InnoDB;";
                        $ret = wfQuery($sql, DB_WRITE, "");
                }
        }
 
        private function configurePFC_DB_Params($tblname, &$params) {
                global $wgDBserver, $wgDBname, $wgDBprefix, $wgDBuser, $wgDBpassword;
 
                $params["container_type"]               = "mysql";
                $params["container_cfg_mysql_host"]     = $wgDBserver;
                $params["container_cfg_mysql_database"] = $wgDBname;
                $params["container_cfg_mysql_port"]     = 3306;
                $params["container_cfg_mysql_table"]    = $tblname;
                $params["container_cfg_mysql_username"] = $wgDBuser;
                $params["container_cfg_mysql_password"] = $wgDBpassword;
        }
 
        private function showChat($params) {
                global $wgOut;
 
                $pfc = new phpFreeChat($params);
                $wgOut->addHTML($pfc->printChat(true));
                $wgOut->addHTML('<br><br><p>Type /help for a list of all commands</p>');
                $wgOut->addWikiText("[http://www.wikichat.org/index.php/WikiChat_help More help on WikiChat.org]");
        }
 
       public function onSkinTemplateTabs( &$skin, &$content_actions ) {
                global $wgRequest;
 
                $action = $wgRequest->getText( 'action' );
 
                $content_actions['chat'] = array(
                                            'class' => ($action == 'chat') ? 'selected' : false,
                                            'text' => "chat",
                                            'href' => $skin->mTitle->getLocalURL( 'action=chat' )
                                             );
 
                return true;
        }
 
        # Needed in some versions to prevent Special:Version from breaking
        public function __toString() { return 'WikiChat'; }
 } /* class WikiChat */
 
/* Global function */
# Called from $wgExtensionFunctions array when initialising extensions
function wfSetupWikiChat() {
        global $wgWikiChat;
        $wgWikiChat = new WikiChat();
}
 
?>

[edit] MediaWiki 1.16 and later

Save WikiChat.php in the "extensions" directory.

<?php
/**
* MediaWiki WikiChat extension
* See: http://www.mediawiki.org/wiki/Extension:Chat for installation
* Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
* Author: http://www.wikichat.org/User:Firebreather
*/
 
#set to the directory phpfreechat is installed in
define('WC_PFC_DIRECTORY', 'phpfreechat');
 
# set to false to deny access to anonymous users
define('WC_ALLOW_ANONYMOUS_USERS', true);
 
# message shown when denying anonymous users. Change if you want a different message. WikiText ok..
define('WC_DENY_ACCESS_MESSAGE', 'You must [[Special:Userlogin|login]] to be allowed into this chatroom');
 
# when true there will be a chat room per article. Set to false to have a single site-wide chat room.
define('WC_ROOM_PER_ARTICLE', true);
 
if (!defined('MEDIAWIKI')) die ('Not an entry point');
 
$wgPFC_Directory = WC_PFC_DIRECTORY;
 
require_once "$IP/$wgPFC_Directory/src/phpfreechat.class.php";
require_once "$IP/includes/DatabaseFunctions.php";
 
$wgRoomPerArticle = WC_ROOM_PER_ARTICLE;
$wgAllowAnonUsers = WC_ALLOW_ANONYMOUS_USERS;
$wgDenyAccessMessage = WC_DENY_ACCESS_MESSAGE;
 
/* Extension variables */
$wgExtensionFunctions[] = 'wfSetupWikiChat';
$wgExtensionCredits['other'][] = array(
    'name' => 'WikiChat',
    'version' => '0.3.8, 2010-09-03, 1.16',
    'author' => '[http://www.wikichat.org/User:Firebreather  User:Firebreather]',
    'url' => 'http://www.wikichat.org/',
    'description' => 'Adds a tab to each article that switches to a chatroom',
);              
 
class WikiChat {
 
        // Constructor
        public function WikiChat() {
                global $wgHooks;
 
                # Add all our needed hooks
                $wgHooks['UnknownAction'][] = $this;
                $wgHooks['SkinTemplateTabs'][] = $this;
        }
 
        // main entry point
        public function onUnknownAction($action, $article) {
                global $wgOut, $wgCachePages, $wgTitle, $wgDBprefix, $wgDenyAccessMessage;
 
                $wgCachePages = false;
 
                if($action == 'chat') {
                        $wgOut->setPageTitle(str_replace('_', ' ', $wgTitle->getDBKey()));
 
                        if($this->isAnonDenied()) {
                                $wgOut->addWikiText($wgDenyAccessMessage);
                                return false;
                        }
 
                        $params = $this->configurePFC_Params();
 
                        $tblname = $wgDBprefix."chathistory";
 
                        $this->createChatHistoryDBTable($tblname);
 
                        $this->configurePFC_DB_Params($tblname, $params);
 
                        $this->configureNick($params);
 
                        $this->showChat($params);
 
                        return false;
                }
                else {
                        return true;
                }
        }
 
        private function isAnonDenied() {
                global $wgUser, $wgAllowAnonUsers;
 
                return !$wgAllowAnonUsers && $wgUser->isAnon();
        }
 
        private function configureNick(&$params) {
                global $wgUser, $wgOut, $wgAllowAnonUsers, $wgDenyAccessMessage, $wgTitle;
 
                $nick = "";
 
                if($wgUser->isAnon()) {
                }
                else {
                        $nick = $wgUser->getName();
                }
 
                $params["nick"]          = $nick; // setup the initial nickname
 
                return $nick;
        }
 
        private function configurePFC_Params() {
                global $wgTitle, $wgRoomPerArticle, $wgPFC_Directory;
                global $wgOut;
 
                $params["title"]         = "WikiChat";
 
                // apply room per page or site-wide room configuration option
                if($wgRoomPerArticle) {
                        //replace slashes in the page db key to ensure chat works for subpages
                        $params["serverid"]      = str_replace('/', '##', $wgTitle->getDBKey());
                }
                else {
                        $params["serverid"]      = md5(__FILE__);
                }
 
                $params["data_public_url"] = "$wgPFC_Directory/data/public";
                $params["data_public_path"] = "$wgPFC_Directory/data/public";
 
                $params["server_script_url"] = $_SERVER['REQUEST_URI'];
                $params["openlinknewwindow"] = true;
                $params["channels"] = array(str_replace('_', ' ', $wgTitle->getDBKey()));
                $params["frozen_nick"]    = true;     // do not allow to change the nickname
                $params["shownotice"]     = 0;        // 0 = nothing, 1 = just nickname changes, 2 = connect/quit, 3 = nick + connect
                $params["max_nick_len"]   = 30;       // nickname length could not be longer than 10 caracteres
                $params["max_text_len"]   = 300;      // a message cannot be longer than 50 caracteres
                $params["max_channels"]   = 3;        // limit the number of joined channels tab to 3
                $params["max_privmsg"]    = 1;        // limit the number of private message tab to 1
                $params["refresh_delay"]  = 2000;    // chat refresh speed is 2 secondes (2000ms)
                $params["max_msg"]        = 30;       // max message in the history is 15 (message seen when reloading the chat)
                $params["height"]         = "230px";  // height of chat area is 230px
                $params["debug"]          = false;     // activate debug console
                $params["timeout"]        = 600000;   // msecs until user is disconnected
 
                return $params;
        }
 
        private function createChatHistoryDBTable($tblname) {
                $dbr =& wfGetDB( DB_SLAVE );
 
                $sql = "show tables like '$tblname'";
                $res = $dbr->query ( $sql ) ;
                $num_rows = $dbr->numRows($res) + 0;
                $dbr->freeResult( $res );
 
                //create the chathistory table if it doesn't exist
                if($num_rows == 0) {
                        $sql =
                          "CREATE TABLE IF NOT EXISTS `$tblname` (
                            `server` varchar(32) NOT NULL default '',
                            `group` varchar(64) NOT NULL default '',
                            `subgroup` varchar(64) NOT NULL default '',
                            `leaf` varchar(64) NOT NULL default '',
                            `leafvalue` text NOT NULL,
                            `timestamp` int(11) NOT NULL default 0,
                            PRIMARY KEY  (`server`,`group`,`subgroup`,`leaf`),
                            INDEX (`server`,`group`,`subgroup`,`timestamp`)
                          ) ENGINE=InnoDB;";
                        $ret = wfQuery($sql, DB_WRITE, "");
                }
        }
 
        private function configurePFC_DB_Params($tblname, &$params) {
                global $wgDBserver, $wgDBname, $wgDBprefix, $wgDBuser, $wgDBpassword;
 
                $params["container_type"]               = "mysql";
                $params["container_cfg_mysql_host"]     = $wgDBserver;
                $params["container_cfg_mysql_database"] = $wgDBname;
                $params["container_cfg_mysql_port"]     = 3306;
                $params["container_cfg_mysql_table"]    = $tblname;
                $params["container_cfg_mysql_username"] = $wgDBuser;
                $params["container_cfg_mysql_password"] = $wgDBpassword;
        }
 
        private function showChat($params) {
                global $wgOut;
 
                $pfc = new phpFreeChat($params);
                $wgOut->addHTML($pfc->printChat(true));
                $wgOut->addHTML('<br><br><p>Type /help for a list of all commands</p>');
                $wgOut->addWikiText("[http://www.wikichat.org/index.php/WikiChat_help More help on WikiChat.org]");
        }
 
       public function onSkinTemplateTabs( $skin, &$content_actions ) {
                global $wgRequest;
 
                $action = $wgRequest->getText( 'action' );
 
                $content_actions['chat'] = array(
                                            'class' => ($action == 'chat') ? 'selected' : false,
                                            'text' => "chat",
                                            'href' => $skin->mTitle->getLocalURL( 'action=chat' )
                                             );
 
                return true;
        }
 
        # Needed in some versions to prevent Special:Version from breaking
        public function __toString() { return 'WikiChat'; }
 } /* class WikiChat */
 
/* Global function */
# Called from $wgExtensionFunctions array when initialising extensions
function wfSetupWikiChat() {
        global $wgWikiChat;
        $wgWikiChat = new WikiChat();
}
 
?>

[edit] Site List

Please add your wiki to the site list so we can visit you to see how you're using WikiChat and how to improve it. We'll also put a link to your wiki on the front page of WikiChat.org.

[edit] See also

Personal tools
Namespaces
Variants
Actions
Site
Support
Download
Development
Communication
Print/export
Toolbox