dokuwikitweet plugin

Compatible with DokuWiki

dokuwiki-2009-12-25

plugin a plugin to create a mini tweeter page in your wiki

Last updated on
2010-10-20
Provides
Syntax

Tagged with tweete

Manual installation

Refer to Plugins on how to install plugins manually. Grap all file below :

syntax.php
<?php
//
// Tweet plugin
//
// @license    Public domain
// @author     MARTINEAU Emeric
//
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
 
//
// Main class
//
class syntax_plugin_dokuwikitweet extends DokuWiki_Syntax_Plugin {
 
    private static $urlArray = array() ;
 
    //
    // return some info
    //
    function getInfo() {
        return array(
            'author' => 'MARTINEAU Emeric',
            'email'  => '',
            'date'   => '2010-09-15',
            'name'   => 'Tweet plugin',
            'desc'   => 'Space to tweet v1.0',
            'url'    => 'http://www.dokuwiki.org/plugin:dokuwikitweet'
        ) ;
    }
 
    //
    // Type of plugin
    //
    function getType() {
        return 'formatting';
    }
 
    //
    // ???
    //
    function getAllowedTypes() {
        return array() ; //'formatting', 'substition', 'disabled') ;
    }
 
    //
    // ???
    //
    function getPType() {
        return 'normal' ;
    }
 
    //
    // When run it
    // 
    function getSort() {
        return 158 ;
    }
 
    //
    // What tag to connect this plugin
    //
    function connectTo($mode) {
        include(dirname(__FILE__) . '/config.php') ;
 
        $this->Lexer->addEntryPattern('<' . $DOKUWIKI_TWEET_CONFIG['tag'] . '?>(?=.*?</' . $DOKUWIKI_TWEET_CONFIG['tag'] . '>)', $mode, 'plugin_dokuwikitweet') ;
    }
 
    //
    // What tag to deconnect this plugin
    //
    function postConnect() {
        include(dirname(__FILE__) . '/config.php') ;
 
        $this->Lexer->addExitPattern('</' . $DOKUWIKI_TWEET_CONFIG['tag'] . '>', 'plugin_dokuwikitweet') ;
    }
 
    //
    // Handle the match
    ///
    function handle($match, $state, $pos, &$handler) {        
        switch ($state) {
          case DOKU_LEXER_ENTER :
          case DOKU_LEXER_UNMATCHED :  
              return array($state, $match) ;
          case DOKU_LEXER_EXIT :
              return array($state, '') ;
        }
 
        return array() ;
    }
 
