I meant like another column in the user list that lists when each person was last online for quick glance instead of having to open everyone's profile individually.

I believe it uses prototype. You might try using jquery in a kind of "safe mode" using the jQuery(); function instead of the shortcut $(); which both prototype and jquery use (i think).

I'll also look into modifying it a bit more to be compatible with other libraries.

http://docs.jquery.com/Using_jQuery_wit … _Libraries

I modified the extension some more to make it validate as XHTML 1.0 Strict and added a send button.

I'm currently working on getting an admin backend added onto it so you can set some options so until I finish that, the previous modifications I've done aren't included.

Modified chatlite:ChatLite 0.6.0

Let me know if you find anything wrong with it as I'm still kind of a novice at this.

54

(6 replies, posted in PunBB 1.3 extensions)

You've got a couple xhtml validation errors on line 46 of the manifest.xml (in the adm version, I haven't checked the other but I assume it's close to the same line).

You need to change the ampersands from & to & like this:

$stats_list['newest_user'] = '<li class="st-users"><span>'.sprintf($lang_index['Newest user'], '<strong>'.($forum_user['g_view_users'] == '1' ? '<a href="'.forum_link($forum_url['user'], $stats['last_user']['id']).'">'.forum_htmlencode($stats['last_user']['username']).'</a></strong>&nbsp;&nbsp;&nbsp;<a href="userlist.php?username=&amp;show_group=-1&amp;sort_by=registered&amp;sort_dir=DESC">('.$lang_show_last_registered['Show more'].')</a>' : forum_htmlencode($stats['last_user']['username']).'</strong>')).'</span></li>';

After that, it should validate.

I've modified the extension very slightly to include/remove some things that I needed and I thought I'd post it here for anyone else who needed it.

I've modified it to add the chat to every page. Next, I removed it from showing up for anyone not logged in. Lastly, I removed it from showing up for the default group that everyone is put in when they first register, making it only show up for people you move out of that group and that are logged in.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE extension SYSTEM "ext-1.0.dtd">

<!--
/**
 * ChatLite: Adds a javascript chat to the forum.
 * Please note the licence DOES NOT apply to prototype's framework supplied with this extension. 
 *
 * @author Neck - http://www.eikylon.net
 * @license Creative Commons Attribution 3.0 Unported - http://creativecommons.org/licenses/by/3.0/
 * @package ek_chatlite 
 */
-->

