*/ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); require_once(DOKU_PLUGIN.'syntax.php'); class syntax_plugin_semanticdata_entry extends DokuWiki_Syntax_Plugin { /** * will hold the data helper plugin */ var $dthlp = null; /** * Constructor. Load helper plugin */ function syntax_plugin_semanticdata_entry(){ $this->dthlp =& plugin_load('helper', 'semanticdata'); if(!$this->dthlp) msg('Loading the data helper failed. Make sure the semanticdata plugin is installed.',-1); } /** * What kind of syntax are we? */ function getType(){ return 'substition'; } /** * What about paragraphs? */ function getPType(){ return 'block'; } /** * Where to sort in? */ function getSort(){ return 155; } /** * Connect pattern to lexer */ function connectTo($mode) { $this->Lexer->addSpecialPattern('----+ *dataentry(?: [ a-zA-Z0-9_]*)?-+\n.*?\n----+',$mode,'plugin_semanticdata_entry'); } /** * Handle the match - parse the data */ function handle($match, $state, $pos, &$handler){ // get lines $lines = explode("\n",$match); array_pop($lines); $class = array_shift($lines); $class = str_replace('dataentry','',$class); $class = trim($class,'- '); // parse info $data = array(); $meta = array(); foreach ( $lines as $line ) { // ignore comments preg_match('/^(.*?(?dthlp->_column($line[0]); if (isset($matches[2])) $column['comment'] = $matches[2]; if($column['multi']){ if(!isset($data[$column['key']])) { // init with empty array // Note that multiple occurrences of the field are // practically merged $data[$column['key']] = array(); } $vals = explode(',',$line[1]); foreach($vals as $val){ $val = trim($this->dthlp->_cleanData($val,$column['type'])); if($val == '') continue; if(!in_array($val,$data[$column['key']])) $data[$column['key']][] = $val; } }else{ $data[$column['key']] = $this->dthlp->_cleanData($line[1],$column['type']); } $columns[$column['key']] = $column; } return array('data'=>$data, 'cols'=>$columns, 'classes'=>$class, 'pos' => $pos, 'len' => strlen($match)); // not utf8_strlen } /** * Create output or save the data */ function render($format, &$renderer, $data) { global $ID; switch ($format){ case 'xhtml': $this->_showData($data,$renderer); return true; case 'metadata': $this->_saveData($data,$ID,$renderer->meta['title']); return true; case 'plugin_semanticdata_edit': $this->_editData($data, $renderer); return true; default: return false; } } /** * Output the data in a table */ function _showData($data,&$R){ global $ID; $ret = ''; if (method_exists($R, 'startSectionEdit')) { $data['classes'] .= ' ' . $R->startSectionEdit($data['pos'], 'plugin_semanticdata'); } $ret .= '
'; foreach($data['data'] as $key => $val){ if($val == '' || !count($val)) continue; $type = $data['cols'][$key]['type']; if (is_array($type)) $type = $type['type']; switch ($type) { case 'pageid': $type = 'title'; case 'wiki': $val = $ID . '|' . $val; break; } $ret .= '
'.hsc($data['cols'][$key]['title']).':
'; if(is_array($val)){ $cnt = count($val); for ($i=0; $i<$cnt; $i++){ $ret .= '
'; $ret .= $this->dthlp->_formatData($data['cols'][$key], $val[$i],$R); if($i < $cnt - 1) $ret .= ', '; $ret .= '
'; } }else{ $ret .= '
'. $this->dthlp->_formatData($data['cols'][$key], $val, $R).'
'; } } $ret .= '
'; $R->doc .= $ret; if (method_exists($R, 'finishSectionEdit')) { $R->finishSectionEdit($data['len'] + $data['pos']); } } /** * Save date to the triple store */ function _saveData($data,$id,$title){ $store = $this->dthlp->_getTripleStore(); $resultFormat = phpSesame::SPARQL_XML; $lang = "sparql"; $infer = true; if(!$store) return false; $error = ''; if(!$title) $title = $id; $class = $data['classes']; // delete all data from this page $sparql = sprintf('DELETE DATA { <%s%s> ?s ?o }',$this->getConf('base_url'),urlencode($id)); $result = $store->update($sparql, $resultFormat, $lang, $infer); // add page information $sparql = "PREFIX rdfs:" . sprintf("PREFIX spd:<%s> ",$this->getConf('base_url')) . "INSERT DATA " . sprintf("{ <%s%s> rdfs:label \"%s\" ; spd:hastitle \"%s\" ; spd:class \"%s\" . }",$this->getConf('base_url'),urlencode($id),$id,$title,$class); $result = $store->update($sparql, $resultFormat, $lang, $infer); // note, it should be possible to delete and update in a single query <> // insert new data foreach ($data['data'] as $key => $val){ if(is_array($val)) foreach($val as $v){ $sparql = sprintf("PREFIX spd:<%s> ",$this->getConf('base_url')) . 'INSERT DATA ' . sprintf('{ <%s%s> <%s%s> "%s" . }',$this->getConf('base_url'),urlencode($id),$this->getConf('base_url'),urlencode($key),$v); $result = $store->update($sparql, $resultFormat, $lang, $infer); }else { $sparql = sprintf("PREFIX spd:<%s> ",$this->getConf('base_url')) . 'INSERT DATA ' . sprintf('{ <%s%s> <%s%s> "%s" . }',$this->getConf('base_url'),urlencode($id),$this->getConf('base_url'),urlencode($key),$val); $result = $store->update($sparql, $resultFormat, $lang, $infer); } } return true; } function _editData($data, &$renderer) { $renderer->form->startFieldset($this->getLang('dataentry')); $renderer->form->_content[count($renderer->form->_content) - 1]['class'] = 'plugin__data'; if ($this->getConf('edit_content_only')) { $renderer->form->addHidden('data_edit[classes]', $data['classes']); $renderer->form->addElement(''); } else { $renderer->form->addElement(form_makeField('text', 'data_edit[classes]', $data['classes'], $this->getLang('class'), 'data__classes')); $renderer->form->addElement('
'); $text = ''; foreach(array('title', 'type', 'multi', 'value', 'comment') as $val) { $text .= ''; } $renderer->form->addElement($text . ''); // New line $data['data'][''] = ''; $data['cols'][''] = array('type' => '', 'multi' => false); } $n = 0; foreach($data['cols'] as $key => $vals) { $fieldid = 'data_edit[data][' . $n++ . ']'; $content = $vals['multi'] ? implode(', ', $data['data'][$key]) : $data['data'][$key]; if (is_array($vals['type'])) { $vals['basetype'] = $vals['type']['type']; if (isset($vals['type']['enum'])) { $vals['enum'] = $vals['type']['enum']; } $vals['type'] = $vals['origtype']; } else { $vals['basetype'] = $vals['type']; } $renderer->form->addElement(''); if ($this->getConf('edit_content_only')) { if (isset($vals['enum'])) { $values = preg_split('/\s*,\s*/', $vals['enum']); if (!$vals['multi']) array_unshift($values, ''); $content = form_makeListboxField($fieldid . '[value][]', $values, $data['data'][$key], $vals['title'], '', '', ($vals['multi'] ? array('multiple' => 'multiple'): array())); } else { $classes = 'data_type_' . $vals['type'] . ($vals['multi'] ? 's' : '') . ' ' . 'data_type_' . $vals['basetype'] . ($vals['multi'] ? 's' : ''); $content = form_makeField('text', $fieldid . '[value]', $content, $vals['title'], '', $classes); } $cells = array($vals['title'] . ':', $content, $vals['comment']); foreach(array('title', 'multi', 'comment', 'type') as $field) { $renderer->form->addHidden($fieldid . "[$field]", $vals[$field]); } } else { $check_data = $vals['multi'] ? array('checked' => 'checked') : array(); $cells = array(form_makeField('text', $fieldid . '[title]', $vals['title'], $this->getLang('title')), form_makeMenuField($fieldid . '[type]', array_merge(array('', 'page', 'nspage', 'title', 'mail', 'url', 'tag', 'wiki', 'dt'), array_keys($this->dthlp->_aliases())), $vals['type'], $this->getLang('type')), form_makeCheckboxField($fieldid . '[multi]', array('1', ''), $this->getLang('multi'), '', '', $check_data), form_makeField('text', $fieldid . '[value]', $content, $this->getLang('value')), form_makeField('text', $fieldid . '[comment]', $vals['comment'], $this->getLang('comment'), '', 'data_comment', array('readonly' => 1))); } foreach($cells as $cell) { $renderer->form->addElement(''); } $renderer->form->addElement(''); } $renderer->form->addElement('
' . $this->getLang($val) . '
'); $renderer->form->addElement($cell); $renderer->form->addElement('
'); $renderer->form->endFieldset(); } function _normalize($txt) { return str_replace('#', '\#', trim($txt)); } public static function editToWiki($data) { $nudata = array(); $len = 0; foreach ($data['data'] as $field) { if ($field['title'] === '') continue; $s = syntax_plugin_semanticdata_entry::_normalize($field['title']); if (trim($field['type']) !== '' || (substr($s, -1, 1) === 's' && $field['multi'] === '')) { $s .= '_' . syntax_plugin_semanticdata_entry::_normalize($field['type']); } if ($field['multi'] === '1') { $s .= 's'; } if (is_array($field['value'])) { $field['value'] = join(', ', $field['value']); } $nudata[] = array($s, syntax_plugin_semanticdata_entry::_normalize($field['value']), isset($field['comment']) ? trim($field['comment']) : ''); $len = max($len, utf8_strlen($nudata[count($nudata) - 1][0])); } $ret = '---- dataentry ' . trim($data['classes']) . ' ----' . DOKU_LF; foreach ($nudata as $field) { $ret .= $field[0] . str_repeat(' ', $len + 1 - utf8_strlen($field[0])) . ': ' . $field[1]; if ($field[2] !== '') { $ret .= ' #' . $field[2]; } $ret .= DOKU_LF; } $ret .= '----'; return $ret; } }