Merge branch 'master' into addSchemaClearButton

This commit is contained in:
Andreas Gohr
2017-10-16 15:54:57 +02:00
committed by GitHub
15 changed files with 681 additions and 47 deletions

109
_test/Bureaucracy.test.php Normal file
View File

@ -0,0 +1,109 @@
<?php
namespace dokuwiki\plugin\struct\test;
use dokuwiki\plugin\struct\meta;
use dokuwiki\plugin\struct\meta\AccessTable;
/**
* Tests for the integration with Bureaucracy plugin
*
* @group plugin_struct
* @group plugins
*
*/
class Bureaucracy_struct_test extends StructTest {
/** @var array alway enable the needed plugins */
protected $pluginsEnabled = array('struct', 'sqlite', 'bureaucracy');
/** @var array of lookup data */
protected $lookup = array();
public function setUp() {
parent::setUp();
$this->loadSchemaJSON('bureaucracy_lookup', '', 0, true);
$this->loadSchemaJSON('bureaucracy');
//insert some data to lookup
for($i = 1; $i <= 10; ++$i) {
$data = array(
'lookup_first' => 'value first ' . $i,
'lookup_second' => 'value second ' . $i
);
$lookupData = AccessTable::byTableName('bureaucracy_lookup', 0);
$lookupData->saveData($data);
$this->lookup[] = $lookupData;
}
}
public function test_bureaucracy_lookup_replacement_empty() {
//page created by bureaucracy
$id = 'bureaucracy_lookup_replacement_empty';
//id of template page
$template_id = 'template';
//create template
saveWikiText($template_id, 'Value:@@bureaucracy.lookup_select@@', 'summary');
//build form
$fields = array();
$lookup_field = plugin_load('helper', 'struct_field');
$lookup_field->opt['label'] = 'bureaucracy.lookup_select';
//empty value
$lookup_field->opt['value'] = '';
//left pagename undefined
//$lookup_field->opt['pagename'];
//$args are ommited in struct_field
$lookup_field->initialize(array());
$fields[] = $lookup_field;
//helper_plugin_bureaucracy_actiontemplate
$actiontemplate = plugin_load('helper', 'bureaucracy_actiontemplate');
$actiontemplate->run($fields, '', array($template_id, $id, '_'));
$page_content = io_readWikiPage(wikiFN($id), $id);
$this->assertEquals('Value:', $page_content);
}
public function test_bureaucracy_lookup_replacement() {
//page created by bureaucracy
$id = 'bureaucracy_lookup_replacement';
//id of template page
$template_id = 'template';
//pid of selected value
$lookup_pid = $this->lookup[0]->getPid();
//selected value
$lookup_value = $this->lookup[0]->getData()['lookup_first']->getValue();
//create template
saveWikiText($template_id, 'Value:@@bureaucracy.lookup_select@@', 'summary');
//build form
$fields = array();
$lookup_field = plugin_load('helper', 'struct_field');
$lookup_field->opt['label'] = 'bureaucracy.lookup_select';
$lookup_field->opt['value'] = $lookup_pid;
//left pagename undefined
//$lookup_field->opt['pagename'];
//$args are ommited in struct_field
$lookup_field->initialize(array());
$fields[] = $lookup_field;
//helper_plugin_bureaucracy_actiontemplate
$actiontemplate = plugin_load('helper', 'bureaucracy_actiontemplate');
$actiontemplate->run($fields, '', array($template_id, $id, '_'));
$page_content = io_readWikiPage(wikiFN($id), $id);
$this->assertEquals('Value:' . $lookup_value, $page_content);
}
}

View File

