*/
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
require_once(DOKU_INC.'inc/infoutils.php');
require_once(DOKU_PLUGIN.'semanticdata/phpSesame/phpSesame.php');
/**
* This is the base class for all syntax classes, providing some general stuff
*/
class helper_plugin_semanticdata extends DokuWiki_Plugin {
/**
* Connect to the triple store
*/
function _getTripleStore(){
static $ts = null;
if ($ts === null) {
$sesame = array('url' => $this->getConf('connect_url'), 'repository' => $this->getConf('connect_repository'));
$ts = new phpSesame($sesame['url'], $sesame['repository']);
}
return $ts;
}
/**
* Makes sure the given data fits with the given type
*/
function _cleanData($value, $type){
$value = trim($value);
if(!$value) return '';
if (is_array($type)) {
if (isset($type['enum']) &&
!preg_match('/(^|,\s*)' . preg_quote_cb($value) . '($|\s*,)/', $type['enum'])) {
return '';
}
$type = $type['type'];
}
switch($type){
case 'dt':
if(preg_match('/^(\d\d\d\d)-(\d\d?)-(\d\d?)$/',$value,$m)){
return sprintf('%d-%02d-%02d',$m[1],$m[2],$m[3]);
}
return '';
case 'url':
if(!preg_match('!^[a-z]+://!i',$value)) $value='http://'.$value;
return $value;
case 'mail':
$email = '';
$name = '';
$part = '';
$parts = preg_split('/\s+/',$value);
do{
$part = array_shift($parts);
if(!$email && mail_isvalid($part)){
$email = strtolower($part);
continue;
}
$name .= $part.' ';
}while($part);
return trim($email.' '.$name);
case 'page': case 'nspage':
return cleanID($value);
default:
return $value;
}
}
function _addPrePostFixes($type, $val, $pre='', $post='') {
if (is_array($type)) {
if (isset($type['prefix'])) $pre = $type['prefix'];
if (isset($type['postfix'])) $post = $type['postfix'];
}
return $pre.$val.$post;
}
/**
* Return XHTML formated data, depending on column type
*/
function _formatData($column, $value, &$R){
global $conf;
$vals = explode("\n",$value);
$outs = array();
foreach($vals as $val){
$val = trim($val);
if($val=='') continue;
$type = $column['type'];
if (is_array($type)) $type = $type['type'];
switch($type){
case 'page':
$val = $this->_addPrePostFixes($column['type'], $val, ':');
$outs[] = $R->internallink($val,null,null,true);
break;
case 'title':
list($id,$title) = explode('|',$val,2);
$id = $this->_addPrePostFixes($column['type'], $id, ':');
$outs[] = $R->internallink($id,$title,null,true);
break;
case 'nspage':
// no prefix/postfix here
$val = ':'.$column['key'].":$val";
$outs[] = $R->internallink($val,null,null,true);
break;
case 'mail':
list($id,$title) = explode(' ',$val,2);
$id = $this->_addPrePostFixes($column['type'], $id);
$id = obfuscate(hsc($id));
if(!$title){
$title = $id;
}else{
$title = hsc($title);
}
if($conf['mailguard'] == 'visible') $id = rawurlencode($id);
$outs[] = ''.$title.'';
break;
case 'url':
$val = $this->_addPrePostFixes($column['type'], $val);
$outs[] = ''.hsc($val).'';
break;
case 'tag':
#FIXME handle pre/postfix
$outs[] = ''.hsc($val).'';
break;
case 'wiki':
global $ID;
$oldid = $ID;
list($ID,$data) = explode('|',$val,2);
$data = $this->_addPrePostFixes($column['type'], $data);
// Trim document_{start,end}, p_{open,close}
$ins = array_slice(p_get_instructions($data), 2, -2);
$outs[] = p_render('xhtml', $ins, $byref_ignore);
$ID = $oldid;
break;
default:
$val = $this->_addPrePostFixes($column['type'], $val);
if(substr($type,0,3) == 'img'){
$sz = (int) substr($type,3);
if(!$sz) $sz = 40;
$title = $column['key'].': '.basename(str_replace(':','/',$val));
$outs[] = '';
}else{
$outs[] = hsc($val);
}
}
}
return join(', ',$outs);
}
/**
* Split a column name into its parts
*
* @returns array with key, type, ismulti, title, opt
*/
function _column($col){
preg_match('/^([^_]*)(?:_(.*))?((? ($matches[3] === 's'),
'key' => utf8_strtolower($matches[1]),
'title' => $matches[1],
'type' => utf8_strtolower($matches[2]));
// fix title for special columns
static $specials = array('%title%' => array('page', 'title'),
'%pageid%' => array('title', 'page'),
'%class%' => array('class'));
if (isset($specials[$column['title']])) {
$s = $specials[$column['title']];
$column['title'] = $this->getLang($s[0]);
if($column['type'] === '' && isset($s[1])) {
$column['type'] = $s[1];
}
}
// check if the type is some alias
$aliases = $this->_aliases();
if(isset($aliases[$column['type']])){
$column['origtype'] = $column['type'];
$column['type'] = $aliases[$column['type']];
}
return $column;
}
/**
* Load defined type aliases
*/
function _aliases(){
static $aliases = null;
if(!is_null($aliases)) return $aliases;
//$sqlite = $this->_getDB();
$sqlite = $this->_getTripleStore();
if(!$sqlite) return array();
// aliases come later
$aliases = array();
/*
* Aliases are currently not supported
*/
return $aliases;
}
/**
* Parse a filter line into an array
*
* @return mixed - array on success, false on error
*/
function _parse_filter($filterline){
if(preg_match('/^(.*?)([=<>!~]{1,2})(.*)$/',$filterline,$matches)){
$column = $this->_column(trim($matches[1]));
$com = $matches[2];
$aliasses = array('<>' => '!=', '=!' => '!=', '~!' => '!~',
'==' => '=', '~=' => '~', '=~' => '~');
if (isset($aliasses[$com])) {
$com = $aliasses[$com];
} elseif (!preg_match('/(!?[=~])|([<>]=?)/', $com)) {
msg('Failed to parse comparison "'.hsc($com).'"',-1);
return false;
}
$val = trim($matches[3]);
// allow current user name in filter:
$val = str_replace('%user%',$_SERVER['REMOTE_USER'],$val);
// allow current date in filter:
$val = str_replace('%now%', dformat(null, '%Y-%m-%d'),$val);
if(strpos($com, '~') !== false) {
$val = str_replace('*','%',$val);
if ($com == '!~'){
$com = 'NOT LIKE';
} else {
$com = 'LIKE';
}
} else {
// Clean if there are no asterisks I could kill
$val = $this->_cleanData($val, $column['type']);
}
$val = addslashes($val);
return array('key' => $column['key'],
'value' => $val,
'compare' => $com,
);
}
msg('Failed to parse filter "'.hsc($filterline).'"',-1);
return false;
}
/**
* Get filters given in the request via GET or POST
*/
function _get_filters(){
$flt = array();
$filters = array();
if(!isset($_REQUEST['dataflt'])){
$flt = array();
}elseif(!is_array($_REQUEST['dataflt'])){
$flt = (array) $_REQUEST['dataflt'];
}else{
$flt = $_REQUEST['dataflt'];
}
foreach($flt as $key => $line){
// we also take the column and filtertype in the key:
if(!is_numeric($key)) $line = $key.$line;
$f = $this->_parse_filter($line);
if(is_array($f)){
$f['logic'] = 'AND';
$filters[] = $f;
}
}
return $filters;
}
/**
* prepare an array to be passed through buildURLparams()
*/
function _a2ua($name,$array){
$urlarray = array();
foreach((array) $array as $key => $val){
$urlarray[rawurlencode($name).'['.rawurlencode($key).']'] = $val;
}
return $urlarray;
}
}