    //
    // Create output
    //
    function render($mode, &$renderer, $data) {
        global $conf ;
        global $INFO ;
 
        if($mode == 'xhtml') {
            list($state,$match) = $data ;
 
            switch ($state) {
                case DOKU_LEXER_ENTER :
                    include(dirname(__FILE__) . '/config.php') ;
 
                    $renderer->doc .= '<script type="text/javascript">' . "\n" .
                        'reloadTime=' . ($DOKUWIKI_TWEET_CONFIG['auto_reload_page'] * 1000) . ";\n" .
                        'timeOutReload=setTimeout("autoRefreshPage()", reloadTime) ;</script>' . "\n" ;
 
 
                    $renderer->doc .= '</p><div class="tweet_page">' . "\n" ;
 
                    // Add tweet bar
                    if ($conf['useacl'] && auth_quickAclCheck($pageId) >= AUTH_EDIT) {
                        $renderer->doc .= '  <form action="" method="post" name="tweet_form" id="tweet_form" onsubmit="return sendMessage();">' . "\n" .
                                      '    <textarea name="tweet_msg" id="tweet_msg" cols="50" rows="2" onkeyup="textLimit(this, ' . $DOKUWIKI_TWEET_CONFIG['msg_maximum_size'] . ');"></textarea>' . "\n" .
                                      '    <input type="submit" name="tweet_send" id="tweet_send" value="Send" />' . "\n" .
                                      '    <input type="hidden" name="tweet_user" id="tweet_user" value="' . $renderer->_xmlEntities($INFO['userinfo']['name']) . '" />' . "\n" .
                                      '    <input type="hidden" name="tweet_page_id" id="tweet_page_id" value="' . $renderer->_xmlEntities(getID()) . '" />' . "\n" .
                                      '    <input type="button" name="tweet_relod" id="tweet_reload" onclick="reloadPage()" value="Reload" />' .
                                      '  </form>' . "\n" .
                                      '  <div class="tweet_reloading" id="tweet_reloading">Reloading page...</div>' . "\n" ;
                    }
 
                    break ; 
                case DOKU_LEXER_UNMATCHED :
                    include(dirname(__FILE__) . '/config.php') ;
 
                    if (empty($DOKUWIKI_TWEET_CONFIG['date_format'])) {
                        $dateFormat = $conf['dformat'] ;
                        $dateFormat = str_replace('%Y', 'Y', $dateFormat) ;
                        $dateFormat = str_replace('%m', 'm', $dateFormat) ;
                        $dateFormat = str_replace('%d', 'd', $dateFormat) ;
                        $dateFormat = str_replace('%H', 'H', $dateFormat) ;
                        $dateFormat = str_replace('%M', 'i', $dateFormat) ;
                    } else {
                        $dateFormat = $DOKUWIKI_TWEET_CONFIG['date_format'] ;
                    }
 
                    $oddLine = true ;
 
                    // Read data
                    $data = explode("\n", $match) ;
                    $count = count($data) ;
 
                    // if last line empty, delete-it
                    if (($count > 0) && (empty($data[$count -1]))) {
                        unset($data[$count -1]) ;
 
                        $count-- ;
                    }
 
                    // Get url
                    $urlPageKey = $DOKUWIKI_TWEET_CONFIG['url_page_key'] ;
 
                    // Create new url
                    $newUrl = $this->getNewUrlString($urlPageKey) ;
 
                    // Get max msg
                    $maximumMsg = $DOKUWIKI_TWEET_CONFIG['nb_msg_per_page'] ;
 
                    // Read current page
                    $currentIndexPage = 0 ;
 
                    if (isset($_GET[$urlPageKey])) {
                        $selectedPage = $_GET[$urlPageKey] ;
                    } else {
                        $selectedPage = 0 ;
                    }
 
                    $renderer->doc .= '<ul class="tweet_list_page">' ;
 
                    if ($currentIndexPage == $selectedPage) {
                        $classCSS = 'tweet_list_current_page' ;
                        $classCssLink = 'tweet_url_current_page' ;
                    } else {
                        $classCSS = 'tweet_list_first_page' ;
                        $classCssLink = 'tweet_url_page' ;
                    }
 
                    $maxPage = ceil($count / $maximumMsg) ;
 
                    for($currentIndexPage = 0; $currentIndexPage < $maxPage; $currentIndexPage++) {
                        $renderer->doc .= '<li class="' . $classCSS . '">' .
                            '<a href="' . $newUrl . '&amp;' . $urlPageKey . '=' . $currentIndexPage .
                            '" class="' . $classCssLink . '">' . ($currentIndexPage + 1) . '</a></li>' . "\n" ;
 
                        if ($currentIndexPage == ($selectedPage -1)) {
                            $classCSS = 'tweet_list_current_page' ;
                            $classCssLink = 'tweet_url_current_page' ;
                        } else {
                            $classCSS = 'tweet_list_one_page' ;
                            $classCssLink = 'tweet_url_page' ;
                        }
                    }
 
                    $renderer->doc .= '</ul>' . "\n" ;
                    $renderer->doc .= '<div class="spacer">&nbsp;</div>' . "\n" ;
 
                    $startMessage = ($selectedPage * $maximumMsg) ;
                    $stopMessage = $startMessage + $maximumMsg ;
 
                    $renderer->doc .= '<div><table class="tweet_table_msg">' . "\n" ;
 
                    self::$urlArray = array() ;
 
                    for($indexMessage = $startMessage; ($indexMessage < $stopMessage) && ($indexMessage < $count); $indexMessage++) {
                        $line = $data[$indexMessage] ;
 
                        if (strlen($line) != 0) {
                            $renderer->doc .= '  <tr class="' ;
 
                            if ($oddLine) {
                                $renderer->doc .= 'tweet-line-odd' ;
                            } else {
                                $renderer->doc .= 'tweet-line-even' ;
                            }
 
                            $renderer->doc .= '">' . "\n" ;
 
                            $oddLine = !$oddLine ;
 
                            $field = explode($DOKUWIKI_TWEET_CONFIG['separator'], $line) ;
 
                            $renderer->doc .= '    <td class="tweet_user_and_date">' . "\n" ;
                            $renderer->doc .= '      <span class="tweet_show_user">' . $field[1] . '</span><br />' .
                                '<span class="tweet_show_date">' . date($dateFormat, $field[0]) . '</span>' . "\n" ;
                            $renderer->doc .= '    </td>' . "\n" ;
 
                            $renderer->doc .= '    <td class="tweet_show_message">' . "\n" ;
                            $renderer->doc .= '      ' . $this->decode($field[2], $renderer) . "\n" ;
                            $renderer->doc .= '    </td>' . "\n" ;
 
                            $renderer->doc .= '  </tr>' . "\n" ; 
                        }
                    }
 
                    $renderer->doc .= '</table></div>' . "\n" ;
 
                    break ;
                case DOKU_LEXER_EXIT :
                    $renderer->doc .= "</div>\n<p>" ;
                    break ;
            }
 
             return true ;
        }
 
        return false ;
    }
 
