DokuWiki

It's better when it's simple

User Tools

Site Tools


plugin:flmod

file last modified plugin

Compatible with DokuWiki

2012-01-25

plugin To get feedback if a file have been updated.

Last updated on
2012-05-10
Provides
Syntax

This extension has not been updated in over 2 years. It may no longer be maintained or supported and may have compatibility issues.

Tagged with file, last, modified, timestamp

my native language is not English so I welcome grammar corrections.

License

You are free to use and modify this as you wish.

If you make some improvements share it to the comunity.

Installation

  1. In your plugins directory, create a new plugin folder titled “filelastmodified”
  2. Copy the PHP Code below and name it syntax.php
  3. Place the syntax.php in your plugin folder titled “filelastmodified”
  4. Upload the syntax.php into your plugins directory

Testing your installation

I assume you have a linux server

Place this code sample in your playground: mark that you must have a dummy line at the end

~~NOCACHE~~
<flmod>
filename: /var/log/messages
timeframe: 0
text: I rebootet the server on @filedate. Today it's @today so it was @days ago.
</flmod>
dummyline

Syntax

filename: your_file.txt
timeframe: how many days to look back on
shellexec: your_shell_command
show_help: [disabled]
text: Here you put your text that will be displayed when the file is newer then the timeframe. The text: area must be last item.

It's important to not having a white space between the command and the :. For example text : will not work but text: will.

In the text: area you can use html syntax. You don't have to use <br> for new line. The plugin does it for you. For user who is not familiarly whit this I have listed some common ones.

  • <b> text </b> for bold
  • <i> text </i> for italic

add some more FIXME

In the text: section you could call some varibles that is used in the process The variables is :