<extension engine="1.0">
    <id>ek_chatlite</id>
    <title>ChatLite</title>
    <version>0.5.1</version>
    <description>Adds a javascript chat to the forum index.</description>
    <author>Neck - http://www.eikylon.net</author>
    <minversion>1.3</minversion>
    <maxtestedon>1.3.2</maxtestedon>

    <install><![CDATA[

// check the PHP version
if(version_compare(PHP_VERSION, '5.2.1') === -1) {
    $notices[] = '<strong>ERROR !</strong> PHP 5.2.1 or superior required ('.PHP_VERSION.' found). This extension cannot be run on your server, please uninstall it.';
}
// check write access on some files
if(!is_writable($ext_info['path'].'/data/chat.dat') || !is_writable($ext_info['path'].'/data/.htaccess')) {
    $notices[] = '<strong>WARNING !</strong> Write access needed. Please give php the permission to write in <em>ek_chatlite/data/chat.dat</em> and <em>ek_chatlite/data/.htaccess</em> before running the chat.';
}

    ]]></install>

    <hooks>
        <hook id="hd_head" priority="4"><![CDATA[

// add javascript and style files on the Index

// The following line is commented out to add the chatbox to every page (including admin pages). Uncomment it (and the ending bracket) to put it back to only the index page
// if(FORUM_PAGE === 'index') {
if(!$forum_user['is_guest']) { // this will remove the chat for users that aren't logged in
    if($forum_user['g_id'] != $forum_config['o_default_user_group']) { // this removes the chat for the default group, but leaves it for every other group
        $forum_head['prototypejs'] = '<script type="text/javascript" src="'.$ext_info['url'].'/media/js/prototype.js"></script>';
        $forum_head['ek_chatlitejs'] = '<script type="text/javascript" src="'.$ext_info['url'].'/media/js/chat.js?logged='.(($forum_user['is_guest']) ? 0 :(($forum_user['is_admmod']) ? 2 : 1)).'&baseUri='.$base_url.'/&extUri='.$ext_info['url'].'/"></script>';

        if (file_exists($ext_info['path'].'/media/js/lang/'.$forum_user['language'].'.js')) {
            $forum_head['ek_chatlitelangjs'] = '<script type="text/javascript" src="'.$ext_info['url'].'/media/js/lang/'.$forum_user['language'].'.js"></script>';
        } else {
            $forum_head['ek_chatlitelangjs'] = '<script type="text/javascript" src="'.$ext_info['url'].'/media/js/lang/English.js"></script>';
        }

        $ek_chatlite_css = (file_exists($ext_info['path'].'/media/css/'.$forum_user['style'].'.css')) ? $forum_user['style'] : 'default';
        $forum_head['style_ek_chatlite'] = '<link rel="stylesheet" type="text/css" media="screen" href="'.$ext_info['url'].'/media/css/'.$ek_chatlite_css.'.css" />';
    } // comment out this bracket if you remove the default group portion above
} // comment out this bracket if you remove the guest (users not logged in) portion above
// } // removed to add chat to every page
        ]]></hook>
        
        <hook id="mi_new_action"><![CDATA[
        

if ($action == 'ek_chatlite') {
    // the file we work on
    $chatFile = $ext_info['path'].'/data/chat.dat';

    $do = (isset($_POST['do'])) ? $_POST['do'] : null;
    if($do === 'post') {
        date_default_timezone_set('UTC');
        $message = (isset($_POST['message'])) ? forum_trim($_POST['message']) : null;
    
        // check for guests or empty messages
        if($forum_user['is_guest'] == true) {
            header('HTTP/1.x 401 Unauthorized');
            exit();
        } else if (empty($message)) {
            header('HTTP/1.x 404 Not Found');
            exit();
        } else {
            // read chat's content
            $content = file_get_contents($chatFile);
            $content = (empty($content)) ? array() : json_decode($content);

            // prepare values
            $user = htmlspecialchars($forum_user['username']);
            $message = str_replace("\n", '<br />', htmlspecialchars($message));

            // check double message
            $last = end($content);
            if(!empty($last) && $last[1]===$user && $last[3]===$message) {
                header('HTTP/1.x 403 Forbidden');
                exit();
            }

            // add the new message
            $content[] = array(
                md5(uniqid(rand(), true)),
                $user,
                date('r'),
                $message
            );

            // remove if there's more than 50 messages
            while(count($content) >= 50) {
                array_shift($content);
            }

            // encode and write
            $content = json_encode($content);
            file_put_contents($chatFile, $content);
            // push the checksum
            $check = md5($content);
            $htaccess = file_get_contents($ext_info['path'].'/data/.htaccess');
            $htaccess = preg_replace('`X-json "\\\"\w{32}\\\""`', 'X-json "\"'.$check.'\""', $htaccess);
            file_put_contents($ext_info['path'].'/data/.htaccess', $htaccess);
        }
    } else if ($do === 'del') {
        // admins/mods only
        if($forum_user['is_admmod'] != true) {
            header('HTTP/1.x 401 Unauthorized');
            exit();
        }

        // get and validate message id
        $msgId = (isset($_POST['msgId'])) ? $_POST['msgId'] : null;
        if(preg_match('`\w{32}`A', $msgId) == 0) {
            header('HTTP/1.x 404 Not Found');
            exit();
        }

        // get content, seek for the message and delete it
        $found = false;
        $content = file_get_contents($chatFile);
        $content = (empty($content)) ? array() : json_decode($content);
        foreach($content as $i=>$msg) {
            if($msg[0] === $msgId) {
                array_splice($content, $i, 1);
                $found = true;
                break;
            }
        }

        // return new content or an error
        if($found) {
            // encode and write
            $content = json_encode($content);
            file_put_contents($chatFile, $content);
            // push the checksum
            $check = md5($content);
            $htaccess = file_get_contents($ext_info['path'].'/data/.htaccess');
            $htaccess = preg_replace('`X-json "\\\"\w{32}\\\""`', 'X-json "\"'.$check.'\""', $htaccess);
            file_put_contents($ext_info['path'].'/data/.htaccess', $htaccess);
            
        } else {
            header('HTTP/1.x 404 Not Found');
            exit();
        }
    } else {
        $content = file_get_contents($ext_info['path'].'/data/chat.dat');
        $check = md5($content);
    }

    // return chat content
    header('X-json: "'.$check.'"');
    echo $content;
    exit();
}

        ]]></hook>

        <hook id="co_modify_url_scheme"><![CDATA[

// disable token validation for chat submit
if(get_current_url() === $base_url.'/misc.php?action=ek_chatlite') {
    $_POST['csrf_token'] = generate_form_token($base_url.'/misc.php?action=ek_chatlite');
}
        ]]></hook>
    </hooks>
</extension>

The file above is manifest.xml and the modifications begin on about line 42. I've commented all the lines that I've changed and if you remove/modify it to suit your needs, remember to remove the ending brackets (which also have been commented) further down in the code.

How hard would it be to add another column in the user list for when they were last online? I haven't looked too much into utilizing the hook system yet, but any points in the right direction would be nice and I can write this one up myself and release it.

I'll get right on that... Thanks for the help. big_smile

Thank you for the quick response!

I just sat down to write up a quick extension (or rather to see if I could do it) and it's actually not that hard, but it'd be a bit easier if there was a list of all the variables available somewhere. If there is I must be blind cause I've looked for about an hour and haven't found any for 1.3.

Now you say that if I want to share it, I should add new group permission options. How would I go about doing that? Are you talking about adding the option into the Admin panel?

Thanks!

So I'm trying to limit an extension so it can't be viewed by either a guest or the default user group (named "Visitor" on my forum). I'm not quite sure how to call that in the $forum_user variable.

if($forum_user['is_guest'] != true || $forum_user['Visitor'] != true) { blahblah }

returns

Notice: Undefined index: Visitor in header.php(133) : eval()'d code on line 28

How do I go about checking for both the guest and default user group (or specific group, in the case my "Visitor" group)?

I was wondering if there was any way of making it so only registered users can see the chat.