    //
    // Save url
    //
    // @param string $url url
    //
    // @return string
    public static function saveUrl($url) {
        $replace = '$starturl$' . count(self::$urlArray) . '$enurl$' ;
 
        self::$urlArray[] = $url[0] ;
 
        return $replace ;
    }
 
    //
    // Restore url
    //
    // @param string $ref ref
    //
    // @return url
    public static function restoreUrl($ref) {
        $url = self::$urlArray[$ref[2]] ;
 
        return '<a href="' . $url . '">' . $url . '</a>' ;
    }
 
    //
    // Escape url
    //
    // @param string $url string
    //
    // @return same string but escaped
    function escapeUrl($url) {
        $key = preg_quote('!*\'();:@&=+$,/?#[]' .
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
            'abcdefghijklmnopqrstuvwxyz' .
            '0123456789-_.~%') ;
 
        $in = '`((?:https?|ftp)://[' . $key . ']+/?)`si' ;
 
        return preg_replace_callback($in, 'syntax_plugin_dokuwikitweet::saveUrl', $url) ;
    }
 
 
    //
    // Escape url
    //
    // @param string $url string
    //
    // @return same string but escaped
    function clickableUrl($url) {
        $key = preg_quote('!*\'();:@&=+$,/?#[]' .
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
            'abcdefghijklmnopqrstuvwxyz' .
            '0123456789-_.~%') ;
 
        $openTag = preg_quote('$starturl$') ;
        $closeTag = preg_quote('$enurl$') ;
 
        $in = '`(' . $openTag . ')([0-9]+)(' . $closeTag . ')`si' ;
 
        return preg_replace_callback($in, 'syntax_plugin_dokuwikitweet::restoreUrl', $url) ;
    }
 
    //
    // Decode string
    //
    // @param string $string string to decode
    //
    // @return string
    function decode($string, $renderer) {        
        $string = urldecode($string) ;
 
        $string = $this->escapeUrl($string) ;
 
        $string = $renderer->_xmlEntities($string) ;
 
        $string = $this->clickableUrl($string) ;
 
        return $string ;
    }
 
    //
    // Create url link
    //
    // @param string $without without key
    //
    // @return url without
    function getNewUrlString($without) {
        $newUrl = '?' ;
 
        foreach($_GET as $key => $value) {
            if ($key != $without) {
                $newUrl .= urlencode($key) . '=' . urlencode($value) . '&amp;' ;
            }
        }
 
        return $newUrl ;
    }
}
ajax.php
<?php
//
// DokuWiki AJAX call handler
//
// @license    Public domain
// @author     MARTINEAU Emeric
//
 
//fix for Opera XMLHttpRequests
if(!count($_POST) && isset($HTTP_RAW_POST_DATA)) {
    parse_str($HTTP_RAW_POST_DATA, $_POST) ;
}
 