@ -203,4 +203,54 @@ class SearchConfigParameter_struct_test extends StructTest {
$this->assertArrayNotHasKey('sort', $conf);
$this->assertArrayNotHasKey(meta\SearchConfigParameters::$PARAM_SORT, $param);
}
public function test_pagination() {
global $INPUT;
$data = array(
'schemas' => array(
array('schema2', 'alias2'),
),
'cols' => array(
'afirst'
),
'rownumbers' => '1',
'limit' => '5',
);
$R = new \Doku_Renderer_xhtml();
// init with offset
$INPUT->set(meta\SearchConfigParameters::$PARAM_OFFSET, 5);
//$params[meta\SearchConfigParameters::$PARAM_OFFSET] = 25;
$searchConfig = new meta\SearchConfig($data);
$aggregationTable = new meta\AggregationTable('test_pagination', 'xhtml', $R, $searchConfig);
$aggregationTable->render();
$expect = '<div class="structaggregation"><div class="table"><table class="inline">
<thead>
<tr class="row0">
<th class="col0">#</th><th data-field="schema2.afirst"><a href="/./doku.php?id=test_pagination&amp;ofs=5&amp;srt=schema2.afirst" class="" title="Sort by this column">afirst</a></th>
</tr>
</thead>
<tbody>
<tr class="row1" data-pid="page14"><td class="col0">6</td><td class="col1">page14 first data</td>
</tr>
<tr class="row2" data-pid="page15"><td class="col0">7</td><td class="col1">page15 first data</td>
</tr>
<tr class="row3" data-pid="page16"><td class="col0">8</td><td class="col1">page16 first data</td>
</tr>
<tr class="row4" data-pid="page17"><td class="col0">9</td><td class="col1">page17 first data</td>
</tr>
<tr class="row5" data-pid="page18"><td class="col0">10</td><td class="col1">page18 first data</td>
</tr>
</tbody>
<tfoot>
<tr class="row6">
<th class="col0" colspan="2"><a href="/./doku.php?id=test_pagination" class="prev">Previous page</a><a href="/./doku.php?id=test_pagination&amp;ofs=10" class="next">Next page</a></th>
</tr>
</tfoot>
</table></div>
</div>';
$this->assertEquals($expect, $R->doc);
}
}

View File

@ -0,0 +1,36 @@
{
"structversion": "2017-07-11",
"schema": "bureaucracy",
"id": "2",
"user": "",
"config": {
"allowed editors": "",
"label": {
"en": ""
}
},
"columns": [
{
"colref": 1,
"ismulti": false,
"isenabled": true,
"sort": 10,
"label": "lookup_select",
"class": "Lookup",
"config": {
"visibility": {
"inpage": true,
"ineditor": true
},
"schema": "bureaucracy_lookup",
"field": "lookup_first",
"label": {
"en": ""
},
"hint": {
"en": ""
}
}
}
]
}

View File

@ -0,0 +1,58 @@
{
"structversion": "2017-07-11",
"schema": "bureaucracy_lookup",
"id": "1",
"user": "",
"config": {
"allowed editors": "",
"label": {
"en": ""
}
},
"columns": [
{
"colref": 1,
"ismulti": false,
"isenabled": true,
"sort": 10,
"label": "lookup_first",
"class": "Text",
"config": {
"visibility": {
"inpage": true,
"ineditor": true
},
"prefix": "",
"postfix": "",
"label": {
"en": ""
},
"hint": {
"en": ""
}
}
},
{
"colref": 2,
"ismulti": false,
"isenabled": true,
"sort": 20,
"label": "lookup_second",
"class": "Text",
"config": {
"visibility": {
"inpage": true,
"ineditor": true
},
"prefix": "",
"postfix": "",
"label": {
"en": ""
},
"hint": {
"en": ""
}
}
}
]
}

View File

