*/ // 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[] = ''.hsc($title).''; }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; } }