if(!defined('DOKU_INC')) {
    define('DOKU_INC',realpath(dirname(__FILE__).'/../../../').'/') ;
}
 
require_once(DOKU_INC.'inc/init.php') ;
require_once(DOKU_INC.'inc/common.php') ;
require_once(DOKU_INC.'inc/auth.php') ;
require_once(DOKU_INC.'inc/html.php') ;
 
define(SHOW_GRAVATAR, false) ;
define(BASE_URL, preg_replace('!(.+)(/.+){3}!', '\\1/', DOKU_BASE)) ;
 
session_write_close();
 
require_once('config.php') ;
 
//
// Get user name
//
// @return user name
//
function getUser() {
    if (isset($_GET['user'])) {
        $user = $_GET['user'] ;
    } else {
        $user = '' ;
    }
 
    $user = preg_replace('/[^ .,a-z0-9_\-]/i', '', $user) ;
    $user = substr($user, 0, 40) ;
 
    return $user ;
}
 
//
// Get page Id
//
// @return page id
//
function getPageId() {
    if (isset($_GET['pageId'])) {
        $pageId = $_GET['pageId'] ;
    } else {
        $pageId = '' ;
    }
 
    return cleanID($pageId) ;
}
 
//
// Get massage
//
// @return page id
//
function getMessage() {
    global $DOKUWIKI_TWEET_CONFIG ;
 
    if (isset($_GET['msg'])) {
        $msg = str_replace(array("\n", "\r"), ' ', $_GET['msg']) ;
        /*
    $fd = fopen('data.txt', 'w') ;
 
    if ($fd) {
        fwrite($fd, $msg) ;
        fclose($fd) ;
    }*/        
        $msg = substr($msg, 0, $DOKUWIKI_TWEET_CONFIG['msg_maximum_size']) ;
    } else {
        $msg = '' ;
    }
 
    $msg = urlencode($msg) ;
 
    return $msg ;
}
 
//
// Save message in wiki
//
function saveMessage() {
    global $conf ;
    global $auth ;
    global $lang ;
    global $DOKUWIKI_TWEET_CONFIG ;
 
    $pageId = getPageId() ;
 
    // TODO but how ?
    //if ($conf['useacl'] && auth_quickaclcheck($pageId) < AUTH_EDIT) {
	    while (checklock($pageId)) {
	        sleep(50) ;
        }
 
	    lock($pageId) ;
 
        $pageFileName = wikiFN($pageId) ;
        $fileContent = @file($pageFileName) ; 
 
        $lineCount = count($fileContent) ;
 
        $start = -1 ;
 
        $tagOpen = '<' . $DOKUWIKI_TWEET_CONFIG['tag'] . '>' ;
        $tagClose = '</' . $DOKUWIKI_TWEET_CONFIG['tag'] . '>' ;
 
        // Search tag
        for($index = 0; $index < $lineCount; $index++) {
            $pos = strpos($fileContent[$index], $tagOpen) ;
 
            if ($pos !== false) {
                $start = $index ;
            }
        }
 
        // Found ?
        if ($start > -1) {
            $line = time() . $DOKUWIKI_TWEET_CONFIG['separator'] . getUser() . $DOKUWIKI_TWEET_CONFIG['separator'] . getMessage() ;
 
            $fileContent[$start] = str_replace($tagOpen,
                $tagOpen . $line . "\n", $fileContent[$start]) ;
 
            $nbMsg = $DOKUWIKI_TWEET_CONFIG['max_msg'] ;
 
            // If -1 no delete
            if ($nbMsg > -1) {
                // Clear line    
                for($index = $start + 1; $index < $lineCount; ) {
                    $pos = strpos($fileContent[$index], $tagClose) ;
 
                    if ($pos !== false) {
                        break ;
                    } 
 
                    $nbMsg-- ;
 
                    if ($nbMsg < 1) {
                        array_splice($fileContent, $index, 1) ;
 
                        $lineCount-- ;
                    } else {
                        $index++ ;
                    }
                }
            }
 
            $fileContent = implode('', $fileContent) ;
 
            saveWikiText($pageId, $fileContent, "Message added", true) ;
 
            unlock($pageId) ;
        }
    //}
}
 
