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 1767f70d54SAnna Dabrowska public function __construct($id, $mode, \Doku_Renderer $renderer, SearchConfig $searchConfig) 1867f70d54SAnna Dabrowska { 1967f70d54SAnna Dabrowska parent::__construct($id, $mode, $renderer, $searchConfig); 2067f70d54SAnna Dabrowska } 2167f70d54SAnna Dabrowska 22d90aa848SAndreas Gohr /** @inheritdoc */ 23d90aa848SAndreas Gohr public function render($showNotFound = false) 24d6d97f60SAnna Dabrowska { 25*ba7f5789SAnna Dabrowska if (in_array($this->mode, \helper_plugin_struct::BLACKLIST_RENDERER)) return; 2667f70d54SAnna Dabrowska 27b7e1d73bSAndreas Gohr // abort early if there are no results at all (not filtered) 28*ba7f5789SAnna Dabrowska if ($this->searchConfig->getCount() <= 0 && !$this->isDynamicallyFiltered() && $showNotFound) { 29b7e1d73bSAndreas Gohr $this->renderer->cdata($this->helper->getLang('none')); 30b7e1d73bSAndreas Gohr return; 31b7e1d73bSAndreas Gohr } 32b7e1d73bSAndreas Gohr 33986ab7e6SAndreas Gohr $this->renderActiveFilters(); 34844a4f01SFrieder Schrempf 357fe2cdf2SAndreas Gohr $rendercontext = [ 36844a4f01SFrieder Schrempf 'table' => $this, 37844a4f01SFrieder Schrempf 'renderer' => $this->renderer, 383f640228SFrieder Schrempf 'format' => $this->mode, 39844a4f01SFrieder Schrempf 'search' => $this->searchConfig, 40844a4f01SFrieder Schrempf 'columns' => $this->columns, 41*ba7f5789SAnna Dabrowska 'data' => $this->searchConfig->getRows() 427fe2cdf2SAndreas Gohr ]; 43844a4f01SFrieder Schrempf 447234bfb1Ssplitbrain $event = new Event( 45844a4f01SFrieder Schrempf 'PLUGIN_STRUCT_RENDER_AGGREGATION_TABLE', 462dbe71f8SAnna Dabrowska $rendercontext 47844a4f01SFrieder Schrempf ); 482dbe71f8SAnna Dabrowska $event->trigger([$this, 'renderTable']); 49844a4f01SFrieder Schrempf 50844a4f01SFrieder Schrempf // export handle 51844a4f01SFrieder Schrempf $this->renderExportControls(); 52844a4f01SFrieder Schrempf } 53844a4f01SFrieder Schrempf 54844a4f01SFrieder Schrempf /** 55844a4f01SFrieder Schrempf * Render the default aggregation table 56844a4f01SFrieder Schrempf */ 57844a4f01SFrieder Schrempf public function renderTable($rendercontext) 58844a4f01SFrieder Schrempf { 5907993756SAndreas Gohr $this->renderer->table_open(); 6007993756SAndreas Gohr 6107993756SAndreas Gohr // header 6207993756SAndreas Gohr $this->renderer->tablethead_open(); 63986ab7e6SAndreas Gohr $this->renderColumnHeaders(); 64986ab7e6SAndreas Gohr $this->renderDynamicFilters(); 6507993756SAndreas Gohr $this->renderer->tablethead_close(); 6607993756SAndreas Gohr 67*ba7f5789SAnna Dabrowska if ($this->searchConfig->getCount()) { 6807993756SAndreas Gohr // actual data 69a9fd81f9SAndreas Gohr $this->renderer->tabletbody_open(); 70986ab7e6SAndreas Gohr $this->renderResult(); 71a9fd81f9SAndreas Gohr $this->renderer->tabletbody_close(); 7207993756SAndreas Gohr 73a9fd81f9SAndreas Gohr // footer (tfoot is develonly currently) 74a9fd81f9SAndreas Gohr if (method_exists($this->renderer, 'tabletfoot_open')) $this->renderer->tabletfoot_open(); 75986ab7e6SAndreas Gohr $this->renderSums(); 76986ab7e6SAndreas Gohr $this->renderPagingControls(); 77a9fd81f9SAndreas Gohr if (method_exists($this->renderer, 'tabletfoot_close')) $this->renderer->tabletfoot_close(); 7807993756SAndreas Gohr } else { 7907993756SAndreas Gohr // nothing found 80986ab7e6SAndreas Gohr $this->renderEmptyResult(); 8107993756SAndreas Gohr } 8207993756SAndreas Gohr 8307993756SAndreas Gohr // table close 8407993756SAndreas Gohr $this->renderer->table_close(); 8507993756SAndreas Gohr } 8607993756SAndreas Gohr 8707993756SAndreas Gohr /** 8807993756SAndreas Gohr * Adds additional info to document and renderer in XHTML mode 8907993756SAndreas Gohr * 9007993756SAndreas Gohr * @see finishScope() 9107993756SAndreas Gohr */ 92af0ce8d2SAndreas Gohr public function startScope() 93d6d97f60SAnna Dabrowska { 9407993756SAndreas Gohr // unique identifier for this aggregation 9507993756SAndreas Gohr $this->renderer->info['struct_table_hash'] = md5(var_export($this->data, true)); 9609dd691aSAndreas Gohr 97af0ce8d2SAndreas Gohr parent::startScope(); 9807993756SAndreas Gohr } 9907993756SAndreas Gohr 10007993756SAndreas Gohr /** 10107993756SAndreas Gohr * Closes the table and anything opened in startScope() 10207993756SAndreas Gohr * 10307993756SAndreas Gohr * @see startScope() 10407993756SAndreas Gohr */ 105af0ce8d2SAndreas Gohr public function finishScope() 106d6d97f60SAnna Dabrowska { 10707993756SAndreas Gohr // remove identifier from renderer again 10807993756SAndreas Gohr if (isset($this->renderer->info['struct_table_hash'])) { 10907993756SAndreas Gohr unset($this->renderer->info['struct_table_hash']); 11007993756SAndreas Gohr } 11109dd691aSAndreas Gohr 112af0ce8d2SAndreas Gohr parent::finishScope(); 11307993756SAndreas Gohr } 11407993756SAndreas Gohr 11507993756SAndreas Gohr /** 11607993756SAndreas Gohr * Displays info about the currently applied filters 11707993756SAndreas Gohr */ 118d6d97f60SAnna Dabrowska protected function renderActiveFilters() 119d6d97f60SAnna Dabrowska { 12007993756SAndreas Gohr if ($this->mode != 'xhtml') return; 12107993756SAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 12207993756SAndreas Gohr $filters = $dynamic->getFilters(); 12307993756SAndreas Gohr if (!$filters) return; 12407993756SAndreas Gohr 1257234bfb1Ssplitbrain $fltrs = []; 12607993756SAndreas Gohr foreach ($filters as $column => $filter) { 1277234bfb1Ssplitbrain [$comp, $value] = $filter; 12804ec4785SAnna Dabrowska 12904ec4785SAnna Dabrowska // display the filters in a human readable format 13004ec4785SAnna Dabrowska foreach ($this->columns as $col) { 13104ec4785SAnna Dabrowska if ($column === $col->getFullQualifiedLabel()) { 13204ec4785SAnna Dabrowska $column = $col->getTranslatedLabel(); 13304ec4785SAnna Dabrowska } 13404ec4785SAnna Dabrowska } 1351f075418SAnna Dabrowska $fltrs[] = sprintf('"%s" %s "%s"', $column, $this->helper->getLang("comparator $comp"), $value); 13607993756SAndreas Gohr } 13707993756SAndreas Gohr 13807993756SAndreas Gohr $this->renderer->doc .= '<div class="filter">'; 13917a3a578SAndreas Gohr $this->renderer->doc .= '<h4>' . 14017a3a578SAndreas Gohr sprintf( 14117a3a578SAndreas Gohr $this->helper->getLang('tablefilteredby'), 14217a3a578SAndreas Gohr hsc(implode(' & ', $fltrs)) 14317a3a578SAndreas Gohr ) . 14417a3a578SAndreas Gohr '</h4>'; 14507993756SAndreas Gohr $this->renderer->doc .= '<div class="resetfilter">'; 14607993756SAndreas Gohr $this->renderer->internallink($this->id, $this->helper->getLang('tableresetfilter')); 14707993756SAndreas Gohr $this->renderer->doc .= '</div>'; 14807993756SAndreas Gohr $this->renderer->doc .= '</div>'; 14907993756SAndreas Gohr } 15007993756SAndreas Gohr 15107993756SAndreas Gohr /** 15207993756SAndreas Gohr * Shows the column headers with links to sort by column 15307993756SAndreas Gohr */ 154d6d97f60SAnna Dabrowska protected function renderColumnHeaders() 155d6d97f60SAnna Dabrowska { 15607993756SAndreas Gohr $this->renderer->tablerow_open(); 15707993756SAndreas Gohr 15807993756SAndreas Gohr // additional column for row numbers 15934ea6e10SAnna Dabrowska if (!empty($this->data['rownumbers'])) { 16007993756SAndreas Gohr $this->renderer->tableheader_open(); 16107993756SAndreas Gohr $this->renderer->cdata('#'); 16207993756SAndreas Gohr $this->renderer->tableheader_close(); 16307993756SAndreas Gohr } 16407993756SAndreas Gohr 16507993756SAndreas Gohr // show all headers 1668c4ee9beSAndreas Gohr foreach ($this->columns as $num => $column) { 1678c4ee9beSAndreas Gohr $header = ''; 1688c4ee9beSAndreas Gohr if (isset($this->data['headers'][$num])) { 1698c4ee9beSAndreas Gohr $header = $this->data['headers'][$num]; 1708c4ee9beSAndreas Gohr } 17107993756SAndreas Gohr 17207993756SAndreas Gohr // use field label if no header was set 17307993756SAndreas Gohr if (blank($header)) { 17401f8b845SAndreas Gohr if (is_a($column, 'dokuwiki\plugin\struct\meta\Column')) { 17507993756SAndreas Gohr $header = $column->getTranslatedLabel(); 17607993756SAndreas Gohr } else { 17707993756SAndreas Gohr $header = 'column ' . $num; // this should never happen 17807993756SAndreas Gohr } 17907993756SAndreas Gohr } 18007993756SAndreas Gohr 18107993756SAndreas Gohr // simple mode first 18207993756SAndreas Gohr if ($this->mode != 'xhtml') { 18307993756SAndreas Gohr $this->renderer->tableheader_open(); 18407993756SAndreas Gohr $this->renderer->cdata($header); 18507993756SAndreas Gohr $this->renderer->tableheader_close(); 18607993756SAndreas Gohr continue; 18707993756SAndreas Gohr } 18807993756SAndreas Gohr 18907993756SAndreas Gohr // still here? create custom header for more flexibility 19007993756SAndreas Gohr 1919113d04aSAndreas Gohr // width setting, widths are prevalidated, no escape needed 19207993756SAndreas Gohr $width = ''; 1939113d04aSAndreas Gohr if (isset($this->data['widths'][$num]) && $this->data['widths'][$num] != '-') { 1949113d04aSAndreas Gohr $width = ' style="min-width: ' . $this->data['widths'][$num] . ';' . 1959113d04aSAndreas Gohr 'max-width: ' . $this->data['widths'][$num] . ';"'; 19607993756SAndreas Gohr } 19707993756SAndreas Gohr 198d4b5a17cSAndreas Gohr // prepare data attribute for inline edits 199d6d97f60SAnna Dabrowska if ( 200d6d97f60SAnna Dabrowska !is_a($column, '\dokuwiki\plugin\struct\meta\PageColumn') && 201d4b5a17cSAndreas Gohr !is_a($column, '\dokuwiki\plugin\struct\meta\RevisionColumn') 202d4b5a17cSAndreas Gohr ) { 203d4b5a17cSAndreas Gohr $data = 'data-field="' . hsc($column->getFullQualifiedLabel()) . '"'; 204d4b5a17cSAndreas Gohr } else { 205d4b5a17cSAndreas Gohr $data = ''; 206d4b5a17cSAndreas Gohr } 207d4b5a17cSAndreas Gohr 20807993756SAndreas Gohr // sort indicator and link 20907993756SAndreas Gohr $sortclass = ''; 21007993756SAndreas Gohr $sorts = $this->searchConfig->getSorts(); 21107993756SAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 212aa124708SAndreas Gohr $dynamic->setSort($column, true); 21307993756SAndreas Gohr if (isset($sorts[$column->getFullQualifiedLabel()])) { 2147fe2cdf2SAndreas Gohr [/*colname*/, $currentSort] = $sorts[$column->getFullQualifiedLabel()]; 215aa124708SAndreas Gohr if ($currentSort) { 21607993756SAndreas Gohr $sortclass = 'sort-down'; 21707993756SAndreas Gohr $dynamic->setSort($column, false); 21807993756SAndreas Gohr } else { 21907993756SAndreas Gohr $sortclass = 'sort-up'; 22007993756SAndreas Gohr } 22107993756SAndreas Gohr } 22207993756SAndreas Gohr $link = wl($this->id, $dynamic->getURLParameters()); 22307993756SAndreas Gohr 22407993756SAndreas Gohr // output XHTML header 225d4b5a17cSAndreas Gohr $this->renderer->doc .= "<th $width $data>"; 2263ebc6780SAnna Dabrowska 227da7041d3SAlexander Yakovlev if (is_a($this->renderer, 'renderer_plugin_dw2pdf')) { 228da7041d3SAlexander Yakovlev $this->renderer->doc .= hsc($header); 229da7041d3SAlexander Yakovlev } else { 23017a3a578SAndreas Gohr $this->renderer->doc .= '<a href="' . $link . '" class="' . $sortclass . '" ' . 23117a3a578SAndreas Gohr 'title="' . $this->helper->getLang('sort') . '">' . hsc($header) . '</a>'; 232da7041d3SAlexander Yakovlev } 2333ebc6780SAnna Dabrowska 23407993756SAndreas Gohr $this->renderer->doc .= '</th>'; 23507993756SAndreas Gohr } 23607993756SAndreas Gohr 23707993756SAndreas Gohr $this->renderer->tablerow_close(); 23807993756SAndreas Gohr } 23907993756SAndreas Gohr 24007993756SAndreas Gohr /** 241b7e1d73bSAndreas Gohr * Is the result set currently dynamically filtered? 242b7e1d73bSAndreas Gohr * @return bool 243b7e1d73bSAndreas Gohr */ 244d6d97f60SAnna Dabrowska protected function isDynamicallyFiltered() 245d6d97f60SAnna Dabrowska { 246b7e1d73bSAndreas Gohr if ($this->mode != 'xhtml') return false; 247b7e1d73bSAndreas Gohr if (!$this->data['dynfilters']) return false; 248b7e1d73bSAndreas Gohr 249b7e1d73bSAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 250b7e1d73bSAndreas Gohr return (bool)$dynamic->getFilters(); 251b7e1d73bSAndreas Gohr } 252b7e1d73bSAndreas Gohr 253b7e1d73bSAndreas Gohr /** 25407993756SAndreas Gohr * Add input fields for dynamic filtering 25507993756SAndreas Gohr */ 256d6d97f60SAnna Dabrowska protected function renderDynamicFilters() 257d6d97f60SAnna Dabrowska { 25807993756SAndreas Gohr if ($this->mode != 'xhtml') return; 2591ca21e17SAnna Dabrowska if (empty($this->data['dynfilters'])) return; 2601bc467a4SMichael Grosse if (is_a($this->renderer, 'renderer_plugin_dw2pdf')) { 261e6ae02ecSMichael Grosse return; 262e6ae02ecSMichael Grosse } 2631bc467a4SMichael Grosse global $conf; 26407993756SAndreas Gohr 26507993756SAndreas Gohr $this->renderer->doc .= '<tr class="dataflt">'; 26607993756SAndreas Gohr 26707993756SAndreas Gohr // add extra column for row numbers 26807993756SAndreas Gohr if ($this->data['rownumbers']) { 26907993756SAndreas Gohr $this->renderer->doc .= '<th></th>'; 27007993756SAndreas Gohr } 27107993756SAndreas Gohr 27207993756SAndreas Gohr // each column gets a form 27307993756SAndreas Gohr foreach ($this->columns as $column) { 27407993756SAndreas Gohr $this->renderer->doc .= '<th>'; 27517a3a578SAndreas Gohr 27617a3a578SAndreas Gohr // BEGIN FORM 2774b00515cSAnna Dabrowska $form = new \Doku_Form( 2784b00515cSAnna Dabrowska [ 2794b00515cSAnna Dabrowska 'method' => 'GET', 2804b00515cSAnna Dabrowska 'action' => wl($this->id, $this->renderer->info['struct_table_hash'], false, '#') 2814b00515cSAnna Dabrowska ] 2824b00515cSAnna Dabrowska ); 28376195677SAndreas Gohr unset($form->_hidden['sectok']); // we don't need it here 28476195677SAndreas Gohr if (!$conf['userewrite']) $form->addHidden('id', $this->id); 28507993756SAndreas Gohr 28607993756SAndreas Gohr // current value 28707993756SAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 28807993756SAndreas Gohr $filters = $dynamic->getFilters(); 28907993756SAndreas Gohr if (isset($filters[$column->getFullQualifiedLabel()])) { 2907234bfb1Ssplitbrain [, $current] = $filters[$column->getFullQualifiedLabel()]; 29107993756SAndreas Gohr $dynamic->removeFilter($column); 29207993756SAndreas Gohr } else { 29307993756SAndreas Gohr $current = ''; 29407993756SAndreas Gohr } 29507993756SAndreas Gohr 29607993756SAndreas Gohr // Add current request params 29707993756SAndreas Gohr $params = $dynamic->getURLParameters(); 29807993756SAndreas Gohr foreach ($params as $key => $val) { 29907993756SAndreas Gohr $form->addHidden($key, $val); 30007993756SAndreas Gohr } 30107993756SAndreas Gohr 30207993756SAndreas Gohr // add input field 303db9b8745SAndreas Gohr $key = $column->getFullQualifiedLabel() . $column->getType()->getDefaultComparator(); 30417a3a578SAndreas Gohr $form->addElement( 30517a3a578SAndreas Gohr form_makeField('text', SearchConfigParameters::$PARAM_FILTER . '[' . $key . ']', $current, '') 30617a3a578SAndreas Gohr ); 30707993756SAndreas Gohr $this->renderer->doc .= $form->getForm(); 30817a3a578SAndreas Gohr // END FORM 30917a3a578SAndreas Gohr 31007993756SAndreas Gohr $this->renderer->doc .= '</th>'; 31107993756SAndreas Gohr } 31207993756SAndreas Gohr $this->renderer->doc .= '</tr>'; 31307993756SAndreas Gohr } 31407993756SAndreas Gohr 31507993756SAndreas Gohr /** 31607993756SAndreas Gohr * Display the actual table data 31707993756SAndreas Gohr */ 318d6d97f60SAnna Dabrowska protected function renderResult() 319d6d97f60SAnna Dabrowska { 320*ba7f5789SAnna Dabrowska foreach ($this->searchConfig->getRows() as $rownum => $row) { 3217fe2cdf2SAndreas Gohr $data = [ 32247eb8cceSSzymon Olewniczak 'id' => $this->id, 32347eb8cceSSzymon Olewniczak 'mode' => $this->mode, 32447eb8cceSSzymon Olewniczak 'renderer' => $this->renderer, 32547eb8cceSSzymon Olewniczak 'searchConfig' => $this->searchConfig, 32647eb8cceSSzymon Olewniczak 'data' => $this->data, 32747eb8cceSSzymon Olewniczak 'rownum' => &$rownum, 3287fe2cdf2SAndreas Gohr 'row' => &$row 3297fe2cdf2SAndreas Gohr ]; 3307234bfb1Ssplitbrain $evt = new Event('PLUGIN_STRUCT_AGGREGATIONTABLE_RENDERRESULTROW', $data); 33147eb8cceSSzymon Olewniczak if ($evt->advise_before()) { 332f107f479SAndreas Gohr $this->renderResultRow($rownum, $row); 333f107f479SAndreas Gohr } 33447eb8cceSSzymon Olewniczak $evt->advise_after(); 33547eb8cceSSzymon Olewniczak } 336f107f479SAndreas Gohr } 337f107f479SAndreas Gohr 338f107f479SAndreas Gohr /** 339f107f479SAndreas Gohr * Render a single result row 340f107f479SAndreas Gohr * 341f107f479SAndreas Gohr * @param int $rownum 342f107f479SAndreas Gohr * @param array $row 343f107f479SAndreas Gohr */ 344d6d97f60SAnna Dabrowska protected function renderResultRow($rownum, $row) 345d6d97f60SAnna Dabrowska { 34607993756SAndreas Gohr $this->renderer->tablerow_open(); 34707993756SAndreas Gohr 348d4b5a17cSAndreas Gohr // add data attribute for inline edit 349d4b5a17cSAndreas Gohr if ($this->mode == 'xhtml') { 350*ba7f5789SAnna Dabrowska $pid = $this->searchConfig->getPids()[$rownum]; 351*ba7f5789SAnna Dabrowska $rid = $this->searchConfig->getRids()[$rownum]; 352*ba7f5789SAnna Dabrowska $rev = $this->searchConfig->getRevs()[$rownum]; 353d4b5a17cSAndreas Gohr $this->renderer->doc = substr(rtrim($this->renderer->doc), 0, -1); // remove closing '>' 3546fd73b4bSAnna Dabrowska $this->renderer->doc .= ' data-pid="' . hsc($pid) . '" data-rev="' . $rev . '" data-rid="' . $rid . '">'; 355d4b5a17cSAndreas Gohr } 356d4b5a17cSAndreas Gohr 35707993756SAndreas Gohr // row number column 35834ea6e10SAnna Dabrowska if (!empty($this->data['rownumbers'])) { 35907993756SAndreas Gohr $this->renderer->tablecell_open(); 360fdf37115SAndreas Gohr $this->renderer->cdata($rownum + $this->searchConfig->getOffset() + 1); 36107993756SAndreas Gohr $this->renderer->tablecell_close(); 36207993756SAndreas Gohr } 36307993756SAndreas Gohr 36407993756SAndreas Gohr /** @var Value $value */ 36507993756SAndreas Gohr foreach ($row as $colnum => $value) { 3667234bfb1Ssplitbrain $align = $this->data['align'][$colnum] ?? null; 36734ea6e10SAnna Dabrowska $this->renderer->tablecell_open(1, $align); 36807993756SAndreas Gohr $value->render($this->renderer, $this->mode); 36907993756SAndreas Gohr $this->renderer->tablecell_close(); 37007993756SAndreas Gohr 37107993756SAndreas Gohr // summarize 3721ca21e17SAnna Dabrowska if (!empty($this->data['summarize']) && is_numeric($value->getValue())) { 37307993756SAndreas Gohr if (!isset($this->sums[$colnum])) { 37407993756SAndreas Gohr $this->sums[$colnum] = 0; 37507993756SAndreas Gohr } 37607993756SAndreas Gohr $this->sums[$colnum] += $value->getValue(); 37707993756SAndreas Gohr } 37807993756SAndreas Gohr } 37907993756SAndreas Gohr $this->renderer->tablerow_close(); 38007993756SAndreas Gohr } 38107993756SAndreas Gohr 38207993756SAndreas Gohr /** 38307993756SAndreas Gohr * Renders an information row for when no results were found 38407993756SAndreas Gohr */ 385d6d97f60SAnna Dabrowska protected function renderEmptyResult() 386d6d97f60SAnna Dabrowska { 38707993756SAndreas Gohr $this->renderer->tablerow_open(); 38870cf6339SAndreas Gohr $this->renderer->tablecell_open(count($this->columns) + $this->data['rownumbers'], 'center'); 38907993756SAndreas Gohr $this->renderer->cdata($this->helper->getLang('none')); 39007993756SAndreas Gohr $this->renderer->tablecell_close(); 39107993756SAndreas Gohr $this->renderer->tablerow_close(); 39207993756SAndreas Gohr } 39307993756SAndreas Gohr 39407993756SAndreas Gohr /** 39507993756SAndreas Gohr * Add sums if wanted 39607993756SAndreas Gohr */ 397d6d97f60SAnna Dabrowska protected function renderSums() 398d6d97f60SAnna Dabrowska { 399d18090e8SAndreas Gohr if (empty($this->data['summarize'])) return; 40007993756SAndreas Gohr 401a0bf8bb2SAndreas Gohr $this->renderer->info['struct_table_meta'] = true; 4028925ba29SAndreas Gohr if ($this->mode == 'xhtml') { 4038925ba29SAndreas Gohr $this->renderer->tablerow_open('summarize'); 4048925ba29SAndreas Gohr } else { 40507993756SAndreas Gohr $this->renderer->tablerow_open(); 4068925ba29SAndreas Gohr } 40707993756SAndreas Gohr 40807993756SAndreas Gohr if ($this->data['rownumbers']) { 4098925ba29SAndreas Gohr $this->renderer->tableheader_open(); 4108925ba29SAndreas Gohr $this->renderer->tableheader_close(); 41107993756SAndreas Gohr } 41207993756SAndreas Gohr 413aee4116bSAndreas Gohr $len = count($this->columns); 41407993756SAndreas Gohr for ($i = 0; $i < $len; $i++) { 4158925ba29SAndreas Gohr $this->renderer->tableheader_open(1, $this->data['align'][$i]); 416aee4116bSAndreas Gohr if (!empty($this->sums[$i])) { 4179b97e610SAndreas Gohr $this->renderer->cdata('∑ '); 4189b97e610SAndreas Gohr $this->columns[$i]->getType()->renderValue($this->sums[$i], $this->renderer, $this->mode); 4197234bfb1Ssplitbrain } elseif ($this->mode == 'xhtml') { 42007993756SAndreas Gohr $this->renderer->doc .= ' '; 42107993756SAndreas Gohr } 4228925ba29SAndreas Gohr $this->renderer->tableheader_close(); 42307993756SAndreas Gohr } 42407993756SAndreas Gohr $this->renderer->tablerow_close(); 425a0bf8bb2SAndreas Gohr $this->renderer->info['struct_table_meta'] = false; 42607993756SAndreas Gohr } 42707993756SAndreas Gohr 42807993756SAndreas Gohr /** 429986ab7e6SAndreas Gohr * Adds paging controls to the table 43007993756SAndreas Gohr */ 431d6d97f60SAnna Dabrowska protected function renderPagingControls() 432d6d97f60SAnna Dabrowska { 433a0bf8bb2SAndreas Gohr if ($this->mode != 'xhtml') return; 43407993756SAndreas Gohr 435fdf37115SAndreas Gohr $limit = $this->searchConfig->getLimit(); 436fdf37115SAndreas Gohr if (!$limit) return; 437fdf37115SAndreas Gohr $offset = $this->searchConfig->getOffset(); 438fdf37115SAndreas Gohr 439a0bf8bb2SAndreas Gohr $this->renderer->info['struct_table_meta'] = true; 44007993756SAndreas Gohr $this->renderer->tablerow_open(); 4414bc1074dSMichael Grosse $this->renderer->tableheader_open((count($this->columns) + ($this->data['rownumbers'] ? 1 : 0))); 442fdf37115SAndreas Gohr 44307993756SAndreas Gohr 44407993756SAndreas Gohr // prev link 44507993756SAndreas Gohr if ($offset) { 446fdf37115SAndreas Gohr $prev = $offset - $limit; 44707993756SAndreas Gohr if ($prev < 0) { 44807993756SAndreas Gohr $prev = 0; 44907993756SAndreas Gohr } 45007993756SAndreas Gohr 45107993756SAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 45207993756SAndreas Gohr $dynamic->setOffset($prev); 45307993756SAndreas Gohr $link = wl($this->id, $dynamic->getURLParameters()); 45407993756SAndreas Gohr $this->renderer->doc .= '<a href="' . $link . '" class="prev">' . $this->helper->getLang('prev') . '</a>'; 45507993756SAndreas Gohr } 45607993756SAndreas Gohr 45707993756SAndreas Gohr // next link 458*ba7f5789SAnna Dabrowska if ($this->searchConfig->getCount() > $offset + $limit) { 459fdf37115SAndreas Gohr $next = $offset + $limit; 46007993756SAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 46107993756SAndreas Gohr $dynamic->setOffset($next); 46207993756SAndreas Gohr $link = wl($this->id, $dynamic->getURLParameters()); 46307993756SAndreas Gohr $this->renderer->doc .= '<a href="' . $link . '" class="next">' . $this->helper->getLang('next') . '</a>'; 46407993756SAndreas Gohr } 46507993756SAndreas Gohr 46607993756SAndreas Gohr $this->renderer->tableheader_close(); 46707993756SAndreas Gohr $this->renderer->tablerow_close(); 468a0bf8bb2SAndreas Gohr $this->renderer->info['struct_table_meta'] = true; 46907993756SAndreas Gohr } 47009dd691aSAndreas Gohr 47109dd691aSAndreas Gohr /** 47209dd691aSAndreas Gohr * Adds CSV export controls 47309dd691aSAndreas Gohr */ 474d6d97f60SAnna Dabrowska protected function renderExportControls() 475d6d97f60SAnna Dabrowska { 47609dd691aSAndreas Gohr if ($this->mode != 'xhtml') return; 4777b240ca8SAndreas Gohr if (empty($this->data['csv'])) return; 478*ba7f5789SAnna Dabrowska if (!$this->searchConfig->getCount()) return; 47909dd691aSAndreas Gohr 480c8ccdaf8SAndreas Gohr $dynamic = $this->searchConfig->getDynamicParameters(); 481c8ccdaf8SAndreas Gohr $params = $dynamic->getURLParameters(); 482c8ccdaf8SAndreas Gohr $params['hash'] = $this->renderer->info['struct_table_hash']; 483c8ccdaf8SAndreas Gohr 48409dd691aSAndreas Gohr // FIXME apply dynamic filters 485eafc109fSAndreas Gohr $link = exportlink($this->id, 'struct_csv', $params); 48609dd691aSAndreas Gohr 48717a3a578SAndreas Gohr $this->renderer->doc .= '<a href="' . $link . '" class="export mediafile mf_csv">' . 48817a3a578SAndreas Gohr $this->helper->getLang('csvexport') . '</a>'; 48909dd691aSAndreas Gohr } 49007993756SAndreas Gohr} 491