コード例 #1
0
 /**
  * Real raster that prints graphs and data
  *
  */
 function print_dashboard()
 {
     global $CFG, $EXTRADBCONNECT, $COURSE, $DB, $OUTPUT;
     /*
     $text = '<link type="text/css" rel="stylesheet" href="'.$CFG->wwwroot.'/blocks/dashboard/js/dhtmlxCalendar/codebase/dhtmlxcalendar.css" />';
     $text .= '<link type="text/css" rel="stylesheet" href="'.$CFG->wwwroot.'/blocks/dashboard/js/dhtmlxCalendar/codebase/skins/dhtmlxcalendar_dhx_web.css" />';
     */
     $text = '';
     if (!isset($this->config)) {
         $this->config = new StdClass();
     }
     $this->config->limit = 20;
     $coursepage = '';
     if ($COURSE->format == 'page') {
         include_once $CFG->dirroot . '/course/format/page/lib.php';
         $pageid = optional_param('page', 0, PARAM_INT);
         // flexipage page number
         if (!$pageid) {
             $flexpage = course_page::get_current_page($COURSE->id);
         } else {
             $flexpage = new StdClass();
             $flexpage->id = $pageid;
         }
         $coursepage = "&page=" . $flexpage->id;
     }
     $rpage = optional_param('rpage' . $this->instance->id, 0, PARAM_INT);
     // result page
     if ($rpage < 0) {
         $rpage = 0;
     }
     // unlogged people cannot see their status
     if ((!isloggedin() || isguestuser()) && @$this->config->guestsallowed) {
         $text = get_string('guestsnotallowed', 'block_dashboard');
         $loginstr = get_string('login');
         $text .= "<a href=\"{$wwwroot}/login/index.php\">{$loginstr}</a>";
         return $text;
     }
     if (!isset($this->config) || empty($this->config->query)) {
         $noquerystr = get_string('noquerystored', 'block_dashboard');
         $text = $noquerystr;
         return $text;
     }
     if (!isset($CFG->block_dashboard_big_result_threshold)) {
         $CFG->block_dashboard_big_result_threshold = 500;
     }
     // connecting
     if ($this->config->target == 'moodle') {
         // already connected
     } else {
         $error = '';
         if (!isset($EXTRADBCONNECT)) {
             $EXTRADBCONNECT = extra_db_connect(true, $error);
         }
         if ($error) {
             $text = $error;
             return $text;
         }
     }
     // prepare all params from config
     $this->prepare_config();
     $graphdata = array();
     $ticks = array();
     $filterquerystring = '';
     if (!empty($this->config->filters)) {
         try {
             $filterquerystring = $this->prepare_filters();
         } catch (Exception $e) {
             if (debugging()) {
                 echo $e->error;
             }
             return get_string('invalidorobsoletefilterquery', 'block_dashboard');
         }
     } else {
         $this->filteredsql = str_replace('<%%FILTERS%%>', '', $this->sql);
     }
     $this->sql = str_replace('<%%FILTERS%%>', '', $this->sql);
     // needed to prepare for filter range prefetch
     if (!empty($this->params)) {
         $filterquerystring = $filterquerystring ? $filterquerystring . '&' . $this->prepare_params() : $this->prepare_params();
     } else {
         $this->sql = str_replace('<%%PARAMS%%>', '', $this->sql);
         // needed to prepare for filter range prefetch
         $this->filteredsql = str_replace('<%%PARAMS%%>', '', $this->filteredsql);
         // needed to prepare for filter range prefetch
     }
     $sort = optional_param('tsort' . $this->instance->id, @$this->config->defaultsort, PARAM_TEXT);
     if (!empty($sort)) {
         // do not sort if already sorted in explained query
         if (!preg_match('/ORDER\\s+BY/si', $this->sql)) {
             $this->filteredsql .= " ORDER BY {$sort}";
         }
     }
     $this->filteredsql = $this->protect($this->filteredsql);
     // ######### GETTING RESULTS
     $countres = $this->count_records($error);
     // if too many results, we force paging mode
     if (empty($this->config->pagesize) && $countres > $CFG->block_dashboard_big_result_threshold && !empty($this->config->bigresult)) {
         $text .= '<span class="error">' . get_string('toomanyrecordsusepaging', 'block_dashboard') . '</span><br/>';
         $this->config->pagesize = $CFG->block_dashboard_big_result_threshold;
         $rpage = 0;
     }
     // getting real results including page and offset
     if (!empty($this->config->pagesize)) {
         $offset = $rpage * $this->config->pagesize;
     } else {
         $offset = '';
     }
     try {
         $results = $this->fetch_dashboard_data($this->filteredsql, @$this->config->pagesize, $offset);
     } catch (Exception $e) {
         return get_string('invalidorobsoletequery', 'block_dashboard', $this->config->query);
     }
     if ($results) {
         $table = new flexible_table('mod-dashboard' . $this->instance->id);
         $instancecontrolvars = array(TABLE_VAR_PAGE => 'rpage' . $this->instance->id, TABLE_VAR_SORT => 'tsort' . $this->instance->id, TABLE_VAR_HIDE => 'thide' . $this->instance->id, TABLE_VAR_SHOW => 'tshow' . $this->instance->id);
         $table->set_control_variables($instancecontrolvars);
         // use full not to collide with flexipage paging
         $tablecolumns = array();
         $tableheaders = array();
         foreach ($this->output as $field => $label) {
             $tablecolumns[] = $field;
             $tableheaders[] = $label;
         }
         $table->define_columns($tablecolumns);
         $table->define_headers($tableheaders);
         $filterquerystringadd = isset($filterquerystring) ? "&amp;{$filterquerystring}" : '';
         if (@$this->config->inblocklayout) {
             $table->define_baseurl($CFG->wwwroot . '/course/view.php?id=' . $COURSE->id . $coursepage . $filterquerystringadd);
         } else {
             $table->define_baseurl($CFG->wwwroot . '/blocks/dashboard/view.php?id=' . $COURSE->id . '&amp;blockid=' . $this->instance->id . $coursepage . $filterquerystringadd);
         }
         if (!empty($this->config->sortable)) {
             $table->sortable(true, $this->config->xaxisfield, SORT_DESC);
         }
         //sorted by xaxisfield by default
         $table->collapsible(true);
         $table->initialbars(true);
         $table->set_attribute('cellspacing', '0');
         $table->set_attribute('id', 'dashboard' . $this->instance->id);
         $table->set_attribute('class', 'dashboard');
         $table->set_attribute('width', '100%');
         foreach ($this->output as $field => $label) {
             $table->column_class($field, $field);
         }
         $table->setup();
         /*			
         $where = $table->get_sql_where();
         $sortsql = $table->get_sql_sort();
         */
         if (!empty($this->config->pagesize)) {
             $table->pagesize($this->config->pagesize, $countres);
             // no paginating at start
         }
         $graphseries = array();
         $treedata = array();
         $treekeys = array();
         $lastvalue = array();
         $hcols = array();
         $splitnumsonsort = @$this->config->splitsumsonsort;
         foreach ($results as $result) {
             // prepare for subsums
             if (!empty($splitnumsonsort)) {
                 $orderkeyed = strtoupper($result->{$splitnumsonsort});
                 if (!isset($oldorderkeyed)) {
                     $oldorderkeyed = $orderkeyed;
                 }
                 // first time
             }
             // pre-aggregates sums
             if (!empty($this->config->shownumsums)) {
                 foreach (array_keys($this->numsumsf) as $numsum) {
                     if (empty($numsum)) {
                         continue;
                     }
                     if (!isset($result->{$numsum})) {
                         continue;
                     }
                     // make subaggregates (only for linear tables and when sorting criteria is the split column)
                     // post aggregate after table output
                     if (!isset($aggr)) {
                         $aggr = new StdClass();
                     }
                     $aggr->{$numsum} = 0 + (double) @$aggr->{$numsum} + (double) $result->{$numsum};
                     if (!empty($splitnumsonsort) && @$this->config->tabletype == 'linear' && preg_match("/\\b{$splitnumsonsort}\\b/", $sort)) {
                         $this->subaggr[$orderkeyed]->{$numsum} = 0 + (double) @$this->subaggr[$orderkeyed]->{$numsum} + (double) $result->{$numsum};
                     }
                 }
             }
             if (!empty($splitnumsonsort) && @$this->config->tabletype == 'linear' && preg_match("/\\b{$splitnumsonsort}\\b/", $sort)) {
                 if ($orderkeyed != $oldorderkeyed) {
                     // when range changes
                     $k = 0;
                     $tabledata = null;
                     foreach (array_keys($this->output) as $field) {
                         if (in_array($field, array_keys($this->numsumsf))) {
                             if (is_null($tabledata)) {
                                 $tabledata = array();
                                 for ($j = 0; $j < $k; $j++) {
                                     $tabledata[$j] = '';
                                 }
                             }
                             $tabledata[$k] = '<b>Tot: ' . @$this->subaggr[$oldorderkeyed]->{$field} . '</b>';
                         }
                         $k++;
                     }
                     if (!is_null($tabledata)) {
                         $table->add_data($tabledata);
                     }
                     $oldorderkeyed = $orderkeyed;
                 }
             }
             // Print data in results
             if (!empty($this->config->showdata)) {
                 if (empty($this->config->tabletype) || $this->config->tabletype == 'linear') {
                     $tabledata = array();
                     foreach (array_keys($this->output) as $field) {
                         if (empty($field)) {
                             continue;
                         }
                         // did we ask for cumulative results ?
                         $cumulativeix = null;
                         if (preg_match('/S\\((.+?)\\)/', $field, $matches)) {
                             $field = $matches[1];
                             $cumulativeix = $this->instance->id . '_' . $field;
                         }
                         if (!empty($this->outputf[$field])) {
                             $datum = dashboard_format_data($this->outputf[$field], $result->{$field}, $cumulativeix);
                         } else {
                             $datum = dashboard_format_data(null, @$result->{$field}, $cumulativeix);
                         }
                         // process coloring if required
                         if (!empty($this->config->colorfield) && $this->config->colorfield == $field) {
                             $datum = dashboard_colour_code($this, $datum, $this->colourcoding);
                         }
                         if (!empty($this->config->cleandisplay)) {
                             if (!array_key_exists($field, $lastvalue) || $lastvalue[$field] != $datum) {
                                 $lastvalue[$field] = $datum;
                                 $tabledata[] = $datum;
                             } else {
                                 $tabledata[] = '';
                                 // if same as above, add blanck
                             }
                         } else {
                             $tabledata[] = $datum;
                         }
                     }
                     $table->add_data($tabledata);
                 } else {
                     if ($this->config->tabletype == 'tabular') {
                         // this is a tabular table
                         /* in a tabular table, data can be placed :
                          * - in first columns in order of vertical keys
                          * the results are grabbed sequentially and spread into the matrix 
                          */
                         $keystack = array();
                         $matrix = array();
                         foreach (array_keys($this->vertkeys->formats) as $vkey) {
                             if (empty($vkey)) {
                                 continue;
                             }
                             $vkeyvalue = $result->{$vkey};
                             $matrix[] = "['" . addslashes($vkeyvalue) . "']";
                         }
                         $hkey = $this->config->horizkey;
                         $hkeyvalue = !empty($hkey) ? $result->{$hkey} : '';
                         $matrix[] = "['" . addslashes($hkeyvalue) . "']";
                         $matrixst = "\$m" . implode($matrix);
                         if (!in_array($hkeyvalue, $hcols)) {
                             $hcols[] = $hkeyvalue;
                         }
                         // now put the cell value in it
                         $outvalues = array();
                         foreach (array_keys($this->output) as $field) {
                             // did we ask for cumulative results ?
                             $cumulativeix = null;
                             if (preg_match('/S\\((.+?)\\)/', $field, $matches)) {
                                 $field = $matches[1];
                                 $cumulativeix = $this->instance->id . '_' . $field;
                             }
                             if (!empty($this->outputf[$field])) {
                                 $datum = dashboard_format_data($this->outputf[$field], $result->{$field}, $cumulativeix);
                             } else {
                                 $datum = dashboard_format_data(null, @$result->{$field}, $cumulativeix);
                             }
                             if (!empty($this->config->colorfield) && $this->config->colorfield == $field) {
                                 $datum = dashboard_colour_code($this, $datum, $this->colourcoding);
                             }
                             $outvalues[] = str_replace("\"", "\\\"", $datum);
                         }
                         $matrixst .= ' = "' . implode(' ', $outvalues) . '"';
                         // make the matrix in memory
                         eval($matrixst . ";");
                     } else {
                         $debug = optional_param('debug', false, PARAM_BOOL);
                         // treeview
                         $resultarr = array_values((array) $result);
                         $resultid = $resultarr[0];
                         if (!empty($parentserie)) {
                             if (!empty($result->{$parentserie})) {
                                 // non root node, attache to his parent if we found it
                                 if (array_key_exists($result->{$parentserie}, $treekeys)) {
                                     if (!empty($debug)) {
                                         echo 'binding to ' . $result->{$parentserie} . '. ';
                                     }
                                     $treekeys[$result->{$parentserie}]->childs[$resultid] = $result;
                                     if (!array_key_exists($resultid, $treekeys)) {
                                         $treekeys[$resultid] = $result;
                                     }
                                 } else {
                                     // in case nodes do not come in correct order, do not connect but register only
                                     if (!empty($debug)) {
                                         echo 'waiting for ' . $result->{$parentserie} . '. ';
                                     }
                                     $waitingnodes[$resultid] = $result;
                                     if (!array_key_exists($resultid, $treekeys)) {
                                         $treekeys[$resultid] = $result;
                                     }
                                 }
                             } else {
                                 // root node
                                 if (!empty($debug)) {
                                     echo 'root as ' . $resultid . '. ';
                                 }
                                 if (!array_key_exists($resultid, $treekeys)) {
                                     $treekeys[$resultid] = $result;
                                 }
                                 $treedata[$resultid] =& $treekeys[$resultid];
                             }
                         } else {
                             if (!array_key_exists($resultid, $treekeys)) {
                                 $treekeys[$resultid] = $result;
                             }
                         }
                     }
                 }
             }
             // Prepare data for graphs
             if (!empty($this->config->showgraph)) {
                 if (!empty($this->config->xaxisfield) && $this->config->graphtype != 'googlemap' && $this->config->graphtype != 'timeline') {
                     $xaxisfield = $this->config->xaxisfield;
                     if ($this->config->graphtype != 'pie') {
                         // TODO : check if $this->config->xaxisfield exists really (misconfiguration)
                         $ticks[] = addslashes($result->{$xaxisfield});
                         $ys = 0;
                         foreach (array_keys($this->yseriesf) as $yserie) {
                             if (!isset($result->{$yserie})) {
                                 continue;
                             }
                             // did we ask for cumulative results ?
                             $cumulativeix = null;
                             if (preg_match('/S\\((.+?)\\)/', $yserie, $matches)) {
                                 $yserie = $matches[1];
                                 $cumulativeix = $this->instance->id . '_' . $yserie;
                             }
                             if ($this->config->graphtype != 'timegraph') {
                                 if (!empty($this->yseriesf[$yserie])) {
                                     $graphseries[$yserie][] = dashboard_format_data($this->yseriesf[$yserie], $result->{$yserie}, $cumulativeix);
                                 } else {
                                     $graphseries[$yserie][] = dashboard_format_data(null, $result->{$yserie}, $cumulativeix);
                                 }
                             } else {
                                 if (!empty($this->yseriesf[$yserie])) {
                                     $timeelm = array($result->{$xaxisfield}, dashboard_format_data($this->yseriesf[$yserie], $result->{$yserie}, $cumulativeix));
                                     $graphseries[$ys][] = $timeelm;
                                 } else {
                                     $timeelm = array($result->{$xaxisfield}, dashboard_format_data(null, $result->{$yserie}, $cumulativeix));
                                     $graphseries[$ys][] = $timeelm;
                                 }
                             }
                             $ys++;
                         }
                     } elseif ($this->config->graphtype == 'pie') {
                         foreach ($yseries as $yserie) {
                             if (empty($result->{$xaxisfield})) {
                                 $result->{$xaxisfield} = 'N.C.';
                             }
                             if (!empty($this->yseriesf[$field])) {
                                 $graphseries[$yserie][] = array($result->{$xaxisfield}, dashboard_format_data($this->yseriesf[$field], $result->{$yserie}, false));
                             } else {
                                 $graphseries[$yserie][] = array($result->{$xaxisfield}, $result->{$yserie});
                             }
                         }
                     }
                 } else {
                     $data[] = $result;
                 }
             }
             $graphdata = array_values($graphseries);
         }
         //************ post aggregating last subtotal *************//
         if (!empty($this->config->shownumsums) && $results) {
             if (!empty($splitnumsonsort) && @$this->config->tabletype == 'linear' && preg_match("/\\b{$splitnumsonsort}\\b/", $sort)) {
                 $k = 0;
                 $tabledata = null;
                 foreach (array_keys($this->output) as $field) {
                     if (in_array($field, array_keys($this->numsumsf))) {
                         if (is_null($tabledata)) {
                             $tabledata = array();
                             for ($j = 0; $j < $k; $j++) {
                                 $tabledata[$j] = '';
                             }
                         }
                         $tabledata[$k] = '<b>Tot: ' . @$this->subaggr[$orderkeyed]->{$field} . '</b>';
                     }
                     $k++;
                 }
                 $oldorderkeyed = $orderkeyed;
                 if (!is_null($tabledata)) {
                     $table->add_data($tabledata);
                 }
             }
         }
         //************ Starting outputing data ************************//
         // if treeview, need to post process waiting nodes
         if (@$this->config->tabletype == 'treeview') {
             if (!empty($waitingnodes)) {
                 foreach ($waitingnodes as $wnid => $wn) {
                     if (array_key_exists($wn->{$parentserie}, $treekeys)) {
                         if (!empty($debug)) {
                             echo ' postbinding to ' . $wn->{$parentserie} . '. ';
                         }
                         $treekeys[$wn->{$parentserie}]->childs[$wnid] = $wn;
                         unset($waitingnodes[$wnid]);
                         // free some stuff
                     }
                 }
             }
         }
         if (@$this->config->inblocklayout) {
             $url = $CFG->wwwroot . '/course/view.php?id=' . $COURSE->id . $coursepage . '&tsort' . $this->instance->id . '=' . $sort;
         } else {
             $url = $CFG->wwwroot . '/blocks/dashboard/view.php?id=' . $COURSE->id . '&blocksid=' . $this->instance->id . $coursepage . '&tsort' . $this->instance->id . '=' . $sort;
         }
         $text .= dashboard_render_filters_and_params_form($this, $sort);
         if ($this->config->showdata) {
             $allexportstr = get_string('exportall', 'block_dashboard');
             $tableexportstr = get_string('exportdataastable', 'block_dashboard');
             $filteredexportstr = get_string('exportfiltered', 'block_dashboard');
             $filterquerystring = !empty($filterquerystring) ? '&' . $filterquerystring : '';
             if (empty($this->config->tabletype) || @$this->config->tabletype == 'linear') {
                 ob_start();
                 $table->print_html();
                 $text .= ob_get_clean();
                 $text .= "<div style=\"text-align:right\">";
                 $text .= "<a href=\"{$CFG->wwwroot}/blocks/dashboard/export/export_csv.php?id={$COURSE->id}&amp;instance={$this->instance->id}&amp;tsort{$this->instance->id}={$sort}&amp;alldata=1\">{$allexportstr}</a>";
                 if ($filterquerystring) {
                     $text .= " - <a href=\"{$CFG->wwwroot}/blocks/dashboard/export/export_csv.php?id={$COURSE->id}&instance={$this->instance->id}&tsort{$this->instance->id}={$sort}{$filterquerystring}\">{$filteredexportstr}</a>";
                 }
                 $text .= "</div>";
             } elseif (@$this->config->tabletype == 'tabular') {
                 // forget table and use $m matrix for making display
                 $text .= print_cross_table($this, $m, $hcols, $this->config->horizkey, $this->vertkeys, $this->config->horizlabel, true);
                 $text .= "<div style=\"text-align:right\"><a href=\"{$CFG->wwwroot}/blocks/dashboard/export/export_csv.php?id={$COURSE->id}&amp;instance={$this->instance->id}&amp;tsort{$this->instance->id}={$sort}&amp;alldata=1\">{$allexportstr}</a></div>";
                 $text .= "<div style=\"text-align:right\"><a href=\"{$CFG->wwwroot}/blocks/dashboard/export/export_csv_tabular.php?id={$COURSE->id}&instance={$this->instance->id}&tsort{$this->instance->id}={$sort}{$filterquerystring}\">{$tableexportstr}</a></div>";
             } else {
                 $text .= dashboard_print_tree_view($this, $treedata, $this->treeoutput, $this->output, $this->outputf, $this->colourcoding, true);
                 $text .= "<div style=\"text-align:right\"><a href=\"{$CFG->wwwroot}/blocks/dashboard/export/export_csv.php?id={$COURSE->id}&amp;instance={$this->instance->id}&amp;tsort{$this->instance->id}={$sort}&amp;alldata=1\">{$allexportstr}</a></div>";
             }
         } else {
             $text .= '';
         }
     } else {
         // no data, but render filters anyway
         $text .= dashboard_render_filters_and_params_form($this, $sort);
     }
     // showing graph
     if ($this->config->showgraph && !empty($this->config->graphtype)) {
         $text .= $OUTPUT->box_start('dashboard-graph-box');
         $graphdesc = $this->dashboard_graph_properties();
         if ($this->config->graphtype != 'googlemap' && $this->config->graphtype != 'timeline') {
             $data = $graphdata;
             $text .= jqplot_print_graph('dashboard' . $this->instance->id, $graphdesc, $data, $this->config->graphwidth, $this->config->graphheight, '', true, $ticks);
         } elseif ($this->config->graphtype == 'googlemap') {
             $text .= dashboard_render_googlemaps_data($this, $data, $graphdesc);
         } else {
             // timeline graph
             if (empty($this->config->timelineeventstart) || empty($this->config->timelineeventend)) {
                 $text .= $OUTPUT->notification("Missing mappings (start or titles)", 'notifyproblem');
             } else {
                 $text .= timeline_print_graph($this, 'dashboard' . $this->instance->id, $this->config->graphwidth, $this->config->graphheight, $data, true);
             }
         }
         $text .= $OUTPUT->box_end();
     }
     // showing bottom summators
     if ($this->config->numsums) {
         $text .= dashboard_render_numsums($this, $aggr);
     }
     // showing query
     if (@$this->config->showquery) {
         $text .= '<div class="dashboard-query-box" style="padding:1px;border:1px solid #808080;margin:2px;font-size:0.75em;font-family:monospace">';
         $text .= '<pre>' . $this->filteredsql . '</pre>';
         $text .= '</div>';
     }
     // showing SQL benches
     if (@$this->config->showbenches) {
         $text .= '<div class="dashboard-benches-box" style="padding:1px;border:1px solid #808080;margin:2px;font-size:0.75em;font-family:monospace">';
         $text .= '<table width="100%">';
         foreach ($this->benches as $bench) {
             $value = $bench->end - $bench->start;
             $text .= "<tr><td>{$bench->name}</td><td>{$value} sec.</td></tr>";
         }
         $text .= '</table>';
         $text .= '</div>';
     }
     return $text;
 }