if (isset($_GET['action'])) {
    $action = $_GET['action'] ;
 
    if ($action == 'save') {
        saveMessage() ;
    }
}
?>
config.php
<?php
$DOKUWIKI_TWEET_CONFIG['separator'] = '|' ; // Separator of field in page
$DOKUWIKI_TWEET_CONFIG['tag'] = 'dokuwikitweet' ;
$DOKUWIKI_TWEET_CONFIG['max_msg'] = '200' ; // -1 no delete
$DOKUWIKI_TWEET_CONFIG['date_format'] = '' ; //'d/m/Y H:i:s' ; // If empty use dokuwiki data format
$DOKUWIKI_TWEET_CONFIG['msg_maximum_size'] = '255' ; // number of char typed by user (chek in JS and PHP)
$DOKUWIKI_TWEET_CONFIG['auto_reload_page'] = '30' ; // in second
$DOKUWIKI_TWEET_CONFIG['nb_msg_per_page'] = '20' ;
$DOKUWIKI_TWEET_CONFIG['url_page_key'] = 'tweet_page' ;
?>
script.js
//
 
// Tweet plugin
 
//
 
// @license    Public domain
 
// @author     MARTINEAU Emeric
 
//
 
var add_tweet = new sack(DOKU_BASE + 'lib/plugins/dokuwikitweet/ajax.php') ;
 
add_tweet.AjaxFailedAlert = '' ;
 
add_tweet.encodeURIString = false ;
 
add_tweet.method = "GET" ;
 
// If not null, a message send
 
var timeOutSend = null ;
 
// Reload time (30s per default)
 
var reloadTime = 30000 ;
 
// If not null, clear if
 
var timeOutReload = null ;
 
 
 
//
 
// Get element
 
function getElement(id) {
 
    if (document.getElementById) {
 
        return document.getElementById(id) ;
 
    } else if (document.all) {
 
        return window.document.all[id] ;
 
    } else if (document.layers) {
 
        return window.document.layers[id] ;
 
    }
 
 
 
    return null ;
 
}
 
 
 
//
 
// Get value of element of form
 
function getValueElement(id) {
 
    var input = getElement(id) ; 
 
    var value = '' ;
 
 
 
    if ((input != null) && (input != undefined)) {
 
        value = input.value ;
 
    }
 
 
 
    return value ;
 
}
 
 
 
//
 
// Send message
 
function sendMessage() {
 
    // Clear timeout to reload page
 
    clearTimeout(timeOutReload) ;
 
 
 
    var pageId = encodeURIComponent(getValueElement('tweet_page_id')) ;
 
    var user = encodeURIComponent(getValueElement('tweet_user')) ;
 
    var message = encodeURIComponent(getValueElement('tweet_msg')) ;
 
 
 
    if (message.length > 0) {
 
        if (add_tweet.setVar) {
 
            add_tweet.setVar('action', 'save') ;
 
            add_tweet.setVar('pageId', pageId) ;
 
            add_tweet.setVar('user', user) ;
 
            add_tweet.setVar('msg', message) ;
 
 
 
            add_tweet.runAJAX() ;    
 
        } else {    
 
            add_tweet.runAJAX(
 
            'action=save' + 
 
            '&pageId=' + pageId+
 
            '&user=' + user+
 
            '&msg=' + message) ;
 
        }
 
    }
 
 
 
    timeOutSend = setTimeout('reloadPage()', 2000) ;
 
 
 
    refreshPage() ;
 
 
 
    return false ;
 
}
 
 
 
//
 
// Hide item
 
function hide(id) {
 
    var tweetForm = getElement(id) ;
 
 
 
    tweetForm.style.display='none' ;
 
    tweetForm.style.visibility='hidden' ;
 
}
 
 
 
//
 
// Show item
 
function show(id) {
 
    var tweetForm = getElement(id) ;
 
 
 
    tweetForm.style.visibility='visible' ;
 
    tweetForm.style.display='block' ;
 
}
 
 
 
