107993756SAndreas Gohr<?php 207993756SAndreas Gohr 3ba766201SAndreas Gohrnamespace dokuwiki\plugin\struct\meta; 407993756SAndreas Gohr 57234bfb1Ssplitbrainuse dokuwiki\Extension\Event; 67234bfb1Ssplitbrain 7d60f71efSAndreas Gohr/** 8d60f71efSAndreas Gohr * Creates the table aggregation output 9d60f71efSAndreas Gohr * 10ba766201SAndreas Gohr * @package dokuwiki\plugin\struct\meta 11d60f71efSAndreas Gohr */ 12d90aa848SAndreas Gohrclass AggregationTable extends Aggregation 13d6d97f60SAnna Dabrowska{ 14d90aa848SAndreas Gohr /** @var array for summing up columns */ 15d90aa848SAndreas Gohr protected $sums; 1607993756SAndreas Gohr 17d90aa848SAndreas Gohr /** @var string[] the result PIDs for each row */ 18d4b5a17cSAndreas Gohr protected $resultPIDs; 190ceefd5cSAnna Dabrowska protected $resultRids; 206fd73b4bSAnna Dabrowska protected $resultRevs; 21d4b5a17cSAndreas Gohr 22*67f70d54SAnna Dabrowska public function __construct($id, $mode, \Doku_Renderer $renderer, SearchConfig $searchConfig) 23*67f70d54SAnna Dabrowska { 24*67f70d54SAnna Dabrowska parent::__construct($id, $mode, $renderer, $searchConfig); 25*67f70d54SAnna Dabrowska $this->resultPIDs = $this->searchConfig->getPids(); 26*67f70d54SAnna Dabrowska $this->resultRids = $this->searchConfig->getRids(); 27*67f70d54SAnna Dabrowska $this->resultRevs = $this->searchConfig->getRevs(); 28*67f70d54SAnna Dabrowska } 29*67f70d54SAnna Dabrowska 30d90aa848SAndreas Gohr /** @inheritdoc */ 31d90aa848SAndreas Gohr public function render($showNotFound = false) 32d6d97f60SAnna Dabrowska { 33*67f70d54SAnna Dabrowska 34b7e1d73bSAndreas Gohr // abort early if there are no results at all (not filtered) 35d90aa848SAndreas Gohr if (!$this->resultCount && !$this->isDynamicallyFiltered() && $showNotFound) { 36b7e1d73bSAndreas Gohr $this->renderer->cdata($this->helper->getLang('none')); 37b7e1d73bSAndreas Gohr return; 38b7e1d73bSAndreas Gohr } 39b7e1d73bSAndreas Gohr 40986ab7e6SAndreas Gohr $this->renderActiveFilters(); 41844a4f01SFrieder Schrempf 427fe2cdf2SAndreas Gohr $rendercontext = [ 43844a4f01SFrieder Schrempf 'table' => $this, 44844a4f01SFrieder Schrempf 'renderer' => $this->renderer, 453f640228SFrieder Schrempf 'format' => $this->mode, 46844a4f01SFrieder Schrempf 'search' => $this->searchConfig, 47844a4f01SFrieder Schrempf 'columns' => $this->columns, 48844a4f01SFrieder Schrempf 'data' => $this->result 497fe2cdf2SAndreas Gohr ]; 50844a4f01SFrieder Schrempf 517234bfb1Ssplitbrain $event = new Event( 52844a4f01SFrieder Schrempf 'PLUGIN_STRUCT_RENDER_AGGREGATION_TABLE', 532dbe71f8SAnna Dabrowska $rendercontext 54844a4f01SFrieder Schrempf ); 552dbe71f8SAnna Dabrowska $event->trigger([$this, 'renderTable']); 56844a4f01SFrieder Schrempf 57844a4f01SFrieder Schrempf // export handle 58844a4f01SFrieder Schrempf $this->renderExportControls(); 59844a4f01SFrieder Schrempf } 60844a4f01SFrieder Schrempf 61844a4f01SFrieder Schrempf /** 62844a4f01SFrieder Schrempf * Render the default aggregation table 63844a4f01SFrieder Schrempf */ 64844a4f01SFrieder Schrempf public function renderTable($rendercontext) 65844a4f01SFrieder Schrempf { 6607993756SAndreas Gohr $this->renderer->table_open(); 6707993756SAndreas Gohr 6807993756SAndreas Gohr // header 6907993756SAndreas Gohr $this->renderer->tablethead_open(); 70986ab7e6SAndreas Gohr $this->renderColumnHeaders(); 71986ab7e6SAndreas Gohr $this->renderDynamicFilters(); 7207993756SAndreas Gohr $this->renderer->tablethead_close(); 7307993756SAndreas Gohr 7407993756SAndreas Gohr if ($this->resultCount) { 7507993756SAndreas Gohr // actual data 76a9fd81f9SAndreas Gohr $this->renderer->tabletbody_open(); 77986ab7e6SAndreas Gohr $this->renderResult(); 78a9fd81f9SAndreas Gohr $this->renderer->tabletbody_close(); 7907993756SAndreas Gohr 80a9fd81f9SAndreas Gohr // footer (tfoot is develonly currently) 81a9fd81f9SAndreas Gohr if (method_exists($this->renderer, 'tabletfoot_open')) $this->renderer->tabletfoot_open(); 82986ab7e6SAndreas Gohr $this->renderSums(); 83986ab7e6SAndreas Gohr $this->renderPagingControls(); 84a9fd81f9SAndreas Gohr if (method_exists($this->renderer, 'tabletfoot_close')) $this->renderer->tabletfoot_close(); 8507993756SAndreas Gohr } else { 8607993756SAndreas Gohr // nothing found 87986ab7e6SAndreas Gohr $this->renderEmptyResult(); 8807993756SAndreas Gohr } 8907993756SAndreas Gohr 9007993756SAndreas Gohr // table close 9107993756SAndreas Gohr $this->renderer->table_close(); 9207993756SAndreas Gohr } 9307993756SAndreas Gohr 9407993756SAndreas Gohr /** 9507993756SAndreas Gohr * Adds additional info to document and renderer in XHTML mode 9607993756SAndreas Gohr * 9707993756SAndreas Gohr * @see finishScope() 9807993756SAndreas Gohr */ 99af0ce8d2SAndreas Gohr public function startScope() 100d6d97f60SAnna Dabrowska { 10107993756SAndreas Gohr // unique identifier for this aggregation 10207993756SAndreas Gohr $this->renderer->info['struct_table_hash'] = md5(var_export($this->data, true)); 10309dd691aSAndreas Gohr 104af0ce8d2SAndreas Gohr parent::startScope(); 10507993756SAndreas Gohr } 10607993756SAndreas Gohr 10707993756SAndreas Gohr /** 10807993756SAndreas Gohr * Closes the table and anything opened in startScope() 10907993756SAndreas Gohr * 11007993756SAndreas Gohr * @see startScope() 11107993756SAndreas Gohr */ 112af0ce8d2SAndreas Gohr public function finishScope() 113d6d97f60SAnna Dabrowska { 11407993756SAndreas Gohr // remove identifier from renderer again 11507993756SAndreas Gohr if (isset($this->renderer->info['struct_table_hash'])) { 11607993756SAndreas Gohr unset($this->renderer->info['struct_table_hash']); 11707993756SAndreas Gohr } 11809dd691aSAndreas Gohr 119af0ce8d2SAndreas Gohr parent::finishScope(); 12007993756SAndreas Gohr } 12107993756SAndreas Gohr 12207993756SAndreas Gohr /** 12307993756SAndreas Gohr * Displays info about the currently applied filters 12407993756SAndreas Gohr */ 125d6d97f60SAnna Dabrowska protected function renderActiveFilters() 126d6d97f60SAnna Dabrowska { 12707993756SAndreas Gohr if ($this->mode != 'xhtml') return; 12807993756SAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 12907993756SAndreas Gohr $filters = $dynamic->getFilters(); 13007993756SAndreas Gohr if (!$filters) return; 13107993756SAndreas Gohr 1327234bfb1Ssplitbrain $fltrs = []; 13307993756SAndreas Gohr foreach ($filters as $column => $filter) { 1347234bfb1Ssplitbrain [$comp, $value] = $filter; 13504ec4785SAnna Dabrowska 13604ec4785SAnna Dabrowska // display the filters in a human readable format 13704ec4785SAnna Dabrowska foreach ($this->columns as $col) { 13804ec4785SAnna Dabrowska if ($column === $col->getFullQualifiedLabel()) { 13904ec4785SAnna Dabrowska $column = $col->getTranslatedLabel(); 14004ec4785SAnna Dabrowska } 14104ec4785SAnna Dabrowska } 1421f075418SAnna Dabrowska $fltrs[] = sprintf('"%s" %s "%s"', $column, $this->helper->getLang("comparator $comp"), $value); 14307993756SAndreas Gohr } 14407993756SAndreas Gohr 14507993756SAndreas Gohr $this->renderer->doc .= '<div class="filter">'; 14617a3a578SAndreas Gohr $this->renderer->doc .= '<h4>' . 14717a3a578SAndreas Gohr sprintf( 14817a3a578SAndreas Gohr $this->helper->getLang('tablefilteredby'), 14917a3a578SAndreas Gohr hsc(implode(' & ', $fltrs)) 15017a3a578SAndreas Gohr ) . 15117a3a578SAndreas Gohr '</h4>'; 15207993756SAndreas Gohr $this->renderer->doc .= '<div class="resetfilter">'; 15307993756SAndreas Gohr $this->renderer->internallink($this->id, $this->helper->getLang('tableresetfilter')); 15407993756SAndreas Gohr $this->renderer->doc .= '</div>'; 15507993756SAndreas Gohr $this->renderer->doc .= '</div>'; 15607993756SAndreas Gohr } 15707993756SAndreas Gohr 15807993756SAndreas Gohr /** 15907993756SAndreas Gohr * Shows the column headers with links to sort by column 16007993756SAndreas Gohr */ 161d6d97f60SAnna Dabrowska protected function renderColumnHeaders() 162d6d97f60SAnna Dabrowska { 16307993756SAndreas Gohr $this->renderer->tablerow_open(); 16407993756SAndreas Gohr 16507993756SAndreas Gohr // additional column for row numbers 16634ea6e10SAnna Dabrowska if (!empty($this->data['rownumbers'])) { 16707993756SAndreas Gohr $this->renderer->tableheader_open(); 16807993756SAndreas Gohr $this->renderer->cdata('#'); 16907993756SAndreas Gohr $this->renderer->tableheader_close(); 17007993756SAndreas Gohr } 17107993756SAndreas Gohr 17207993756SAndreas Gohr // show all headers 1738c4ee9beSAndreas Gohr foreach ($this->columns as $num => $column) { 1748c4ee9beSAndreas Gohr $header = ''; 1758c4ee9beSAndreas Gohr if (isset($this->data['headers'][$num])) { 1768c4ee9beSAndreas Gohr $header = $this->data['headers'][$num]; 1778c4ee9beSAndreas Gohr } 17807993756SAndreas Gohr 17907993756SAndreas Gohr // use field label if no header was set 18007993756SAndreas Gohr if (blank($header)) { 18101f8b845SAndreas Gohr if (is_a($column, 'dokuwiki\plugin\struct\meta\Column')) { 18207993756SAndreas Gohr $header = $column->getTranslatedLabel(); 18307993756SAndreas Gohr } else { 18407993756SAndreas Gohr $header = 'column ' . $num; // this should never happen 18507993756SAndreas Gohr } 18607993756SAndreas Gohr } 18707993756SAndreas Gohr 18807993756SAndreas Gohr // simple mode first 18907993756SAndreas Gohr if ($this->mode != 'xhtml') { 19007993756SAndreas Gohr $this->renderer->tableheader_open(); 19107993756SAndreas Gohr $this->renderer->cdata($header); 19207993756SAndreas Gohr $this->renderer->tableheader_close(); 19307993756SAndreas Gohr continue; 19407993756SAndreas Gohr } 19507993756SAndreas Gohr 19607993756SAndreas Gohr // still here? create custom header for more flexibility 19707993756SAndreas Gohr 1989113d04aSAndreas Gohr // width setting, widths are prevalidated, no escape needed 19907993756SAndreas Gohr $width = ''; 2009113d04aSAndreas Gohr if (isset($this->data['widths'][$num]) && $this->data['widths'][$num] != '-') { 2019113d04aSAndreas Gohr $width = ' style="min-width: ' . $this->data['widths'][$num] . ';' . 2029113d04aSAndreas Gohr 'max-width: ' . $this->data['widths'][$num] . ';"'; 20307993756SAndreas Gohr } 20407993756SAndreas Gohr 205d4b5a17cSAndreas Gohr // prepare data attribute for inline edits 206d6d97f60SAnna Dabrowska if ( 207d6d97f60SAnna Dabrowska !is_a($column, '\dokuwiki\plugin\struct\meta\PageColumn') && 208d4b5a17cSAndreas Gohr !is_a($column, '\dokuwiki\plugin\struct\meta\RevisionColumn') 209d4b5a17cSAndreas Gohr ) { 210d4b5a17cSAndreas Gohr $data = 'data-field="' . hsc($column->getFullQualifiedLabel()) . '"'; 211d4b5a17cSAndreas Gohr } else { 212d4b5a17cSAndreas Gohr $data = ''; 213d4b5a17cSAndreas Gohr } 214d4b5a17cSAndreas Gohr 21507993756SAndreas Gohr // sort indicator and link 21607993756SAndreas Gohr $sortclass = ''; 21707993756SAndreas Gohr $sorts = $this->searchConfig->getSorts(); 21807993756SAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 219aa124708SAndreas Gohr $dynamic->setSort($column, true); 22007993756SAndreas Gohr if (isset($sorts[$column->getFullQualifiedLabel()])) { 2217fe2cdf2SAndreas Gohr [/*colname*/, $currentSort] = $sorts[$column->getFullQualifiedLabel()]; 222aa124708SAndreas Gohr if ($currentSort) { 22307993756SAndreas Gohr $sortclass = 'sort-down'; 22407993756SAndreas Gohr $dynamic->setSort($column, false); 22507993756SAndreas Gohr } else { 22607993756SAndreas Gohr $sortclass = 'sort-up'; 22707993756SAndreas Gohr } 22807993756SAndreas Gohr } 22907993756SAndreas Gohr $link = wl($this->id, $dynamic->getURLParameters()); 23007993756SAndreas Gohr 23107993756SAndreas Gohr // output XHTML header 232d4b5a17cSAndreas Gohr $this->renderer->doc .= "<th $width $data>"; 2333ebc6780SAnna Dabrowska 234da7041d3SAlexander Yakovlev if (is_a($this->renderer, 'renderer_plugin_dw2pdf')) { 235da7041d3SAlexander Yakovlev $this->renderer->doc .= hsc($header); 236da7041d3SAlexander Yakovlev } else { 23717a3a578SAndreas Gohr $this->renderer->doc .= '<a href="' . $link . '" class="' . $sortclass . '" ' . 23817a3a578SAndreas Gohr 'title="' . $this->helper->getLang('sort') . '">' . hsc($header) . '</a>'; 239da7041d3SAlexander Yakovlev } 2403ebc6780SAnna Dabrowska 24107993756SAndreas Gohr $this->renderer->doc .= '</th>'; 24207993756SAndreas Gohr } 24307993756SAndreas Gohr 24407993756SAndreas Gohr $this->renderer->tablerow_close(); 24507993756SAndreas Gohr } 24607993756SAndreas Gohr 24707993756SAndreas Gohr /** 248b7e1d73bSAndreas Gohr * Is the result set currently dynamically filtered? 249b7e1d73bSAndreas Gohr * @return bool 250b7e1d73bSAndreas Gohr */ 251d6d97f60SAnna Dabrowska protected function isDynamicallyFiltered() 252d6d97f60SAnna Dabrowska { 253b7e1d73bSAndreas Gohr if ($this->mode != 'xhtml') return false; 254b7e1d73bSAndreas Gohr if (!$this->data['dynfilters']) return false; 255b7e1d73bSAndreas Gohr 256b7e1d73bSAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 257b7e1d73bSAndreas Gohr return (bool)$dynamic->getFilters(); 258b7e1d73bSAndreas Gohr } 259b7e1d73bSAndreas Gohr 260b7e1d73bSAndreas Gohr /** 26107993756SAndreas Gohr * Add input fields for dynamic filtering 26207993756SAndreas Gohr */ 263d6d97f60SAnna Dabrowska protected function renderDynamicFilters() 264d6d97f60SAnna Dabrowska { 26507993756SAndreas Gohr if ($this->mode != 'xhtml') return; 2661ca21e17SAnna Dabrowska if (empty($this->data['dynfilters'])) return; 2671bc467a4SMichael Grosse if (is_a($this->renderer, 'renderer_plugin_dw2pdf')) { 268e6ae02ecSMichael Grosse return; 269e6ae02ecSMichael Grosse } 2701bc467a4SMichael Grosse global $conf; 27107993756SAndreas Gohr 27207993756SAndreas Gohr $this->renderer->doc .= '<tr class="dataflt">'; 27307993756SAndreas Gohr 27407993756SAndreas Gohr // add extra column for row numbers 27507993756SAndreas Gohr if ($this->data['rownumbers']) { 27607993756SAndreas Gohr $this->renderer->doc .= '<th></th>'; 27707993756SAndreas Gohr } 27807993756SAndreas Gohr 27907993756SAndreas Gohr // each column gets a form 28007993756SAndreas Gohr foreach ($this->columns as $column) { 28107993756SAndreas Gohr $this->renderer->doc .= '<th>'; 28217a3a578SAndreas Gohr 28317a3a578SAndreas Gohr // BEGIN FORM 2844b00515cSAnna Dabrowska $form = new \Doku_Form( 2854b00515cSAnna Dabrowska [ 2864b00515cSAnna Dabrowska 'method' => 'GET', 2874b00515cSAnna Dabrowska 'action' => wl($this->id, $this->renderer->info['struct_table_hash'], false, '#') 2884b00515cSAnna Dabrowska ] 2894b00515cSAnna Dabrowska ); 29076195677SAndreas Gohr unset($form->_hidden['sectok']); // we don't need it here 29176195677SAndreas Gohr if (!$conf['userewrite']) $form->addHidden('id', $this->id); 29207993756SAndreas Gohr 29307993756SAndreas Gohr // current value 29407993756SAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 29507993756SAndreas Gohr $filters = $dynamic->getFilters(); 29607993756SAndreas Gohr if (isset($filters[$column->getFullQualifiedLabel()])) { 2977234bfb1Ssplitbrain [, $current] = $filters[$column->getFullQualifiedLabel()]; 29807993756SAndreas Gohr $dynamic->removeFilter($column); 29907993756SAndreas Gohr } else { 30007993756SAndreas Gohr $current = ''; 30107993756SAndreas Gohr } 30207993756SAndreas Gohr 30307993756SAndreas Gohr // Add current request params 30407993756SAndreas Gohr $params = $dynamic->getURLParameters(); 30507993756SAndreas Gohr foreach ($params as $key => $val) { 30607993756SAndreas Gohr $form->addHidden($key, $val); 30707993756SAndreas Gohr } 30807993756SAndreas Gohr 30907993756SAndreas Gohr // add input field 310db9b8745SAndreas Gohr $key = $column->getFullQualifiedLabel() . $column->getType()->getDefaultComparator(); 31117a3a578SAndreas Gohr $form->addElement( 31217a3a578SAndreas Gohr form_makeField('text', SearchConfigParameters::$PARAM_FILTER . '[' . $key . ']', $current, '') 31317a3a578SAndreas Gohr ); 31407993756SAndreas Gohr $this->renderer->doc .= $form->getForm(); 31517a3a578SAndreas Gohr // END FORM 31617a3a578SAndreas Gohr 31707993756SAndreas Gohr $this->renderer->doc .= '</th>'; 31807993756SAndreas Gohr } 31907993756SAndreas Gohr $this->renderer->doc .= '</tr>'; 32007993756SAndreas Gohr } 32107993756SAndreas Gohr 32207993756SAndreas Gohr /** 32307993756SAndreas Gohr * Display the actual table data 32407993756SAndreas Gohr */ 325d6d97f60SAnna Dabrowska protected function renderResult() 326d6d97f60SAnna Dabrowska { 32707993756SAndreas Gohr foreach ($this->result as $rownum => $row) { 3287fe2cdf2SAndreas Gohr $data = [ 32947eb8cceSSzymon Olewniczak 'id' => $this->id, 33047eb8cceSSzymon Olewniczak 'mode' => $this->mode, 33147eb8cceSSzymon Olewniczak 'renderer' => $this->renderer, 33247eb8cceSSzymon Olewniczak 'searchConfig' => $this->searchConfig, 33347eb8cceSSzymon Olewniczak 'data' => $this->data, 33447eb8cceSSzymon Olewniczak 'rownum' => &$rownum, 3357fe2cdf2SAndreas Gohr 'row' => &$row 3367fe2cdf2SAndreas Gohr ]; 3377234bfb1Ssplitbrain $evt = new Event('PLUGIN_STRUCT_AGGREGATIONTABLE_RENDERRESULTROW', $data); 33847eb8cceSSzymon Olewniczak if ($evt->advise_before()) { 339f107f479SAndreas Gohr $this->renderResultRow($rownum, $row); 340f107f479SAndreas Gohr } 34147eb8cceSSzymon Olewniczak $evt->advise_after(); 34247eb8cceSSzymon Olewniczak } 343f107f479SAndreas Gohr } 344f107f479SAndreas Gohr 345f107f479SAndreas Gohr /** 346f107f479SAndreas Gohr * Render a single result row 347f107f479SAndreas Gohr * 348f107f479SAndreas Gohr * @param int $rownum 349f107f479SAndreas Gohr * @param array $row 350f107f479SAndreas Gohr */ 351d6d97f60SAnna Dabrowska protected function renderResultRow($rownum, $row) 352d6d97f60SAnna Dabrowska { 35307993756SAndreas Gohr $this->renderer->tablerow_open(); 35407993756SAndreas Gohr 355d4b5a17cSAndreas Gohr // add data attribute for inline edit 356d4b5a17cSAndreas Gohr if ($this->mode == 'xhtml') { 357d4b5a17cSAndreas Gohr $pid = $this->resultPIDs[$rownum]; 3580ceefd5cSAnna Dabrowska $rid = $this->resultRids[$rownum]; 3596fd73b4bSAnna Dabrowska $rev = $this->resultRevs[$rownum]; 360d4b5a17cSAndreas Gohr $this->renderer->doc = substr(rtrim($this->renderer->doc), 0, -1); // remove closing '>' 3616fd73b4bSAnna Dabrowska $this->renderer->doc .= ' data-pid="' . hsc($pid) . '" data-rev="' . $rev . '" data-rid="' . $rid . '">'; 362d4b5a17cSAndreas Gohr } 363d4b5a17cSAndreas Gohr 36407993756SAndreas Gohr // row number column 36534ea6e10SAnna Dabrowska if (!empty($this->data['rownumbers'])) { 36607993756SAndreas Gohr $this->renderer->tablecell_open(); 367fdf37115SAndreas Gohr $this->renderer->cdata($rownum + $this->searchConfig->getOffset() + 1); 36807993756SAndreas Gohr $this->renderer->tablecell_close(); 36907993756SAndreas Gohr } 37007993756SAndreas Gohr 37107993756SAndreas Gohr /** @var Value $value */ 37207993756SAndreas Gohr foreach ($row as $colnum => $value) { 3737234bfb1Ssplitbrain $align = $this->data['align'][$colnum] ?? null; 37434ea6e10SAnna Dabrowska $this->renderer->tablecell_open(1, $align); 37507993756SAndreas Gohr $value->render($this->renderer, $this->mode); 37607993756SAndreas Gohr $this->renderer->tablecell_close(); 37707993756SAndreas Gohr 37807993756SAndreas Gohr // summarize 3791ca21e17SAnna Dabrowska if (!empty($this->data['summarize']) && is_numeric($value->getValue())) { 38007993756SAndreas Gohr if (!isset($this->sums[$colnum])) { 38107993756SAndreas Gohr $this->sums[$colnum] = 0; 38207993756SAndreas Gohr } 38307993756SAndreas Gohr $this->sums[$colnum] += $value->getValue(); 38407993756SAndreas Gohr } 38507993756SAndreas Gohr } 38607993756SAndreas Gohr $this->renderer->tablerow_close(); 38707993756SAndreas Gohr } 38807993756SAndreas Gohr 38907993756SAndreas Gohr /** 39007993756SAndreas Gohr * Renders an information row for when no results were found 39107993756SAndreas Gohr */ 392d6d97f60SAnna Dabrowska protected function renderEmptyResult() 393d6d97f60SAnna Dabrowska { 39407993756SAndreas Gohr $this->renderer->tablerow_open(); 39570cf6339SAndreas Gohr $this->renderer->tablecell_open(count($this->columns) + $this->data['rownumbers'], 'center'); 39607993756SAndreas Gohr $this->renderer->cdata($this->helper->getLang('none')); 39707993756SAndreas Gohr $this->renderer->tablecell_close(); 39807993756SAndreas Gohr $this->renderer->tablerow_close(); 39907993756SAndreas Gohr } 40007993756SAndreas Gohr 40107993756SAndreas Gohr /** 40207993756SAndreas Gohr * Add sums if wanted 40307993756SAndreas Gohr */ 404d6d97f60SAnna Dabrowska protected function renderSums() 405d6d97f60SAnna Dabrowska { 406d18090e8SAndreas Gohr if (empty($this->data['summarize'])) return; 40707993756SAndreas Gohr 408a0bf8bb2SAndreas Gohr $this->renderer->info['struct_table_meta'] = true; 4098925ba29SAndreas Gohr if ($this->mode == 'xhtml') { 4108925ba29SAndreas Gohr /** @noinspection PhpMethodParametersCountMismatchInspection */ 4118925ba29SAndreas Gohr $this->renderer->tablerow_open('summarize'); 4128925ba29SAndreas Gohr } else { 41307993756SAndreas Gohr $this->renderer->tablerow_open(); 4148925ba29SAndreas Gohr } 41507993756SAndreas Gohr 41607993756SAndreas Gohr if ($this->data['rownumbers']) { 4178925ba29SAndreas Gohr $this->renderer->tableheader_open(); 4188925ba29SAndreas Gohr $this->renderer->tableheader_close(); 41907993756SAndreas Gohr } 42007993756SAndreas Gohr 421aee4116bSAndreas Gohr $len = count($this->columns); 42207993756SAndreas Gohr for ($i = 0; $i < $len; $i++) { 4238925ba29SAndreas Gohr $this->renderer->tableheader_open(1, $this->data['align'][$i]); 424aee4116bSAndreas Gohr if (!empty($this->sums[$i])) { 4259b97e610SAndreas Gohr $this->renderer->cdata('∑ '); 4269b97e610SAndreas Gohr $this->columns[$i]->getType()->renderValue($this->sums[$i], $this->renderer, $this->mode); 4277234bfb1Ssplitbrain } elseif ($this->mode == 'xhtml') { 42807993756SAndreas Gohr $this->renderer->doc .= ' '; 42907993756SAndreas Gohr } 4308925ba29SAndreas Gohr $this->renderer->tableheader_close(); 43107993756SAndreas Gohr } 43207993756SAndreas Gohr $this->renderer->tablerow_close(); 433a0bf8bb2SAndreas Gohr $this->renderer->info['struct_table_meta'] = false; 43407993756SAndreas Gohr } 43507993756SAndreas Gohr 43607993756SAndreas Gohr /** 437986ab7e6SAndreas Gohr * Adds paging controls to the table 43807993756SAndreas Gohr */ 439d6d97f60SAnna Dabrowska protected function renderPagingControls() 440d6d97f60SAnna Dabrowska { 441a0bf8bb2SAndreas Gohr if ($this->mode != 'xhtml') return; 44207993756SAndreas Gohr 443fdf37115SAndreas Gohr $limit = $this->searchConfig->getLimit(); 444fdf37115SAndreas Gohr if (!$limit) return; 445fdf37115SAndreas Gohr $offset = $this->searchConfig->getOffset(); 446fdf37115SAndreas Gohr 447a0bf8bb2SAndreas Gohr $this->renderer->info['struct_table_meta'] = true; 44807993756SAndreas Gohr $this->renderer->tablerow_open(); 4494bc1074dSMichael Grosse $this->renderer->tableheader_open((count($this->columns) + ($this->data['rownumbers'] ? 1 : 0))); 450fdf37115SAndreas Gohr 45107993756SAndreas Gohr 45207993756SAndreas Gohr // prev link 45307993756SAndreas Gohr if ($offset) { 454fdf37115SAndreas Gohr $prev = $offset - $limit; 45507993756SAndreas Gohr if ($prev < 0) { 45607993756SAndreas Gohr $prev = 0; 45707993756SAndreas Gohr } 45807993756SAndreas Gohr 45907993756SAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 46007993756SAndreas Gohr $dynamic->setOffset($prev); 46107993756SAndreas Gohr $link = wl($this->id, $dynamic->getURLParameters()); 46207993756SAndreas Gohr $this->renderer->doc .= '<a href="' . $link . '" class="prev">' . $this->helper->getLang('prev') . '</a>'; 46307993756SAndreas Gohr } 46407993756SAndreas Gohr 46507993756SAndreas Gohr // next link 466fdf37115SAndreas Gohr if ($this->resultCount > $offset + $limit) { 467fdf37115SAndreas Gohr $next = $offset + $limit; 46807993756SAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 46907993756SAndreas Gohr $dynamic->setOffset($next); 47007993756SAndreas Gohr $link = wl($this->id, $dynamic->getURLParameters()); 47107993756SAndreas Gohr $this->renderer->doc .= '<a href="' . $link . '" class="next">' . $this->helper->getLang('next') . '</a>'; 47207993756SAndreas Gohr } 47307993756SAndreas Gohr 47407993756SAndreas Gohr $this->renderer->tableheader_close(); 47507993756SAndreas Gohr $this->renderer->tablerow_close(); 476a0bf8bb2SAndreas Gohr $this->renderer->info['struct_table_meta'] = true; 47707993756SAndreas Gohr } 47809dd691aSAndreas Gohr 47909dd691aSAndreas Gohr /** 48009dd691aSAndreas Gohr * Adds CSV export controls 48109dd691aSAndreas Gohr */ 482d6d97f60SAnna Dabrowska protected function renderExportControls() 483d6d97f60SAnna Dabrowska { 48409dd691aSAndreas Gohr if ($this->mode != 'xhtml') return; 4857b240ca8SAndreas Gohr if (empty($this->data['csv'])) return; 48609dd691aSAndreas Gohr if (!$this->resultCount) return; 48709dd691aSAndreas Gohr 488c8ccdaf8SAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 489c8ccdaf8SAndreas Gohr $params = $dynamic->getURLParameters(); 490c8ccdaf8SAndreas Gohr $params['hash'] = $this->renderer->info['struct_table_hash']; 491c8ccdaf8SAndreas Gohr 49209dd691aSAndreas Gohr // FIXME apply dynamic filters 493eafc109fSAndreas Gohr $link = exportlink($this->id, 'struct_csv', $params); 49409dd691aSAndreas Gohr 49517a3a578SAndreas Gohr $this->renderer->doc .= '<a href="' . $link . '" class="export mediafile mf_csv">' . 49617a3a578SAndreas Gohr $this->helper->getLang('csvexport') . '</a>'; 49709dd691aSAndreas Gohr } 49807993756SAndreas Gohr} 499