@filename (the same as filename: ) 
@timeframe (the same as timeframe: )
@filedate (the date of the file ) 
@days (how many days it was to it was last modified
@today (current date)

A good start is to include @filename in your text:. Because it contain some debugging information. You can remove it when it works.

I have also include a help text that will be shown as default. The help text is turned of by adding show_help: disabled.

Tip

Let say that you have a linked file and want to show when i was last saved, use timeframe: 0.

[[your_file]]
<flmod>
filename: /var/www/dokuwiki/data/media/media/your_file
timeframe: 0
text: your_file was last updated on @filedate
</flmod>

Enable shellexecute

Warning! …. you are opening a HUGE security hole …. Warning!

Only use this on private wikis!

You just change shellexecute to TRUE in the beginning of syntax.php

* shellexecute = TRUE;   
 */
$_shellexecute = TRUE;
 
if (!defined('DOKU_INC'))

I also strongly advise you to test your script before you run it in <flmod>. Else you could end up with a blanks screen. To fix that you must manually edit the page.txt outside dokuwiki.

Tips on usefully shellexecute commands

assuming you use a linux server

Add if you have something that you could share to the comunity

shellexec: touch /var/www/dokuwiki/media/pages/start.txt →will then be caught by RSS

shellexec: if test “./file1.txt” -nt “./file2.zip”; then zip -r file2.zip file1.txt some_dir2; fi → is file1.txt newer than file2.zip then rezip file2.zip and include all files in some_dir.

Copy and save this

syntax.php
<?php
 
/*
 * Plugin File last modified: Check if a file has been updated in a certain timeframe.
 * 
 * @license    use and modify as you wish
 * @author     Per Nils Snygg <pernils@smpparts.com>
 * @source     http://www.dokuwiki.org/plugin:flmod
 */
 
// http://www.dokuwiki.org/plugin:avtaskbox?s[]=doku&s[]=lexer&s[]=exit        source of the preg_match 
// http://www.brightcherry.co.uk/scribbles/php-adding-and-subtracting-dates/   source of the date subtraction             
 
/*
 *    ***  Config  ***
 * Enable shellexecute only if you are on a private Wiki. It will implement a HUGE security hole 
 * To enable shellexecute change it to true.
 * shellexecute = TRUE;   
 */
$_shellexecute = FALSE;
 
 
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');
 
/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_filelastmodified extends DokuWiki_Syntax_Plugin {
 
    function getInfo() {
        return array(
            'author' => 'Per-Nils Snygg',
            'email' => 'pernils@smpparts.com',
            'date' => '2012-05-01',
            'name' => 'File last modified/saved',
            'desc' => 'Give notifcation if the file have been saved/modified in current timeframe',
            'url' => 'http://www.dokuwiki.org/plugin:flmod',
        );
    }
 
    function getType() {
        return 'substition';
    }
 
    function getAllowedTypes() {
        return array();
    }
 
    function getPType() {
        return 'normal';
    }
 
    function getSort() {
        return 999;
    }
 
    function connectTo($mode) {
        $this->Lexer->addEntryPattern('<flmod>', $mode, 'plugin_filelastmodified');
    }
 
    function postConnect() {
        $this->Lexer->addExitPattern('</flmod>', 'plugin_filelastmodified');
    }
 
    function _help_text() {
        // string heredoc
        $output = <<< HEREDOC
Syntax : <br>
filename: <i>your_file.txt </i> <br>
timeframe: <i> how many days to look back on</i><br>
shellexec: <i>your_shell_comand </i> <br>
text: <i>Here you put your text that will be displayed when the file is newer then the timeframe. Here you can also get some output from variables.</i><br>
The variables is : <br>
@filename (the same as filename: ) <br>
@timeframe (the same as timeframe: ) <br> 
@filedate (the date of the file ) <br>
@days (how many days it was to it was last modified <br>  
@today (current date) <br>
<i> Always start the text area with @filename because it have some debugging information. You can remove it when it works <br>
To enable shellexec: you must set the _shellexecute to true in the beginning of syntax.php in the plugin folder. <br>
To remove this help text include </i> show_help: disable <br><br>
<b> Example.. <br>
&#60;flmod> <br>
filename: /var/www/index.html <br>
timeframe: 6 <br>
shellexec: cp /var/www/index.html /home/backup/index.html <br>
show_help: disable <br>
text: The @filename was updated on @filedate. <br>
It was @days ago. Today it is <b>@today</b>. <br>
I have now made a backup to /home/backup <br>
&#60;/flmod>
HEREDOC;
        return ($output);
    }
 
 
    function handle($match, $state, $pos, &$handler) {
        GLOBAL $_shellexecute;
        switch ($state) {
            case DOKU_LEXER_ENTER :
                break;
            case DOKU_LEXER_MATCHED :
                break;
            case DOKU_LEXER_UNMATCHED :
                preg_match('/^Filename:(.*?)$/isxm', $match, $matches);
                $filename = (!empty($matches[1]) && strlen(trim($matches[1])) > 0) ? trim($matches[1]) : 'No file is given! e.g Filename: [path]/your_file.txt';
 
                preg_match('/^Timeframe:(.*?)$/isxm', $match, $matches);
                $timeframe = (!empty($matches[1]) && strlen(trim($matches[1])) > 0) ? intval(preg_replace('[^0-9]', '', $matches[1])) : 0;
 
                preg_match('/^ShellExec:(.*?)$/isxm', $match, $matches);
                $shellexec = (!empty($matches[1]) && strlen(trim($matches[1])) > 0) ? trim($matches[1]) : '';
 
                preg_match('/^Show_help:(.*?)$/isxm', $match, $matches);
                $show_help = (!empty($matches[1]) && strlen(trim($matches[1])) > 0) ? trim($matches[1]) : 'enabled';
 
                preg_match('/Text:(.*)/isx', $match, $matches);
                $text = (!empty($matches[1]) && strlen(trim($matches[1])) > 0) ? trim($matches[1]) : '';
 
                ($show_help == 'enabled') ? $match = $this->_help_text() : $match = '';  // include help text or not
 
                if (file_exists($filename)) {
                    $filedate = date("Y-m-d", filemtime($filename));      // $filedate .. date of the file
                    $today_array = getdate();                             // $today .. current date     
                    $today = $today_array[year] . '-' . $today_array[mon] . '-' . $today_array[mday];
                    $days = (strtotime($today) - strtotime($filedate)) / (60 * 60 * 24); // $days .. is how many days ago it was modified
                } else {
                    $filename = '<br><i>The file :</i>' . $filename . '<i> couldn\ be found!</i><br>';
                }
                if ($timeframe > $days || $timeframe == 0) {             // simpel parser
                    $search = array("\r\n", "@filename", "@filedate", "@days", "@today", "@timeframe");
                    $replace = array('<br>', $filename, $filedate, $days, $today, $timeframe);
                    $str = str_replace($search, $replace, $text);
                    $match .= $str;
                }
                if ($_shellexecute) {
                    $output = shell_exec($shellexec);
                    $match .=$output;
                }
 
                return array($state, $match);
            case DOKU_LEXER_EXIT :
                break;
            case DOKU_LEXER_SPECIAL :
                break;
        }
        return array();
    }
 
    function render($mode, &$renderer, $data) {
        if ($mode == 'xhtml') {
            list($state, $match) = $data;
 
            switch ($state) {
                case DOKU_LEXER_ENTER :
                    break;
                case DOKU_LEXER_MATCHED :
                    break;
                case DOKU_LEXER_UNMATCHED :
                    $renderer->doc .= $match . '<br>';
                    break;
                case DOKU_LEXER_EXIT :
                    break;
                case DOKU_LEXER_SPECIAL :
                    break;
            }
            return true;
        }
        return false;
    }
 
}
 
//Setup VIM: ex: et ts=4 enc=utf-8 :
?>

Why this plugin?

When you have a linked file the RSS will not update if you modify the file. In my case I have a samba share and I wanted the visitor to directly see if the linked file has been modified or not. He/she could download it to see if it has been changed but that could be a bit annoying in the long run.

With this plugin I solved this. I have also added the possibility to execute some shell command. With this you could touch the page.txt so it will cough by RSS.

But enable shellexecute you will open a HUGE security hole. So don't use that on public wikis.

What could be improved ?

I tried but I couldn't figure out how to run time consuming shellexecute commands and also having some sort of interact with the user. Like spitting out some ** on the screen.

If you don't use the & on big shellexecute you will end up in a blank screen while it runs.

Discussion

This is my first attempt to do something in php so would be fun to hear your thoughts…thumbs up or down .. :-D

plugin/flmod.txt · Last modified: 2013-02-28 07:21 by 62.63.206.88