//
 
// Reload page
 
function reloadPage() {
 
    window.location.reload() ;
 
}
 
 
 
//
 
// Set element to say page is reloading but don't reloading
 
function refreshPage() {
 
    var tweetMsg = getElement('tweet_msg') ;
 
 
 
    tweetMsg.value = '' ;
 
 
 
    show('tweet_reloading') ;
 
 
 
    hide('tweet_form') ;
 
}
 
 
 
// Source from
 
// http://www.wikistuce.info/doku.php/javascript/limiter_la_saisie_dans_un_textearea
 
function textLimit(field, maxlen) {
 
   if (field.value.length > maxlen) {
 
      field.value = field.value.substring(0, maxlen) ;
 
   }
 
}
 
 
 
//
 
// Auto reload page if message is empty
 
function autoRefreshPage() {
 
    // Check if send a message
 
    var message = encodeURIComponent(getValueElement('tweet_msg')) ;
 
 
 
    if ((timeOutSend == null) && (message.length == 0)) {
 
        refreshPage() ;
 
        reloadPage() ;
 
    } else {
 
        timeOutReload = setTimeout("autoRefreshPage()", reloadTime) ;
 
    }
 
}
style.css
div.tweet_page {
}
 
div.tweet-line-even {
    background-color: white;
}
 
div.tweet-line-odd  {
    background-color: white;
}
 
form#tweet_form {
}
 
input#tweet_send {
}
 
input#tweet_msg {
}
 
div.tweet_reloading {
    visibility : hidden ;
    display : inline ;
}
 
div#tweet_reload {
}
 
.tweet_user_and_date {
    width:auto;
    background-color:#C1D3D6;
    white-space:nowrap;
    vertical-align:top;
}
 
span.tweet_show_user {
    font-weight:bold;
}
 
span.tweet_show_date {
    font-size:80%;
}
 
.tweet_show_message {
    height:40px;
    background-color:#EEEEEE;
    width:600px;
}
 
ul.tweet_list_page li {
    display:table;
    padding: 0px 0px 0px 0px ;
    margin: 0px 0px 0px 0px;
    list-style-type: none;
    float:left;
    text-align: center;
    line-height: 2.3em;
}
 
li.tweet_list_first_page {
    display:block;
    padding:4px;
    height:2.5em;
    width:2.5em; 
}
 
li.tweet_list_one_page {
    display:block;
    padding:4px;
    height:2.5em;
    width:2.5em; 
}
 
li.tweet_list_current_page {
    display:block;
    padding:4px;
    height:2.5em;
    width:2.5em;
    border:solid #CCCCCC;
    border-width: 1px 1px 1px 1px;    
    background-color: #3399AA;
    color:white;
}
 
.spacer {
    clear:left;
}
 
a.tweet_url_page {
    color:#999999 !important;
    text-decoration:none !important; 
}
 
a.tweet_url_current_page {
    color:white !important;
    text-decoration:none !important; 
}
 
.tweet_table_msg {
    border-spacing: 5px;
    /*border-collapse: collapse; */
}
install.txt
====== DokuWiki Tweet Plugin ======
Written by MARTINEAU Emeric. Public domain.
 
===== Installation =====
 
Just unzip this archive in lib directory or use plugin manager to download it.
After, edit config.php file.
 
===== Use it =====
 
Create a page and put :
~~NOCACHE~~
<dokuwikitweet></dokuwikitweet>
 
===== History =====
 
1.0 - 20/09/2010
  - delete CR or LF in text,
  - use table and not div cause firefox bug,
  - correct bug to show one page with empty message.
  - change encoding/decoding string,
  - better url support.
 
1.0b1 - 17/09/2010 :
  - first release.

Create a directory <dokuwiki_install_dir>/lib/plugins/dokuwikitweet and put all files in it.

Syntax and Usage

Create a page and put : <dokuwikitweet></dokuwikitweet>

plugin/dokuwikitweet.txt · Last modified: 2010/12/28 18:41 by lupo49
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 3.0 Unported
Imprint Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki
WikiForumIRCBugsGitXRefTranslate