1549a0837SAndreas Gohr<?php 2549a0837SAndreas Gohr/** 3549a0837SAndreas Gohr * DokuWiki Plugin struct (Syntax Component) 4549a0837SAndreas Gohr * 5549a0837SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6549a0837SAndreas Gohr * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 7549a0837SAndreas Gohr */ 8549a0837SAndreas Gohr 9549a0837SAndreas Gohr// must be run within Dokuwiki 105511bd5bSAndreas Gohruse plugin\struct\meta\ConfigParser; 1115929be2SAndreas Gohruse plugin\struct\meta\Search; 125511bd5bSAndreas Gohruse plugin\struct\meta\SearchConfig; 1315929be2SAndreas Gohruse plugin\struct\meta\SearchException; 145511bd5bSAndreas Gohruse plugin\struct\meta\StructException; 1515929be2SAndreas Gohr 16549a0837SAndreas Gohrif (!defined('DOKU_INC')) die(); 17549a0837SAndreas Gohr 18549a0837SAndreas Gohrclass syntax_plugin_struct_table extends DokuWiki_Syntax_Plugin { 19549a0837SAndreas Gohr /** 20549a0837SAndreas Gohr * @return string Syntax mode type 21549a0837SAndreas Gohr */ 22549a0837SAndreas Gohr public function getType() { 2315929be2SAndreas Gohr return 'substition'; 24549a0837SAndreas Gohr } 25549a0837SAndreas Gohr /** 26549a0837SAndreas Gohr * @return string Paragraph type 27549a0837SAndreas Gohr */ 28549a0837SAndreas Gohr public function getPType() { 2915929be2SAndreas Gohr return 'block'; 30549a0837SAndreas Gohr } 31549a0837SAndreas Gohr /** 32549a0837SAndreas Gohr * @return int Sort order - Low numbers go before high numbers 33549a0837SAndreas Gohr */ 34549a0837SAndreas Gohr public function getSort() { 355511bd5bSAndreas Gohr return 155; 36549a0837SAndreas Gohr } 37549a0837SAndreas Gohr 38549a0837SAndreas Gohr /** 39549a0837SAndreas Gohr * Connect lookup pattern to lexer. 40549a0837SAndreas Gohr * 41549a0837SAndreas Gohr * @param string $mode Parser mode 42549a0837SAndreas Gohr */ 43549a0837SAndreas Gohr public function connectTo($mode) { 445511bd5bSAndreas Gohr $this->Lexer->addSpecialPattern('----+ *struct table *-+\n.*?\n----+', $mode, 'plugin_struct_table'); 45549a0837SAndreas Gohr } 46549a0837SAndreas Gohr 47549a0837SAndreas Gohr 48549a0837SAndreas Gohr /** 49549a0837SAndreas Gohr * Handle matches of the struct syntax 50549a0837SAndreas Gohr * 51549a0837SAndreas Gohr * @param string $match The match of the syntax 52549a0837SAndreas Gohr * @param int $state The state of the handler 53549a0837SAndreas Gohr * @param int $pos The position in the document 54549a0837SAndreas Gohr * @param Doku_Handler $handler The handler 55549a0837SAndreas Gohr * @return array Data for the renderer 56549a0837SAndreas Gohr */ 57ab466032SAndreas Gohr public function handle($match, $state, $pos, Doku_Handler $handler){ 58549a0837SAndreas Gohr 595511bd5bSAndreas Gohr $lines = explode("\n", $match); 605511bd5bSAndreas Gohr array_shift($lines); 615511bd5bSAndreas Gohr array_pop($lines); 625511bd5bSAndreas Gohr 635511bd5bSAndreas Gohr try { 645511bd5bSAndreas Gohr $parser = new ConfigParser($lines); 655511bd5bSAndreas Gohr return $parser->getConfig(); 665511bd5bSAndreas Gohr } catch (StructException $e) { 675511bd5bSAndreas Gohr msg($e->getMessage(), -1, $e->getLine(), $e->getFile()); 685511bd5bSAndreas Gohr return null; 695511bd5bSAndreas Gohr } 70549a0837SAndreas Gohr } 71549a0837SAndreas Gohr 72*29877279SMichael Große protected $sums = array(); 73*29877279SMichael Große 74*29877279SMichael Große /** @var helper_plugin_struct_aggregation $dthlp */ 75*29877279SMichael Große protected $dthlp = null; 76*29877279SMichael Große 77549a0837SAndreas Gohr /** 78549a0837SAndreas Gohr * Render xhtml output or metadata 79549a0837SAndreas Gohr * 80549a0837SAndreas Gohr * @param string $mode Renderer mode (supported modes: xhtml) 81549a0837SAndreas Gohr * @param Doku_Renderer $renderer The renderer 82549a0837SAndreas Gohr * @param array $data The data from the handler() function 83549a0837SAndreas Gohr * @return bool If rendering was successful. 84549a0837SAndreas Gohr */ 85ab466032SAndreas Gohr public function render($mode, Doku_Renderer $renderer, $data) { 86549a0837SAndreas Gohr if($mode != 'xhtml') return false; 875511bd5bSAndreas Gohr if(!$data) return false; 88*29877279SMichael Große $this->dthlp = $this->loadHelper('struct_aggregation'); 89*29877279SMichael Große 90*29877279SMichael Große $clist = $data['cols']; 91*29877279SMichael Große 92*29877279SMichael Große //reset counters 93*29877279SMichael Große $this->sums = array(); 94*29877279SMichael Große 95*29877279SMichael Große /** @var \helper_plugin_struct_config $confHlp */ 96*29877279SMichael Große $confHlp = plugin_load('helper','struct_config'); 97549a0837SAndreas Gohr 9815929be2SAndreas Gohr try { 99*29877279SMichael Große global $INPUT; 100*29877279SMichael Große 101*29877279SMichael Große $datasrt = $INPUT->str('datasrt'); 102*29877279SMichael Große if ($datasrt) { 103*29877279SMichael Große $data['sort'] = $confHlp->parseSort($datasrt); 104*29877279SMichael Große } 105*29877279SMichael Große $dataflt = $INPUT->arr('dataflt'); 106*29877279SMichael Große if ($dataflt) { 107*29877279SMichael Große foreach ($dataflt as $colcomp => $filter) { 108*29877279SMichael Große $data['filter'][] = $confHlp->parseFilterLine('AND', $colcomp . $filter); 109*29877279SMichael Große } 110*29877279SMichael Große } 1115511bd5bSAndreas Gohr $search = new SearchConfig($data); 112*29877279SMichael Große $rows = $search->execute(); 113*29877279SMichael Große $cnt = count($rows); 1145511bd5bSAndreas Gohr 115*29877279SMichael Große if ($cnt === 0) { 116*29877279SMichael Große //$this->nullList($data, $clist, $R); 117*29877279SMichael Große //return true; 118*29877279SMichael Große } 1195511bd5bSAndreas Gohr 120*29877279SMichael Große if ($data['limit'] && $cnt > $data['limit']) { 121*29877279SMichael Große $rows = array_slice($rows, 0, $data['limit']); 122*29877279SMichael Große } 12315929be2SAndreas Gohr 124*29877279SMichael Große $this->renderPreTable($mode, $renderer, $clist, $data); 125*29877279SMichael Große $this->renderRows($mode, $renderer, $data, $rows); 126*29877279SMichael Große $this->renderPostTable($mode, $renderer, $data, $cnt); 127*29877279SMichael Große 128*29877279SMichael Große $renderer->doc .= ''; 1295511bd5bSAndreas Gohr } catch (StructException $e) { 13015929be2SAndreas Gohr msg($e->getMessage(), -1, $e->getLine(), $e->getFile()); 13115929be2SAndreas Gohr } 13215929be2SAndreas Gohr 133549a0837SAndreas Gohr return true; 134549a0837SAndreas Gohr } 135*29877279SMichael Große 136*29877279SMichael Große /** 137*29877279SMichael Große * create the pretext to the actual table rows 138*29877279SMichael Große * 139*29877279SMichael Große * @param $mode 140*29877279SMichael Große * @param Doku_Renderer $renderer 141*29877279SMichael Große * @param $clist 142*29877279SMichael Große * @param $data 143*29877279SMichael Große */ 144*29877279SMichael Große protected function renderPreTable($mode, Doku_Renderer $renderer, $clist, $data) { 145*29877279SMichael Große // Save current request params to not loose them 146*29877279SMichael Große $cur_params = $this->dthlp->_get_current_param(); 147*29877279SMichael Große 148*29877279SMichael Große $this->startScope($mode, $renderer); 149*29877279SMichael Große $this->showActiveFilters($mode, $renderer, $cur_params); 150*29877279SMichael Große $this->startTable($mode, $renderer); 151*29877279SMichael Große $renderer->tablethead_open(); 152*29877279SMichael Große $this->buildColumnHeaders($mode, $renderer, $clist, $data, $cur_params); 153*29877279SMichael Große $this->addDynamicFilters($mode, $renderer, $data, $cur_params); 154*29877279SMichael Große $renderer->tablethead_close(); 155*29877279SMichael Große } 156*29877279SMichael Große 157*29877279SMichael Große /** 158*29877279SMichael Große * @param array $data 159*29877279SMichael Große * @param int $rowcnt 160*29877279SMichael Große * 161*29877279SMichael Große * @return string 162*29877279SMichael Große */ 163*29877279SMichael Große private function renderPostTable($mode, Doku_Renderer $renderer, $data, $rowcnt) { 164*29877279SMichael Große $this->summarize($mode, $renderer, $data, $this->sums); 165*29877279SMichael Große $this->addLimitControls($mode, $renderer, $data, $rowcnt); 166*29877279SMichael Große $this->finishTableAndScope($mode, $renderer); 167*29877279SMichael Große } 168*29877279SMichael Große 169*29877279SMichael Große /** 170*29877279SMichael Große * if limit was set, add control 171*29877279SMichael Große * 172*29877279SMichael Große * @param $data 173*29877279SMichael Große * @param $rowcnt 174*29877279SMichael Große * 175*29877279SMichael Große */ 176*29877279SMichael Große protected function addLimitControls($mode, Doku_Renderer $renderer, $data, $rowcnt) { 177*29877279SMichael Große global $ID; 178*29877279SMichael Große 179*29877279SMichael Große if($data['limit']) { 180*29877279SMichael Große $renderer->tablerow_open(); 181*29877279SMichael Große $renderer->tableheader_open((count($data['cols']) + ($data['rownumbers'] ? 1 : 0))); 182*29877279SMichael Große $offset = (int) $_REQUEST['dataofs']; 183*29877279SMichael Große if($offset) { 184*29877279SMichael Große $prev = $offset - $data['limit']; 185*29877279SMichael Große if($prev < 0) { 186*29877279SMichael Große $prev = 0; 187*29877279SMichael Große } 188*29877279SMichael Große 189*29877279SMichael Große // keep url params 190*29877279SMichael Große $params = $this->dthlp->_a2ua('dataflt', $_REQUEST['dataflt']); 191*29877279SMichael Große if(isset($_REQUEST['datasrt'])) { 192*29877279SMichael Große $params['datasrt'] = $_REQUEST['datasrt']; 193*29877279SMichael Große } 194*29877279SMichael Große $params['dataofs'] = $prev; 195*29877279SMichael Große 196*29877279SMichael Große if ($mode == 'xhtml') { 197*29877279SMichael Große $renderer->doc .= '<a href="' . wl($ID, $params) . 198*29877279SMichael Große '" title="' . $this->getLang('prev') . 199*29877279SMichael Große '" class="prev">' . $this->getLang('prev') . '</a> '; 200*29877279SMichael Große } else { 201*29877279SMichael Große $renderer->internallink($ID,$this->getLang('prev')); 202*29877279SMichael Große } 203*29877279SMichael Große } 204*29877279SMichael Große 205*29877279SMichael Große if($rowcnt > $data['limit']) { 206*29877279SMichael Große $next = $offset + $data['limit']; 207*29877279SMichael Große 208*29877279SMichael Große // keep url params 209*29877279SMichael Große $params = $this->dthlp->_a2ua('dataflt', $_REQUEST['dataflt']); 210*29877279SMichael Große if(isset($_REQUEST['datasrt'])) { 211*29877279SMichael Große $params['datasrt'] = $_REQUEST['datasrt']; 212*29877279SMichael Große } 213*29877279SMichael Große $params['dataofs'] = $next; 214*29877279SMichael Große 215*29877279SMichael Große if ($mode == 'xhtml') { 216*29877279SMichael Große $renderer->doc .= '<a href="' . wl($ID, $params) . 217*29877279SMichael Große '" title="' . $this->getLang('next') . 218*29877279SMichael Große '" class="next">' . $this->getLang('next') . '</a>'; 219*29877279SMichael Große } else { 220*29877279SMichael Große $renderer->internallink($ID,$this->getLang('next')); 221*29877279SMichael Große } 222*29877279SMichael Große } 223*29877279SMichael Große $renderer->tableheader_close(); 224*29877279SMichael Große $renderer->tablerow_close(); 225*29877279SMichael Große } 226*29877279SMichael Große } 227*29877279SMichael Große 228*29877279SMichael Große /** 229*29877279SMichael Große * @param $mode 230*29877279SMichael Große * @param Doku_Renderer $renderer 231*29877279SMichael Große * @param $cur_params 232*29877279SMichael Große */ 233*29877279SMichael Große protected function showActiveFilters($mode, Doku_Renderer $renderer, $cur_params) { 234*29877279SMichael Große global $ID, $INPUT; 235*29877279SMichael Große 236*29877279SMichael Große if($mode == 'xhtml' && $INPUT->has('dataflt')) { 237*29877279SMichael Große $filters = $INPUT->arr('dataflt'); 238*29877279SMichael Große $confHelper = $this->loadHelper('struct_config'); 239*29877279SMichael Große $fltrs = array(); 240*29877279SMichael Große foreach($filters as $colcomp => $filter) { 241*29877279SMichael Große $filter = $confHelper->parseFilterLine('', $colcomp.$filter); 242*29877279SMichael Große if(strpos($filter[1], '~') !== false) { 243*29877279SMichael Große if(strpos($filter[1], '!~') !== false) { 244*29877279SMichael Große $comparator_value = '!~' . str_replace('%', '*', $filter[2]); 245*29877279SMichael Große } else { 246*29877279SMichael Große $comparator_value = '~' . str_replace('%', '', $filter[2]); 247*29877279SMichael Große } 248*29877279SMichael Große $fltrs[] = $filter[0] . $comparator_value; 249*29877279SMichael Große } else { 250*29877279SMichael Große $fltrs[] = $filter[0] . $filter[1] . $filter[2]; 251*29877279SMichael Große } 252*29877279SMichael Große } 253*29877279SMichael Große 254*29877279SMichael Große $renderer->doc .= '<div class="filter">'; 255*29877279SMichael Große $renderer->doc .= '<h4>' . sprintf($this->getLang('tablefilteredby'), hsc(implode(' & ', $fltrs))) . '</h4>'; 256*29877279SMichael Große $renderer->doc .= '<div class="resetfilter">'; 257*29877279SMichael Große $renderer->internallink($ID, $this->getLang('tableresetfilter')); 258*29877279SMichael Große $renderer->doc .= '</div>'; 259*29877279SMichael Große $renderer->doc .= '</div>'; 260*29877279SMichael Große } 261*29877279SMichael Große } 262*29877279SMichael Große 263*29877279SMichael Große /** 264*29877279SMichael Große * @param $mode 265*29877279SMichael Große * @param Doku_Renderer $renderer 266*29877279SMichael Große * @param $data 267*29877279SMichael Große * @param $cur_params 268*29877279SMichael Große */ 269*29877279SMichael Große protected function addDynamicFilters($mode, Doku_Renderer $renderer, $data, $cur_params) { 270*29877279SMichael Große if ($mode != 'xhtml') return; 271*29877279SMichael Große 272*29877279SMichael Große global $conf, $ID; 273*29877279SMichael Große 274*29877279SMichael Große $html = ''; 275*29877279SMichael Große if($data['dynfilters']) { 276*29877279SMichael Große $html .= '<tr class="dataflt">'; 277*29877279SMichael Große 278*29877279SMichael Große if($data['rownumbers']) { 279*29877279SMichael Große $html .= '<th></th>'; 280*29877279SMichael Große } 281*29877279SMichael Große 282*29877279SMichael Große foreach($data['headers'] as $num => $head) { 283*29877279SMichael Große $html .= '<th>'; 284*29877279SMichael Große $form = new Doku_Form(array('method' => 'GET',)); 285*29877279SMichael Große $form->_hidden = array(); 286*29877279SMichael Große if(!$conf['userewrite']) { 287*29877279SMichael Große $form->addHidden('id', $ID); 288*29877279SMichael Große } 289*29877279SMichael Große 290*29877279SMichael Große $key = 'dataflt[' . $data['cols'][$num] . '~' . ']'; 291*29877279SMichael Große $val = isset($cur_params[$key]) ? $cur_params[$key] : ''; 292*29877279SMichael Große 293*29877279SMichael Große // Add current request params 294*29877279SMichael Große foreach($cur_params as $c_key => $c_val) { 295*29877279SMichael Große if($c_val !== '' && $c_key !== $key) { 296*29877279SMichael Große $form->addHidden($c_key, $c_val); 297*29877279SMichael Große } 298*29877279SMichael Große } 299*29877279SMichael Große 300*29877279SMichael Große $form->addElement(form_makeField('text', $key, $val, '')); 301*29877279SMichael Große $html .= $form->getForm(); 302*29877279SMichael Große $html .= '</th>'; 303*29877279SMichael Große } 304*29877279SMichael Große $html .= '</tr>'; 305*29877279SMichael Große $renderer->doc .= $html; 306*29877279SMichael Große } 307*29877279SMichael Große } 308*29877279SMichael Große 309*29877279SMichael Große /** 310*29877279SMichael Große * @param $mode 311*29877279SMichael Große * @param Doku_Renderer $renderer 312*29877279SMichael Große */ 313*29877279SMichael Große private function startTable($mode, Doku_Renderer $renderer) { 314*29877279SMichael Große $renderer->table_open(); 315*29877279SMichael Große } 316*29877279SMichael Große 317*29877279SMichael Große /** 318*29877279SMichael Große * @param $mode 319*29877279SMichael Große * @param Doku_Renderer $renderer 320*29877279SMichael Große * @param $clist 321*29877279SMichael Große * @param $data 322*29877279SMichael Große * @param $cur_params 323*29877279SMichael Große * 324*29877279SMichael Große */ 325*29877279SMichael Große protected function buildColumnHeaders($mode, Doku_Renderer $renderer, $clist, $data, $cur_params) { 326*29877279SMichael Große global $ID; 327*29877279SMichael Große 328*29877279SMichael Große $renderer->tablerow_open(); 329*29877279SMichael Große 330*29877279SMichael Große if($data['rownumbers']) { 331*29877279SMichael Große $renderer->tableheader_open(); 332*29877279SMichael Große $renderer->cdata('#'); 333*29877279SMichael Große $renderer->tableheader_close(); 334*29877279SMichael Große } 335*29877279SMichael Große 336*29877279SMichael Große foreach($data['headers'] as $num => $head) { 337*29877279SMichael Große $ckey = $clist[$num]; 338*29877279SMichael Große 339*29877279SMichael Große $width = ''; 340*29877279SMichael Große if(isset($data['widths'][$num]) AND $data['widths'][$num] != '-') { 341*29877279SMichael Große $width = ' style="width: ' . $data['widths'][$num] . ';"'; 342*29877279SMichael Große } 343*29877279SMichael Große if ($mode == 'xhmtl') { 344*29877279SMichael Große $renderer->doc .= '<th' . $width . '>'; 345*29877279SMichael Große } else { 346*29877279SMichael Große $renderer->tableheader_open(); 347*29877279SMichael Große } 348*29877279SMichael Große 349*29877279SMichael Große // add sort arrow 350*29877279SMichael Große if ($mode == 'xhtml') { 351*29877279SMichael Große if(isset($data['sort']) && $ckey == $data['sort'][0]) { 352*29877279SMichael Große if($data['sort'][1] == 'ASC') { 353*29877279SMichael Große $renderer->doc .= '<span>↓</span> '; 354*29877279SMichael Große $ckey = '^' . $ckey; 355*29877279SMichael Große } else { 356*29877279SMichael Große $renderer->doc .= '<span>↑</span> '; 357*29877279SMichael Große } 358*29877279SMichael Große } 359*29877279SMichael Große } 360*29877279SMichael Große 361*29877279SMichael Große // Clickable header for dynamic sorting 362*29877279SMichael Große if ($mode == 'xhtml') { 363*29877279SMichael Große $renderer->doc .= '<a href="' . wl($ID, array('datasrt' => $ckey,) + $cur_params) . 364*29877279SMichael Große '" title="' . $this->getLang('sort') . '">' . hsc($head) . '</a>'; 365*29877279SMichael Große } else { 366*29877279SMichael Große $renderer->internallink($ID . "?datasrt=$ckey", hsc($head)); 367*29877279SMichael Große } 368*29877279SMichael Große $renderer->tableheader_close(); 369*29877279SMichael Große } 370*29877279SMichael Große $renderer->tablerow_close(); 371*29877279SMichael Große } 372*29877279SMichael Große 373*29877279SMichael Große 374*29877279SMichael Große protected function startScope($mode, \Doku_Renderer $renderer) { 375*29877279SMichael Große if ($mode == 'xhtml') { 376*29877279SMichael Große $renderer->doc .= '<div class="table structaggegation">'; 377*29877279SMichael Große } 378*29877279SMichael Große } 379*29877279SMichael Große 380*29877279SMichael Große /** 381*29877279SMichael Große * if summarize was set, add sums 382*29877279SMichael Große * 383*29877279SMichael Große * @param $mode 384*29877279SMichael Große * @param Doku_Renderer $renderer 385*29877279SMichael Große * @param $data 386*29877279SMichael Große * @param $sums 387*29877279SMichael Große */ 388*29877279SMichael Große private function summarize($mode, \Doku_Renderer $renderer, $data, $sums) { 389*29877279SMichael Große if($data['summarize']) { 390*29877279SMichael Große $renderer->tablerow_open(); 391*29877279SMichael Große $len = count($data['cols']); 392*29877279SMichael Große 393*29877279SMichael Große if($data['rownumbers']) { 394*29877279SMichael Große $renderer->tablecell_open(); 395*29877279SMichael Große $renderer->tablecell_close(); 396*29877279SMichael Große } 397*29877279SMichael Große 398*29877279SMichael Große for($i = 0; $i < $len; $i++) { 399*29877279SMichael Große $renderer->tablecell_open(1, $data['align'][$i]); 400*29877279SMichael Große if(!empty($sums[$i])) { 401*29877279SMichael Große $renderer->cdata('∑ ' . $sums[$i]); 402*29877279SMichael Große } else { 403*29877279SMichael Große if ($mode == 'xhtml') { 404*29877279SMichael Große $renderer->doc .= ' '; 405*29877279SMichael Große } 406*29877279SMichael Große } 407*29877279SMichael Große $renderer->tablecell_close(); 408*29877279SMichael Große } 409*29877279SMichael Große $renderer->tablerow_close(); 410*29877279SMichael Große } 411*29877279SMichael Große } 412*29877279SMichael Große 413*29877279SMichael Große /** 414*29877279SMichael Große * @param $mode 415*29877279SMichael Große * @param Doku_Renderer $renderer 416*29877279SMichael Große * 417*29877279SMichael Große */ 418*29877279SMichael Große private function finishTableAndScope($mode, Doku_Renderer $renderer) { 419*29877279SMichael Große $renderer->table_close(); 420*29877279SMichael Große if ($mode == 'xhmtl') { 421*29877279SMichael Große $renderer->doc .= '</div>'; 422*29877279SMichael Große } 423*29877279SMichael Große } 424*29877279SMichael Große 425*29877279SMichael Große /** 426*29877279SMichael Große * @param $mode 427*29877279SMichael Große * @param Doku_Renderer $renderer 428*29877279SMichael Große * @param $data 429*29877279SMichael Große * @param $rows 430*29877279SMichael Große * 431*29877279SMichael Große */ 432*29877279SMichael Große private function renderRows($mode, Doku_Renderer $renderer, $data, $rows) { 433*29877279SMichael Große $renderer->tabletbody_open(); 434*29877279SMichael Große foreach($rows as $rownum => $row) { 435*29877279SMichael Große $renderer->tablerow_open(); 436*29877279SMichael Große 437*29877279SMichael Große if($data['rownumbers']) { 438*29877279SMichael Große $renderer->tablecell_open(); 439*29877279SMichael Große $renderer->doc .= $rownum + 1; 440*29877279SMichael Große $renderer->tablecell_close(); 441*29877279SMichael Große } 442*29877279SMichael Große 443*29877279SMichael Große /** @var plugin\struct\meta\Value $value */ 444*29877279SMichael Große foreach($row as $colnum => $value) { 445*29877279SMichael Große $renderer->tablecell_open(); 446*29877279SMichael Große $value->render($renderer, $mode); 447*29877279SMichael Große $renderer->tablecell_close(); 448*29877279SMichael Große 449*29877279SMichael Große // summarize 450*29877279SMichael Große if($data['summarize'] && is_numeric($value->getValue())) { 451*29877279SMichael Große if(!isset($this->sums[$colnum])) { 452*29877279SMichael Große $this->sums[$colnum] = 0; 453*29877279SMichael Große } 454*29877279SMichael Große $this->sums[$colnum] += $value->getValue(); 455*29877279SMichael Große } 456*29877279SMichael Große } 457*29877279SMichael Große $renderer->tablerow_close(); 458*29877279SMichael Große } 459*29877279SMichael Große $renderer->tabletbody_close(); 460*29877279SMichael Große } 461549a0837SAndreas Gohr} 462549a0837SAndreas Gohr 463549a0837SAndreas Gohr// vim:ts=4:sw=4:et: 464