1549a0837SAndreas Gohr<?php 261356325SAnna Dabrowska 3549a0837SAndreas Gohr/** 4549a0837SAndreas Gohr * DokuWiki Plugin struct (Syntax Component) 5549a0837SAndreas Gohr * 6549a0837SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 7549a0837SAndreas Gohr * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 8549a0837SAndreas Gohr */ 9549a0837SAndreas Gohr 107234bfb1Ssplitbrainuse dokuwiki\Extension\SyntaxPlugin; 11d90aa848SAndreas Gohruse dokuwiki\plugin\struct\meta\Aggregation; 12ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\AggregationTable; 13ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\ConfigParser; 14ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\SearchConfig; 15ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\StructException; 1615929be2SAndreas Gohr 177234bfb1Ssplitbrainclass syntax_plugin_struct_table extends SyntaxPlugin 1861356325SAnna Dabrowska{ 193f2a8309SAndreas Gohr /** @var string which class to use for output */ 203f2a8309SAndreas Gohr protected $tableclass = AggregationTable::class; 213f2a8309SAndreas Gohr 22d90aa848SAndreas Gohr /** @var string Config options that are not allowed for this syntax mode */ 23ce44c639SAndreas Gohr protected $illegalOptions = ['nesting', 'index']; 24d90aa848SAndreas Gohr 25549a0837SAndreas Gohr /** 26549a0837SAndreas Gohr * @return string Syntax mode type 27549a0837SAndreas Gohr */ 2861356325SAnna Dabrowska public function getType() 2961356325SAnna Dabrowska { 3015929be2SAndreas Gohr return 'substition'; 31549a0837SAndreas Gohr } 323f2a8309SAndreas Gohr 33549a0837SAndreas Gohr /** 34549a0837SAndreas Gohr * @return string Paragraph type 35549a0837SAndreas Gohr */ 3661356325SAnna Dabrowska public function getPType() 3761356325SAnna Dabrowska { 3815929be2SAndreas Gohr return 'block'; 39549a0837SAndreas Gohr } 403f2a8309SAndreas Gohr 41549a0837SAndreas Gohr /** 42549a0837SAndreas Gohr * @return int Sort order - Low numbers go before high numbers 43549a0837SAndreas Gohr */ 4461356325SAnna Dabrowska public function getSort() 4561356325SAnna Dabrowska { 465511bd5bSAndreas Gohr return 155; 47549a0837SAndreas Gohr } 48549a0837SAndreas Gohr 49549a0837SAndreas Gohr /** 50549a0837SAndreas Gohr * Connect lookup pattern to lexer. 51549a0837SAndreas Gohr * 52549a0837SAndreas Gohr * @param string $mode Parser mode 53549a0837SAndreas Gohr */ 5461356325SAnna Dabrowska public function connectTo($mode) 5561356325SAnna Dabrowska { 565511bd5bSAndreas Gohr $this->Lexer->addSpecialPattern('----+ *struct table *-+\n.*?\n----+', $mode, 'plugin_struct_table'); 57549a0837SAndreas Gohr } 58549a0837SAndreas Gohr 59549a0837SAndreas Gohr /** 60549a0837SAndreas Gohr * Handle matches of the struct syntax 61549a0837SAndreas Gohr * 62549a0837SAndreas Gohr * @param string $match The match of the syntax 63549a0837SAndreas Gohr * @param int $state The state of the handler 64549a0837SAndreas Gohr * @param int $pos The position in the document 65549a0837SAndreas Gohr * @param Doku_Handler $handler The handler 66549a0837SAndreas Gohr * @return array Data for the renderer 67549a0837SAndreas Gohr */ 6861356325SAnna Dabrowska public function handle($match, $state, $pos, Doku_Handler $handler) 6961356325SAnna Dabrowska { 70bd363da9SAndreas Gohr global $conf; 71549a0837SAndreas Gohr 725511bd5bSAndreas Gohr $lines = explode("\n", $match); 735511bd5bSAndreas Gohr array_shift($lines); 745511bd5bSAndreas Gohr array_pop($lines); 755511bd5bSAndreas Gohr 765511bd5bSAndreas Gohr try { 775511bd5bSAndreas Gohr $parser = new ConfigParser($lines); 780659dc64SMichael Grosse $config = $parser->getConfig(); 79d90aa848SAndreas Gohr $this->checkForInvalidOptions($config); 800659dc64SMichael Grosse return $config; 815511bd5bSAndreas Gohr } catch (StructException $e) { 825511bd5bSAndreas Gohr msg($e->getMessage(), -1, $e->getLine(), $e->getFile()); 83bd363da9SAndreas Gohr if ($conf['allowdebug']) msg('<pre>' . hsc($e->getTraceAsString()) . '</pre>', -1); 845511bd5bSAndreas Gohr return null; 855511bd5bSAndreas Gohr } 86549a0837SAndreas Gohr } 87549a0837SAndreas Gohr 88549a0837SAndreas Gohr /** 89549a0837SAndreas Gohr * Render xhtml output or metadata 90549a0837SAndreas Gohr * 9134ea6e10SAnna Dabrowska * @param string $format Renderer mode (supported modes: xhtml) 92549a0837SAndreas Gohr * @param Doku_Renderer $renderer The renderer 9330bf61e6SAndreas Gohr * @param array $config The parsed config data from the handler() function 94549a0837SAndreas Gohr * @return bool If rendering was successful. 95549a0837SAndreas Gohr */ 9630bf61e6SAndreas Gohr public function render($format, Doku_Renderer $renderer, $config) 9761356325SAnna Dabrowska { 9806fee43aSMichael Grosse global $INFO; 99bd363da9SAndreas Gohr global $conf; 10029877279SMichael Große 10130bf61e6SAndreas Gohr if (!$config) return false; 10230bf61e6SAndreas Gohr $config = $this->addTypeFilter($config); // add type specific filters 10330bf61e6SAndreas Gohr 10425ed0c0dSAndreas Gohr // always use the main page's ID @todo might make sense as utility method somewhere 10525ed0c0dSAndreas Gohr if ($INFO !== null) { 10625ed0c0dSAndreas Gohr $mainId = $INFO['id']; 10725ed0c0dSAndreas Gohr } else { 10825ed0c0dSAndreas Gohr $mainId = getID(); 10925ed0c0dSAndreas Gohr } 11025ed0c0dSAndreas Gohr 11115929be2SAndreas Gohr try { 112299ca8ccSAndreas Gohr $search = $this->getSearchConfig($config); 11334ea6e10SAnna Dabrowska if ($format === 'struct_csv') { 1146ce83f43SAndreas Gohr // no pagination in export 1156ce83f43SAndreas Gohr $search->setLimit(0); 1166ce83f43SAndreas Gohr $search->setOffset(0); 1176ce83f43SAndreas Gohr } 1186ce83f43SAndreas Gohr 11925ed0c0dSAndreas Gohr $table = new $this->tableclass($mainId, $format, $renderer, $search); 1207234bfb1Ssplitbrain if (!$table instanceof Aggregation) { 121039b05b8SAndreas Gohr // this may happen with plugins that extend struct 122039b05b8SAndreas Gohr throw new StructException('Aggregation class does not inherit Aggregation: ' . $this->tableclass); 123039b05b8SAndreas Gohr } 124039b05b8SAndreas Gohr 12595a8e37dSAnna Dabrowska $table->startScope(); 12695a8e37dSAnna Dabrowska $table->render(true); 12795a8e37dSAnna Dabrowska $table->finishScope(); 128*67f70d54SAnna Dabrowska 129*67f70d54SAnna Dabrowska if ($format === 'metadata') { 130*67f70d54SAnna Dabrowska /** @var Doku_Renderer_metadata $renderer */ 131*67f70d54SAnna Dabrowska $renderer->meta['plugin']['struct']['hasaggregation'] = $search->getCacheFlag(); 13216b7d914SAndreas Gohr } 1335511bd5bSAndreas Gohr } catch (StructException $e) { 13415929be2SAndreas Gohr msg($e->getMessage(), -1, $e->getLine(), $e->getFile()); 135bd363da9SAndreas Gohr if ($conf['allowdebug']) msg('<pre>' . hsc($e->getTraceAsString()) . '</pre>', -1); 13615929be2SAndreas Gohr } 13715929be2SAndreas Gohr 138549a0837SAndreas Gohr return true; 139549a0837SAndreas Gohr } 1400ceefd5cSAnna Dabrowska 1410ceefd5cSAnna Dabrowska /** 142299ca8ccSAndreas Gohr * Initialize a SearchConfig with the given parsed config 143299ca8ccSAndreas Gohr * 144299ca8ccSAndreas Gohr * @param array $config 145299ca8ccSAndreas Gohr * @return SearchConfig 146299ca8ccSAndreas Gohr */ 147299ca8ccSAndreas Gohr protected function getSearchConfig($config) 148299ca8ccSAndreas Gohr { 149299ca8ccSAndreas Gohr return new SearchConfig($config); 150299ca8ccSAndreas Gohr } 151299ca8ccSAndreas Gohr 152299ca8ccSAndreas Gohr 153299ca8ccSAndreas Gohr /** 154c797933dSAnna Dabrowska * Filter based on primary key columns, applicable in child classes 1550ceefd5cSAnna Dabrowska * 1560ceefd5cSAnna Dabrowska * @param array $config 1570ceefd5cSAnna Dabrowska * @return array 1580ceefd5cSAnna Dabrowska */ 1590ceefd5cSAnna Dabrowska protected function addTypeFilter($config) 1600ceefd5cSAnna Dabrowska { 1610ceefd5cSAnna Dabrowska return $config; 1620ceefd5cSAnna Dabrowska } 163d90aa848SAndreas Gohr 164d90aa848SAndreas Gohr /** 165d90aa848SAndreas Gohr * Checks for options that do not work in this aggregation 166d90aa848SAndreas Gohr * 167d90aa848SAndreas Gohr * @param array $config 168d90aa848SAndreas Gohr */ 169d90aa848SAndreas Gohr protected function checkForInvalidOptions($config) 170d90aa848SAndreas Gohr { 171d90aa848SAndreas Gohr foreach ($this->illegalOptions as $illegalOption) { 172d90aa848SAndreas Gohr if (!empty($config[$illegalOption])) { 173d90aa848SAndreas Gohr throw new StructException('illegal option', $illegalOption); 174d90aa848SAndreas Gohr } 175d90aa848SAndreas Gohr } 176d90aa848SAndreas Gohr } 177549a0837SAndreas Gohr} 178