/action.php |
@@ -5,54 +5,53 @@ |
* Action plugin component, for cache validity determination |
* |
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html) |
* @author Wizardry and Steamworks office@grimore.org |
* original: Christopher Smith <chris@jalakai.co.uk> |
* @author Christopher Smith <chris@jalakai.co.uk> |
*/ |
if(!defined('DOKU_INC')) die(); // no Dokuwiki, no go |
|
if(!defined('DOKU_INC')) die(); // no DokuWiki, no go |
|
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); |
require_once(DOKU_PLUGIN.'action.php'); |
|
|
/** |
* All DokuWiki plugins to extend the parser/rendering mechanism |
* need to inherit from this class |
*/ |
class action_plugin_source extends DokuWiki_Action_Plugin { |
|
|
/** |
* return some info |
*/ |
function getInfo(){ |
return array( |
'author' => 'Wizardry and Steamworks', |
'email' => 'office@grimore.org', |
'date' => '2016-11-19', |
'author' => 'Christopher Smith', |
'email' => 'chris@jalakai.co.uk', |
'date' => '2008-08-13', |
'name' => 'Source Plugin', |
'desc' => 'Include a remote source file', |
'url' => 'http://grimore.org/dokuwiki/plugins/source', |
'url' => 'http://www.dokuwiki.org/plugin:source', |
); |
} |
|
|
/** |
* plugin should use this method to register its handlers with the dokuwiki's event controller |
* plugin should use this method to register its handlers with the DokuWiki's event controller |
*/ |
function register(Doku_Event_Handler $controller) { |
$controller->register_hook('PARSER_CACHE_USE','BEFORE', $this, '_cache_prepare'); |
} |
|
|
/** |
* prepare the cache object for default _useCache action |
*/ |
function _cache_prepare(&$event, $param) { |
$cache =& $event->data; |
|
|
// we're only interested in wiki pages and supported render modes |
if (!isset($cache->page)) return; |
if (!isset($cache->mode) || in_array($cache->mode,array('i','metadata'))) return; |
|
|
$max_age = $this->_cache_maxage($cache->page); |
if (is_null($max_age)) return; |
|
|
if ($max_age <= 0) { |
// expire the cache |
$event->preventDefault(); |
@@ -60,10 +59,10 @@ |
$event->result = false; |
return; |
} |
|
|
$cache->depends['age'] = !empty($cache->depends['age']) ? min($cache->depends['age'],$max_age): $max_age; |
} |
|
|
/** |
* determine the max allowable age of the cache |
* |
@@ -75,28 +74,29 @@ |
function _cache_maxage($id) { |
$hasPart = p_get_metadata($id, 'relation haspart'); |
if (empty($hasPart) || !is_array($hasPart)) return null; |
|
|
$location = $this->getConf('location'); |
|
|
$age = 0; |
foreach ($hasPart as $file => $data) { |
// ensure the metadata entry was created by or for this plugin |
if (empty($data['owner']) || $data['owner'] != $this->getPluginName()) continue; |
|
|
$file = $this->getConf['location'].$file; |
|
|
// determine max allowable age for the cache |
// if filemtime can't be determined, either for a non-existent $file or for a $file using |
// an unsupported scheme, expire the cache immediately/always |
$mtime = @filemtime($file); |
if (!$mtime) { return 0; } |
|
|
$age = max($age,$mtime); |
} |
|
|
return $age ? time()-$age : null; |
} |
|
|
} |
|
//Setup VIM: ex: et ts=4 enc=utf-8 : |
|
//Setup VIM: ex: et ts=4 enc=utf-8 : |
/syntax.php |
@@ -22,26 +22,25 @@ |
* - this plugin's location, allow & deny settings. |
* |
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html) |
* @author Wizardry and Steamworks office@grimore.org |
* original: Christopher Smith <chris@jalakai.co.uk> |
* @author Christopher Smith <chris@jalakai.co.uk> |
*/ |
if(!defined('DOKU_INC')) die(); // no Dokuwiki, no go |
|
|
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_source extends DokuWiki_Syntax_Plugin { |
|
|
//------------------- [ Security settings ] --------------------------------------------- |
var $location = ''; // prepended to all file names, restricting the filespace exposed to the plugin |
var $allow = array(); // if not empty, ONLY files with the extensions listed will be allowed |
var $deny = array(); // if $allow array is empty, any file with an extension listed in $deny array will be denied |
var $rules = array(); // more complex allow/deny rules, refer documentation |
|
|
//------------------------[ Other settings ] --------------------------------------------- |
var $extensions = array( |
'htm' => 'html4strict', |
@@ -48,7 +47,7 @@ |
'html' => 'html4strict', |
'js' => 'javascript' |
); |
|
|
/** |
* return some info |
*/ |
@@ -63,11 +62,11 @@ |
'url' => 'http://www.dokuwiki.org/plugin:source', |
); |
} |
|
|
function getType() { return 'substition'; } |
function getPType() { return 'block'; } |
function getSort() { return 330; } |
|
|
/** |
* Connect pattern to lexer |
*/ |
@@ -74,20 +73,20 @@ |
function connectTo($mode) { |
$this->Lexer->addSpecialPattern('<source.*?>',$mode,substr(get_class($this), 7)); |
} |
|
|
/** |
* Handle the match |
*/ |
function handle($match, $state, $pos, Doku_Handler $handler){ |
$match = trim(substr($match,7,-1)); //strip <source from start and > from end |
|
|
// ['|"]?<filename>[\1] [#<line#>-<line#>] <lang> | <title> |
list($attr, $title) = preg_split('/\|/u', $match, 2); //split out title |
|
|
$attr = trim($attr); |
$pattern = ($attr{0} == '"' || $attr{0} == "'") ? $attr{0} : '\s'; |
$pattern = ($attr[0] == '"' || $attr[0] == "'") ? $attr[0] : '\s'; |
list($file, $prop) = preg_split("/$pattern/u", $attr, 3, PREG_SPLIT_NO_EMPTY); |
|
|
if (isset($prop) && trim($prop)) { |
$matches = array(); |
if (preg_match('/\s*(?:(?:#(\d+)-(\d+))\s*)?(\w+)?/',$prop,$matches)) { |
@@ -97,20 +96,20 @@ |
} else { |
$start = $end = $lang = ''; |
} |
|
|
return array(trim($file), $lang, (isset($title)?trim($title):''), $start, $end); |
} |
|
|
/** |
* Create output |
*/ |
function render($format, Doku_Renderer $renderer, $data) { |
|
|
$this->_loadSettings(); |
|
|
list($file, $lang, $title, $start, $end) = $data; |
$ext = substr(strrchr($file, '.'),1); |
|
|
$ok = false; |
if (count($this->allow)) { |
if (in_array($ext, $this->allow)) $ok = true; |
@@ -117,22 +116,22 @@ |
} else { |
if (!in_array($ext, $this->deny)) $ok = true; |
} |
|
|
// prevent filenames which attempt to move up directory tree by using ".." |
if ($ok && $this->location && preg_match('/(?:^|\/)\.\.(?:\/|$)/', $file)) $ok = false; |
if ($ok && $this->rules) $ok = $this->_checkRules($file); |
|
|
if (!$lang) { $lang = isset($this->extensions[$ext]) ? $this->extensions[$ext] : $ext; } |
|
|
switch ($format) { |
case 'xhtml' : |
|
|
if ($ok && ($source = $this->_getSource($file,$start,$end))) { |
|
|
$title = ($title) ? "<span>".hsc($title)."</span>" |
: $this->_makeTitle($file, $start, $end); |
|
$renderer->doc .= "<div class='source'><p class='title'>$title</p>"; |
|
$renderer->doc .= "<div class='source'><p>$title</p>"; |
$renderer->code($source, $lang); |
$renderer->doc .= "</div>"; |
} else { |
@@ -140,33 +139,33 @@ |
$renderer->doc .= '<div class="source"><p><span>'.$error.'</span></p></div>'; |
} |
break; |
|
|
case 'metadata' : |
if ($ok) { |
$renderer->meta['relation']['haspart'][$file] = array('owner'=>$this->getPluginName()); |
} |
break; |
|
|
default : |
if ($ok) { |
$renderer->code($this->_getSource($file,$start,$end), $lang); |
} |
} |
|
|
} |
|
|
function _makeTitle($file,$start,$end) { |
$lines = $start ? sprintf($this->getLang('lines'),$start,$end) : ''; |
$title = sprintf($this->getLang('title'),hsc($file),$lines); |
|
|
return $title; |
} |
|
|
function _getSource($file,$start,$end) { |
|
|
$source = @file($this->location.$file); |
if (empty($source)) return ''; |
|
|
// $start is a 1 based index, need to correct to 0 based when slicing arrray |
if (!empty($start)) { |
$lines = count($source); |
@@ -182,10 +181,10 @@ |
} else { |
$source = join('',$source); |
} |
|
|
return $source; |
} |
|
|
function _checkRules($file) { |
$permit = true; |
foreach ($this->rules as $rule) { |
@@ -196,41 +195,41 @@ |
if (preg_match($pattern,$file)) $permit = false; |
} |
} |
|
|
return $permit; |
} |
|
|
function _loadSettings() { |
static $loaded = false; |
|
|
if ($loaded) return; |
|
|
$this->location = $this->getConf('location'); |
|
|
$allow = $this->getConf('allow'); |
$this->allow = !empty($allow) ? explode('|',$allow) : array(); |
|
|
$deny = $this->getConf('deny'); |
$this->deny = !empty($deny) ? explode('|',$deny) : array(); |
|
|
$rules = $this->getConf('rules'); |
if (!empty($rules)) $this->_parseRules($rules); |
|
|
$loaded = true; |
} |
|
|
function _parseRules($rules) { |
$rules = explode("\n",$rules); |
foreach ($rules as $rule) { |
$rule = trim($rule); |
if (!$rule || $rule{0} == ';') continue; |
|
if (!$rule || $rule[0] == ';') continue; |
|
$match = array(); |
if (!preg_match('/^(allow|deny)\s+(.+)$/i',$rule,$match)) continue; |
|
|
$this->rules[] = array(strtolower($match[1]),$match[2]); |
} |
} |
} |
|
//Setup VIM: ex: et ts=4 enc=utf-8 : |
|
//Setup VIM: ex: et ts=4 enc=utf-8 : |