@ -12,6 +12,7 @@ if(!defined('DOKU_INC')) die();
use dokuwiki\plugin\struct\meta\AccessTable;
use dokuwiki\plugin\struct\meta\Assignments;
use dokuwiki\plugin\struct\meta\Schema;
use dokuwiki\plugin\struct\meta\Search;
/**
* Handles bureaucracy additions
@ -32,6 +33,7 @@ class action_plugin_struct_bureaucracy extends DokuWiki_Action_Plugin {
* @return void
*/
public function register(Doku_Event_Handler $controller) {
$controller->register_hook('PLUGIN_BUREAUCRACY_TEMPLATE_SAVE', 'BEFORE', $this, 'handle_lookup_fields');
$controller->register_hook('PLUGIN_BUREAUCRACY_TEMPLATE_SAVE', 'AFTER', $this, 'handle_save');
$controller->register_hook('PLUGIN_BUREAUCRACY_FIELD_UNKNOWN', 'BEFORE', $this, 'handle_schema');
}
@ -72,6 +74,47 @@ class action_plugin_struct_bureaucracy extends DokuWiki_Action_Plugin {
return true;
}
/**
* Replace lookup fields placeholder's values
*
* @param Doku_Event $event event object by reference
* @param mixed $param [the parameters passed as fifth argument to register_hook() when this
* handler was registered]
* @return bool
*/
public function handle_lookup_fields(Doku_Event $event, $param) {
foreach($event->data['fields'] as $field) {
if(!is_a($field, 'helper_plugin_struct_field')) continue;
if($field->column->getType()->getClass() != 'Lookup') continue;
$pid = $field->getParam('value');
$config = $field->column->getType()->getConfig();
// find proper value
// current Search implementation doesn't allow doing it using SQL
$search = new Search();
$search->addSchema($config['schema']);
$search->addColumn($config['field']);
$result = $search->execute();
$pids = $search->getPids();
$len = count($result);
$value = '';
for($i = 0; $i < $len; $i++) {
if ($pids[$i] == $pid) {
$value = $result[$i][0]->getDisplayValue();
break;
}
}
//replace previous value
if ($value) {
$event->data['values'][$field->column->getFullQualifiedLabel()] = $value;
}
}
return true;
}
/**
* Save the struct data
*
@ -112,7 +155,8 @@ class action_plugin_struct_bureaucracy extends DokuWiki_Action_Plugin {
);
// trigger meta data rendering to set page title
p_get_metadata($id);
// expire the cache in order to correctly render the struct header on the first page visit
p_get_metadata($id, array('cache' => 'expire'));
}
}

View File

@ -8,7 +8,8 @@
use dokuwiki\Form\Form;
use dokuwiki\plugin\struct\meta\CSVExporter;
use dokuwiki\plugin\struct\meta\CSVImporter;
use dokuwiki\plugin\struct\meta\CSVLookupImporter;
use dokuwiki\plugin\struct\meta\CSVPageImporter;
use dokuwiki\plugin\struct\meta\Schema;
use dokuwiki\plugin\struct\meta\SchemaBuilder;
use dokuwiki\plugin\struct\meta\SchemaEditor;
@ -80,7 +81,13 @@ class admin_plugin_struct_schemas extends DokuWiki_Admin_Plugin {
if($table && $INPUT->bool('importcsv')) {
if(isset($_FILES['csvfile']['tmp_name'])) {
try {
new CSVImporter($table, $_FILES['csvfile']['tmp_name']);
if ($INPUT->bool('lookup')) {
$csvImporter = new CSVLookupImporter($table, $_FILES['csvfile']['tmp_name']);
} else {
$csvImporter = new CSVPageImporter($table, $_FILES['csvfile']['tmp_name']);
}
$csvImporter->import();
msg($this->getLang('admin_csvdone'), 1);
} catch(StructException $e) {
msg(hsc($e->getMessage()), -1);
@ -198,13 +205,11 @@ class admin_plugin_struct_schemas extends DokuWiki_Admin_Plugin {
$form->addButton('exportcsv', $this->getLang('btn_export'));
$form->addFieldsetClose();
if($schema->isLookup()) {
$form->addFieldsetOpen($this->getLang('admin_csvimport'));
$form->addElement(new \dokuwiki\Form\InputElement('file', 'csvfile'));
$form->addButton('importcsv', $this->getLang('btn_import'));
$form->addHTML('<p><a href="https://www.dokuwiki.org/plugin:struct:csvimport">' . $this->getLang('admin_csvhelp') . '</a></p>');
$form->addFieldsetClose();
}
$form->addFieldsetOpen($this->getLang('admin_csvimport'));
$form->addElement(new \dokuwiki\Form\InputElement('file', 'csvfile'));
$form->addButton('importcsv', $this->getLang('btn_import'));
$form->addHTML('<p><a href="https://www.dokuwiki.org/plugin:struct:csvimport">' . $this->getLang('admin_csvhelp') . '</a></p>');
$form->addFieldsetClose();
return $form->toHTML();
}

View File

@ -1,4 +1,4 @@
@media only screen and (max-width: @ini_tablet_width) {
@media only screen and (max-width: 800px) {
#plugin__struct_output {
margin-right: 0;
}

View File

@ -4,16 +4,19 @@
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*
* @author Andreas Gohr <andi@splitbrain.org>
* @author Malte Lembeck <malte.lembeck@outlook.de>
*/
$lang['menu'] = 'Struct Schema Editor';
$lang['menu_assignments'] = 'Struct Schema Zuweisungen';
$lang['headline'] = 'Strukturierte Daten';
$lang['edithl'] = 'Schema <i>%s</i> bearbeiten';
$lang['create'] = 'Neues Schema anlegen';
$lang['schemaname'] = 'Schema-Name:';
$lang['save'] = 'Speichern';
$lang['createhint'] = 'Achtung: Schemas können später nicht umbenannt werden';
$lang['pagelabel'] = 'Seite';
$lang['rowlabel'] = 'Reihe #';
$lang['revisionlabel'] = 'Zuletzt geändert';
$lang['userlabel'] = 'letzter Bearbeitender';
$lang['summary'] = 'Struct-Daten geändert';
$lang['export'] = 'Schema als JSON exportieren';
$lang['btn_export'] = 'Exportieren';
@ -38,3 +41,14 @@ $lang['admin_csvexport'] = 'Exportieren von Rohdaten in einer CSV-Datei';
$lang['admin_csvimport'] = 'Importieren von Rohdaten aus einer CSV-Datei';
$lang['admin_csvdone'] = 'CSV-Datei importiert';
$lang['admin_csvhelp'] = 'Bitte konsultieren Sie das Handbuch zum CSV-Import (engl.) für Formatierungsdetails.';
$lang['btn_delete'] = 'Löschen';
$lang['js']['confirmAssignmentsDelete'] = 'Wollen Sie wirklich die Zuweisung von Schma "{0}" zu Seite/Namensraum "{1}" löschen?';
$lang['tab_export'] = 'Importieren/Exportieren';
$lang['editor_sort'] = 'Sortieren';
$lang['editor_conf'] = 'Konfiguration';
$lang['editor_type'] = 'Eingeben';
$lang['editor_enabled'] = 'Aktiviert';
$lang['assign_add'] = 'Hinzufügen';
$lang['assign_del'] = 'Löschen';
$lang['multidropdown'] = 'Halte STRG oder CMD um mehrere Werte auszuwählen.';