コード例 #2
0
        $sumupdateerrors += $b->updateerrors;
        if ($b->timerun > OVERTIME_THRESHOLD) {
            $overtime++;
        } else {
            $iwo++;
            $sumdurationwovertimes += $b->timerun;
        }
        $timegrid[0][] = array(date('d-M-Y', $b->timestart), $b->timerun);
        $i++;
    }
    $meantime = $sumduration / $i;
    $normalmeantime = $sumdurationwovertimes / $iwo;
}
echo $OUTPUT->box_start('ent-installer-curve');
$jqplot = array('title' => array('text' => get_string('syncbench', 'local_ent_installer'), 'fontSize' => '1.3em', 'color' => '#000080'), 'legend' => array('show' => true, 'location' => 'e', 'placement' => 'outsideGrid', 'marginLeft' => '10px', 'border' => '1px solid #808080', 'labels' => array(get_string('synctime', 'local_ent_installer'))), 'axesDefaults' => array('labelRenderer' => '$.jqplot.CanvasAxisLabelRenderer'), 'axes' => array('xaxis' => array('label' => get_string('day'), 'renderer' => '$.jqplot.DateAxisRenderer', 'tickOptions' => array('formatString' => '%b&nbsp;%#d')), 'yaxis' => array('autoscale' => true, 'tickOptions' => array('formatString' => '%.2f'), 'label' => get_string('seconds'), 'labelRenderer' => '$.jqplot.CanvasAxisLabelRenderer', 'labelOptions' => array('angle' => 90))), 'series' => array(array('color' => '#C00000')));
jqplot_print_graph('plot1', $jqplot, $timegrid, 750, 250, 'margin:20px;');
echo $OUTPUT->box_end();
echo $OUTPUT->box_start('ent-installer-report-globals');
$table = new html_table();
$table->head = array('', '');
$table->align = array('right', 'left');
$table->size = array('60%', '40%');
$table->colstyles = array('head', 'value');
$table->data[] = array(get_string('inserts', 'local_ent_installer'), $suminserts);
$table->data[] = array(get_string('updates', 'local_ent_installer'), $sumupdates);
$table->data[] = array(get_string('inserterrors', 'local_ent_installer'), $suminserterrors);
$table->data[] = array(get_string('updateerrors', 'local_ent_installer'), $sumupdateerrors);
$table->data[] = array(get_string('overtimes', 'local_ent_installer', OVERTIME_THRESHOLD), $overtime);
$table->data[] = array(get_string('minduration', 'local_ent_installer'), sprintf('%0.2f', $minduration));
$table->data[] = array(get_string('maxduration', 'local_ent_installer'), sprintf('%0.2f', $maxduration));
$table->data[] = array(get_string('meantime', 'local_ent_installer'), sprintf('%0.2f', $meantime));