View File

@ -131,8 +131,8 @@ class AggregationCloud {
if (is_array($tagValue)) {
$tagValue = $tagValue[0];
}
$key = $value->getColumn()->getFullQualifiedLabel() . '*~';
$filter = SearchConfigParameters::$PARAM_FILTER . "[$key]=" . urlencode($tagValue);
$key = $value->getColumn()->getFullQualifiedLabel() . '=';
$filter = SearchConfigParameters::$PARAM_FILTER . '[' . urlencode($key) . ']=' . urlencode($tagValue);
$this->renderer->listitem_open(1);
$this->renderer->listcontent_open();

View File

@ -360,7 +360,8 @@ class AggregationTable {
// row number column
if($this->data['rownumbers']) {
$this->renderer->tablecell_open();
$this->renderer->cdata($rownum + 1);
$searchConfigConf = $this->searchConfig->getConf();
$this->renderer->cdata($rownum + $searchConfigConf['offset'] + 1);
$this->renderer->tablecell_close();
}

View File

@ -9,7 +9,7 @@ namespace dokuwiki\plugin\struct\meta;
*
* @package dokuwiki\plugin\struct\meta
*/
class CSVImporter {
abstract class CSVImporter {
/** @var Schema */
protected $schema;
@ -26,6 +26,12 @@ class CSVImporter {
/** @var int current line number */
protected $line = 0;
/** @var list of headers */
protected $header;
/** @var array list of validation errors */
protected $errors;
/**
* CSVImporter constructor.
*
@ -40,12 +46,17 @@ class CSVImporter {
$this->schema = new Schema($table);
if(!$this->schema->getId()) throw new StructException('Schema does not exist');
if(!$this->schema->isLookup()) throw new StructException('CSV import is only valid for Lookup Schemas');
/** @var \helper_plugin_struct_db $db */
$db = plugin_load('helper', 'struct_db');
$this->sqlite = $db->getDB(true);
}
/**
* Import the data from file.
*
* @throws StructException
*/
public function import() {
// Do the import
$this->readHeaders();
$this->importCSV();
@ -53,6 +64,8 @@ class CSVImporter {
/**
* Read the CSV headers and match it with the Schema columns
*
* @return array headers of file
*/
protected function readHeaders() {
$header = fgetcsv($this->fh);
@ -69,6 +82,8 @@ class CSVImporter {
if(!$this->columns) {
throw new StructException('None of the CSV headers matched any of the schema\'s fields');
}
$this->header = $header;
}
/**
@ -109,12 +124,108 @@ class CSVImporter {
$single = $this->getSQLforAllValues();
$multi = $this->getSQLforMultiValue();
$this->sqlite->query('BEGIN TRANSACTION');
while(($data = fgetcsv($this->fh)) !== false) {
$this->sqlite->query('BEGIN TRANSACTION');
$this->line++;
$this->importLine($data, $single, $multi);
$this->sqlite->query('COMMIT TRANSACTION');
}
}
/**
* The errors that occured during validation
*
* @return string[] already translated error messages
*/
public function getErrors() {
return $this->errors;
}
/**
* Validate a single value
*
* @param Column $col the column of that value
* @param mixed &$rawvalue the value, will be fixed according to the type
* @return bool true if the data validates, otherwise false
*/
protected function validateValue(Column $col, &$rawvalue) {
//by default no validation
return true;
}
/**
* Read and validate CSV parsed line
*
* @param &$line
*/
protected function readLine(&$line) {
// prepare values for single value table
$values = array();
foreach($this->columns as $i => $column) {
if(!isset($line[$i])) throw new StructException('Missing field at CSV line %d', $this->line);
if(!$this->validateValue($column, $line[$i])) return false;
if($column->isMulti()) {
// multi values get split on comma
$line[$i] = array_map('trim', explode(',', $line[$i]));
$values[] = $line[$i][0];
} else {
$values[] = $line[$i];
}
}
//if no ok don't import
return $values;
}
/**
* INSERT $values into data_* table
*
* @param string[] $values
* @param string $single SQL for single table
*
* @return string last_insert_rowid()
*/
protected function insertIntoSingle($values, $single) {
$this->sqlite->query($single, $values);
$res = $this->sqlite->query('SELECT last_insert_rowid()');
$pid = $this->sqlite->res2single($res);
$this->sqlite->res_close($res);
return $pid;
}
/**
* INSERT one row into multi_* table
*
* @param string $multi SQL for multi table
* @param $pid string
* @param $column string
* @param $row string
* @param $value string
*/
protected function insertIntoMulti($multi, $pid, $column, $row, $value) {
$this->sqlite->query($multi, array($pid, $column->getColref(), $row + 1, $value));
}
/**
* Save one CSV line into database
*
* @param string[] $values parsed line values
* @param string $single SQL for single table
* @param string $multi SQL for multi table
*/
protected function saveLine($values, $line, $single, $multi) {
// insert into single value table (and create pid)
$pid = $this->insertIntoSingle($values, $single);
// insert all the multi values
foreach($this->columns as $i => $column) {
if(!$column->isMulti()) continue;
foreach($line[$i] as $row => $value) {
$this->insertIntoMulti($multi, $pid, $column, $row, $value);
}
}
$this->sqlite->query('COMMIT TRANSACTION');
}
/**
@ -125,33 +236,13 @@ class CSVImporter {
* @param string $multi SQL for multi table
*/
protected function importLine($line, $single, $multi) {
// prepare values for single value table
$values = array();
foreach($this->columns as $i => $column) {
if(!isset($line[$i])) throw new StructException('Missing field at CSV line %d', $this->line);
//read values, false if no validation
$values = $this->readLine($line);
if($column->isMulti()) {
// multi values get split on comma
$line[$i] = array_map('trim', explode(',', $line[$i]));
$values[] = $line[$i][0];
} else {
$values[] = $line[$i];
}
}
// insert into single value table (and create pid)
$this->sqlite->query($single, $values);
$res = $this->sqlite->query('SELECT last_insert_rowid()');
$pid = $this->sqlite->res2single($res);
$this->sqlite->res_close($res);
// insert all the multi values
foreach($this->columns as $i => $column) {
if(!$column->isMulti()) continue;
foreach($line[$i] as $row => $value) {
$this->sqlite->query($multi, array($pid, $column->getColref(), $row + 1, $value));
}
if($values) {
$this->saveLine($values, $line, $single, $multi);
} else foreach($this->errors as $error) {
msg($error, -1);
}
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace dokuwiki\plugin\struct\meta;
class CSVLookupImporter extends CSVImporter {
/**
* Check if schema is lookup
*
* @throws StructException
* @param string $table
* @param string $file
*/
public function __construct($table, $file) {
parent::__construct($table, $file);
if(!$this->schema->isLookup()) throw new StructException($table.' is not lookup schema');
}
}

164
meta/CSVPageImporter.php Normal file
View File

@ -0,0 +1,164 @@
<?php
namespace dokuwiki\plugin\struct\meta;
use dokuwiki\plugin\struct\types\Page;
class CSVPageImporter extends CSVImporter {
protected $importedPids = array();
/**
* Chceck if schema is page schema
*
* @throws StructException
* @param string $table
* @param string $file
*/
public function __construct($table, $file) {
parent::__construct($table, $file);
if($this->schema->isLookup()) throw new StructException($table.' is not a page schema');
}
/**
* Import page schema only when the pid header is present.
*/
protected function readHeaders() {
//add pid to struct
$pageType = new Page(null, 'pid');
$this->columns[] = new Column(0, $pageType);
parent::readHeaders();
if(!in_array('pid', $this->header)) throw new StructException('There is no "pid" header in the CSV. Schema not imported.');
}
/**
* Creates the insert string for the single value table
*
* @return string
*/
protected function getSQLforAllValues() {
$colnames = array();
foreach($this->columns as $i => $col) {
$colnames[] = 'col' . $col->getColref();
}
//replace first column with pid
$colnames[0] = 'pid';
//insert rev at the end
$colnames[] = 'rev';
$placeholds = join(', ', array_fill(0, count($colnames), '?'));
$colnames = join(', ', $colnames);
$table = $this->schema->getTable();
return "INSERT INTO data_$table ($colnames, latest) VALUES ($placeholds, 1)";
}
/**
* Add the revision.
*
* @param string[] $values
* @param $line
* @param string $single
* @param string $multi
*/
protected function saveLine($values, $line, $single, $multi) {
//create new page revision
$pid = $values[0];
$helper = plugin_load('helper', 'struct');
$revision = $helper->createPageRevision($pid, 'CSV data imported');
p_get_metadata($pid); // reparse the metadata of the page top update the titles/rev/lasteditor table
// make sure this schema is assigned
/** @noinspection PhpUndefinedVariableInspection */
Assignments::getInstance()->assignPageSchema(
$pid,
$this->schema->getTable()
);
//add page revision to values
$values[] = $revision;
parent::saveLine($values, $line, $single, $multi);
}
/**
* In the paga schemas primary key is a touple of (pid, rev)
*
* @param string[] $values
* @param string $single
* @return array(pid, rev)
*/
protected function insertIntoSingle($values, $single) {
$pid = $values[0];
$rev = $values[count($values) - 1];
//update latest
$table = $this->schema->getTable();
$this->sqlite->query("UPDATE data_$table SET latest = 0 WHERE latest = 1 AND pid = ?", array($pid));
//insert into table
parent::insertIntoSingle($values, $single);
//primary key is touple of (pid, rev)
return array($pid, $rev);
}
/**
* Add pid and rev to insert query parameters
*
* @param string $multi
* @param string $pk
* @param string $column
* @param string $row
* @param string $value
*/
protected function insertIntoMulti($multi, $pk, $column, $row, $value) {
list($pid, $rev) = $pk;
//update latest
$table = $this->schema->getTable();
$this->sqlite->query("UPDATE multi_$table SET latest = 0 WHERE latest = 1 AND pid = ?", array($pid));
$this->sqlite->query($multi, array($pid, $rev, $column->getColref(), $row + 1, $value));
}
/**
* In page schemas we use REPLACE instead of INSERT to prevent ambiguity
*
* @return string
*/
protected function getSQLforMultiValue() {
$table = $this->schema->getTable();
/** @noinspection SqlResolve */
return "INSERT INTO multi_$table (pid, rev, colref, row, value, latest) VALUES (?,?,?,?,?,1)";
}
/**
* Check if page id realy exists
*
* @param Column $col
* @param mixed $rawvalue
* @return bool
*/
protected function validateValue(Column $col, &$rawvalue) {
//check if page id exists and schema is bounded to the page
if($col->getLabel() == 'pid') {
$pid = cleanID($rawvalue);
if (isset($this->importedPids[$pid])) {
$this->errors[] = 'Page "'.$pid.'" already imported. Skipping the row.';
return false;
}
if(page_exists($pid)) {
$this->importedPids[$pid] = true;
return true;
}
$this->errors[] = 'Page "'.$pid.'" does not exists. Skipping the row.';
return false;
}
return parent::validateValue($col, $rawvalue);
}
}

View File

@ -1,7 +1,7 @@
base struct
author Andreas Gohr, Michael Große
email dokuwiki@cosmocode.de
date 2017-06-15
date 2017-07-11
name struct plugin
desc Add and query additional structured page data
url https://www.dokuwiki.org/plugin:struct

View File

@ -7,6 +7,8 @@
*/
// must be run within Dokuwiki
use dokuwiki\plugin\struct\meta\ConfigParser;
use dokuwiki\plugin\struct\meta\SearchConfig;
use dokuwiki\plugin\struct\meta\StructException;
if(!defined('DOKU_INC')) die();
@ -116,4 +118,44 @@ class remote_plugin_struct extends DokuWiki_Remote_Plugin {
throw new RemoteException($e->getMessage(), 0, $e);
}
}
/**
* Get the data that would be shown in an aggregation
*
* @param array $schemas array of strings with the schema-names
* @param array $cols array of strings with the columns
* @param array $filter array of arrays with ['logic'=> 'and'|'or', 'condition' => 'your condition']
* @param string $sort string indicating the column to sort by
*
* @return array array of rows, each row is an array of the column values
* @throws RemoteException
*/
public function getAggregationData(array $schemas, array $cols, array $filter = [], $sort = '') {
$schemaLine = 'schema: ' . implode(', ', $schemas);
$columnLine = 'cols: ' . implode(', ', $cols);
$filterLines = array_map(function ($filter) {
return 'filter' . $filter['logic'] . ': ' . $filter['condition'];
}, $filter);
$sortLine = 'sort: ' . $sort;
// schemas, cols, REV?, filter, order
try {
$parser = new ConfigParser(array_merge([$schemaLine, $columnLine, $sortLine], $filterLines));
$config = $parser->getConfig();
$search = new SearchConfig($config);
$results = $search->execute();
$data = [];
/** @var \dokuwiki\plugin\struct\meta\Value[] $rowValues */
foreach ($results as $rowValues) {
$row = [];
foreach ($rowValues as $value) {
$row[$value->getColumn()->getFullQualifiedLabel()] = $value->getDisplayValue();
}
$data[] = $row;
}
return $data;
} catch (StructException $e) {
throw new RemoteException($e->getMessage(), 0, $e);
}
}
}