Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/tablelib.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00026 defined('MOODLE_INTERNAL') || die();
00027 
00031 define('TABLE_VAR_SORT',   1);
00032 define('TABLE_VAR_HIDE',   2);
00033 define('TABLE_VAR_SHOW',   3);
00034 define('TABLE_VAR_IFIRST', 4);
00035 define('TABLE_VAR_ILAST',  5);
00036 define('TABLE_VAR_PAGE',   6);
00043 define('TABLE_P_TOP',    1);
00044 define('TABLE_P_BOTTOM', 2);
00053 class flexible_table {
00054 
00055     var $uniqueid        = NULL;
00056     var $attributes      = array();
00057     var $headers         = array();
00058     var $columns         = array();
00059     var $column_style    = array();
00060     var $column_class    = array();
00061     var $column_suppress = array();
00062     var $column_nosort   = array('userpic');
00063     var $setup           = false;
00064     var $sess            = NULL;
00065     var $baseurl         = NULL;
00066     var $request         = array();
00067 
00068     var $is_collapsible = false;
00069     var $is_sortable    = false;
00070     var $use_pages      = false;
00071     var $use_initials   = false;
00072 
00073     var $maxsortkeys = 2;
00074     var $pagesize    = 30;
00075     var $currpage    = 0;
00076     var $totalrows   = 0;
00077     var $sort_default_column = NULL;
00078     var $sort_default_order  = SORT_ASC;
00079 
00083     var $showdownloadbuttonsat= array(TABLE_P_TOP);
00084 
00089     public $useridfield = 'id';
00090 
00096     var $download  = '';
00097 
00102     var $downloadable = false;
00103 
00108     var $defaultdownloadformat  = 'csv';
00109 
00113     var $started_output = false;
00114 
00115     var $exportclass = null;
00116 
00122     function __construct($uniqueid) {
00123         $this->uniqueid = $uniqueid;
00124         $this->request  = array(
00125             TABLE_VAR_SORT   => 'tsort',
00126             TABLE_VAR_HIDE   => 'thide',
00127             TABLE_VAR_SHOW   => 'tshow',
00128             TABLE_VAR_IFIRST => 'tifirst',
00129             TABLE_VAR_ILAST  => 'tilast',
00130             TABLE_VAR_PAGE   => 'page',
00131         );
00132     }
00133 
00139     function flexible_table($uniqueid) {
00140         debugging('Please update your code to user PHP5-style parent::__construct(...), ' .
00141                 'not parent::flexible_table(...).');
00142         $this->__construct($uniqueid);
00143     }
00144 
00158     function is_downloading($download = null, $filename='', $sheettitle='') {
00159         if ($download!==null) {
00160             $this->sheettitle = $sheettitle;
00161             $this->is_downloadable(true);
00162             $this->download = $download;
00163             $this->filename = clean_filename($filename);
00164             $this->export_class_instance();
00165         }
00166         return $this->download;
00167     }
00168 
00174     function export_class_instance($exportclass = null) {
00175         if (!is_null($exportclass)) {
00176             $this->started_output = true;
00177             $this->exportclass = $exportclass;
00178             $this->exportclass->table = $this;
00179         } else if (is_null($this->exportclass) && !empty($this->download)) {
00180             $classname = 'table_'.$this->download.'_export_format';
00181             $this->exportclass = new $classname($this);
00182             if (!$this->exportclass->document_started()) {
00183                 $this->exportclass->start_document($this->filename);
00184             }
00185         }
00186         return $this->exportclass;
00187     }
00188 
00198     function is_downloadable($downloadable = null) {
00199         if ($downloadable !== null) {
00200             $this->downloadable = $downloadable;
00201         }
00202         return $this->downloadable;
00203     }
00204 
00210     function show_download_buttons_at($showat) {
00211         $this->showdownloadbuttonsat = $showat;
00212     }
00213 
00222     function sortable($bool, $defaultcolumn = NULL, $defaultorder = SORT_ASC) {
00223         $this->is_sortable = $bool;
00224         $this->sort_default_column = $defaultcolumn;
00225         $this->sort_default_order  = $defaultorder;
00226     }
00227 
00232     function no_sorting($column) {
00233         $this->column_nosort[] = $column;
00234     }
00235 
00241     function is_sortable($column = null) {
00242         if (empty($column)) {
00243             return $this->is_sortable;
00244         }
00245         if (!$this->is_sortable) {
00246             return false;
00247         }
00248         return !in_array($column, $this->column_nosort);
00249     }
00250 
00256     function collapsible($bool) {
00257         $this->is_collapsible = $bool;
00258     }
00259 
00265     function pageable($bool) {
00266         $this->use_pages = $bool;
00267     }
00268 
00274     function initialbars($bool) {
00275         $this->use_initials = $bool;
00276     }
00277 
00285     function pagesize($perpage, $total) {
00286         $this->pagesize  = $perpage;
00287         $this->totalrows = $total;
00288         $this->use_pages = true;
00289     }
00290 
00297     function set_control_variables($variables) {
00298         foreach ($variables as $what => $variable) {
00299             if (isset($this->request[$what])) {
00300                 $this->request[$what] = $variable;
00301             }
00302         }
00303     }
00304 
00311     function set_attribute($attribute, $value) {
00312         $this->attributes[$attribute] = $value;
00313     }
00314 
00324     function column_suppress($column) {
00325         if (isset($this->column_suppress[$column])) {
00326             $this->column_suppress[$column] = true;
00327         }
00328     }
00329 
00336     function column_class($column, $classname) {
00337         if (isset($this->column_class[$column])) {
00338             $this->column_class[$column] = ' '.$classname; // This space needed so that classnames don't run together in the HTML
00339         }
00340     }
00341 
00349     function column_style($column, $property, $value) {
00350         if (isset($this->column_style[$column])) {
00351             $this->column_style[$column][$property] = $value;
00352         }
00353     }
00354 
00361     function column_style_all($property, $value) {
00362         foreach (array_keys($this->columns) as $column) {
00363             $this->column_style[$column][$property] = $value;
00364         }
00365     }
00366 
00371     function define_baseurl($url) {
00372         $this->baseurl = new moodle_url($url);
00373     }
00374 
00379     function define_columns($columns) {
00380         $this->columns = array();
00381         $this->column_style = array();
00382         $this->column_class = array();
00383         $colnum = 0;
00384 
00385         foreach ($columns as $column) {
00386             $this->columns[$column]         = $colnum++;
00387             $this->column_style[$column]    = array();
00388             $this->column_class[$column]    = '';
00389             $this->column_suppress[$column] = false;
00390         }
00391     }
00392 
00397     function define_headers($headers) {
00398         $this->headers = $headers;
00399     }
00400 
00406     function setup() {
00407         global $SESSION, $CFG;
00408 
00409         if (empty($this->columns) || empty($this->uniqueid)) {
00410             return false;
00411         }
00412 
00413         if (!isset($SESSION->flextable)) {
00414             $SESSION->flextable = array();
00415         }
00416 
00417         if (!isset($SESSION->flextable[$this->uniqueid])) {
00418             $SESSION->flextable[$this->uniqueid] = new stdClass;
00419             $SESSION->flextable[$this->uniqueid]->uniqueid = $this->uniqueid;
00420             $SESSION->flextable[$this->uniqueid]->collapse = array();
00421             $SESSION->flextable[$this->uniqueid]->sortby   = array();
00422             $SESSION->flextable[$this->uniqueid]->i_first  = '';
00423             $SESSION->flextable[$this->uniqueid]->i_last   = '';
00424         }
00425 
00426         $this->sess = &$SESSION->flextable[$this->uniqueid];
00427 
00428         if (($showcol = optional_param($this->request[TABLE_VAR_SHOW], '', PARAM_ALPHANUMEXT)) &&
00429                 isset($this->columns[$showcol])) {
00430             $this->sess->collapse[$showcol] = false;
00431 
00432         } else if (($hidecol = optional_param($this->request[TABLE_VAR_HIDE], '', PARAM_ALPHANUMEXT)) &&
00433                 isset($this->columns[$hidecol])) {
00434             $this->sess->collapse[$hidecol] = true;
00435             if (array_key_exists($hidecol, $this->sess->sortby)) {
00436                 unset($this->sess->sortby[$hidecol]);
00437             }
00438         }
00439 
00440         // Now, update the column attributes for collapsed columns
00441         foreach (array_keys($this->columns) as $column) {
00442             if (!empty($this->sess->collapse[$column])) {
00443                 $this->column_style[$column]['width'] = '10px';
00444             }
00445         }
00446 
00447         if (($sortcol = optional_param($this->request[TABLE_VAR_SORT], '', PARAM_ALPHANUMEXT)) &&
00448                 $this->is_sortable($sortcol) && empty($this->sess->collapse[$sortcol]) &&
00449                 (isset($this->columns[$sortcol]) || in_array($sortcol, array('firstname', 'lastname')) && isset($this->columns['fullname']))) {
00450 
00451             if (array_key_exists($sortcol, $this->sess->sortby)) {
00452                 // This key already exists somewhere. Change its sortorder and bring it to the top.
00453                 $sortorder = $this->sess->sortby[$sortcol] == SORT_ASC ? SORT_DESC : SORT_ASC;
00454                 unset($this->sess->sortby[$sortcol]);
00455                 $this->sess->sortby = array_merge(array($sortcol => $sortorder), $this->sess->sortby);
00456             } else {
00457                 // Key doesn't exist, so just add it to the beginning of the array, ascending order
00458                 $this->sess->sortby = array_merge(array($sortcol => SORT_ASC), $this->sess->sortby);
00459             }
00460 
00461             // Finally, make sure that no more than $this->maxsortkeys are present into the array
00462             $this->sess->sortby = array_slice($this->sess->sortby, 0, $this->maxsortkeys);
00463         }
00464 
00465         // If we didn't sort just now, then use the default sort order if one is defined and the column exists
00466         if (empty($this->sess->sortby) && !empty($this->sort_default_column))  {
00467             $this->sess->sortby = array ($this->sort_default_column => ($this->sort_default_order == SORT_DESC ? SORT_DESC : SORT_ASC));
00468         }
00469 
00470         $ilast = optional_param($this->request[TABLE_VAR_ILAST], null, PARAM_RAW);
00471         if (!is_null($ilast) && ($ilast ==='' || strpos(get_string('alphabet', 'langconfig'), $ilast) !== false)) {
00472             $this->sess->i_last = $ilast;
00473         }
00474 
00475         $ifirst = optional_param($this->request[TABLE_VAR_IFIRST], null, PARAM_RAW);
00476         if (!is_null($ifirst) && ($ifirst === '' || strpos(get_string('alphabet', 'langconfig'), $ifirst) !== false)) {
00477             $this->sess->i_first = $ifirst;
00478         }
00479 
00480         if (empty($this->baseurl)) {
00481             debugging('You should set baseurl when using flexible_table.');
00482             global $PAGE;
00483             $this->baseurl = $PAGE->url;
00484         }
00485 
00486         $this->currpage = optional_param($this->request[TABLE_VAR_PAGE], 0, PARAM_INT);
00487         $this->setup = true;
00488 
00489         // Always introduce the "flexible" class for the table if not specified
00490         if (empty($this->attributes)) {
00491             $this->attributes['class'] = 'flexible';
00492         } else if (!isset($this->attributes['class'])) {
00493             $this->attributes['class'] = 'flexible';
00494         } else if (!in_array('flexible', explode(' ', $this->attributes['class']))) {
00495             $this->attributes['class'] = trim('flexible ' . $this->attributes['class']);
00496         }
00497     }
00498 
00504     public static function get_sort_for_table($uniqueid) {
00505         global $SESSION;
00506         if (empty($SESSION->flextable[$uniqueid])) {
00507            return '';
00508         }
00509 
00510         $sess = &$SESSION->flextable[$uniqueid];
00511         if (empty($sess->sortby)) {
00512             return '';
00513         }
00514 
00515         return self::construct_order_by($sess->sortby);
00516     }
00517 
00523     public static function construct_order_by($cols) {
00524         $bits = array();
00525 
00526         foreach ($cols as $column => $order) {
00527             if ($order == SORT_ASC) {
00528                 $bits[] = $column . ' ASC';
00529             } else {
00530                 $bits[] = $column . ' DESC';
00531             }
00532         }
00533 
00534         return implode(', ', $bits);
00535     }
00536 
00540     public function get_sql_sort() {
00541         return self::construct_order_by($this->get_sort_columns());
00542     }
00543 
00548     public function get_sort_columns() {
00549         if (!$this->setup) {
00550             throw new coding_exception('Cannot call get_sort_columns until you have called setup.');
00551         }
00552 
00553         if (empty($this->sess->sortby)) {
00554             return array();
00555         }
00556 
00557         foreach ($this->sess->sortby as $column => $notused) {
00558             if (isset($this->columns[$column])) {
00559                 continue; // This column is OK.
00560             }
00561             if (in_array($column, array('firstname', 'lastname')) &&
00562                     isset($this->columns['fullname'])) {
00563                 continue; // This column is OK.
00564             }
00565             // This column is not OK.
00566             unset($this->sess->sortby[$column]);
00567         }
00568 
00569         return $this->sess->sortby;
00570     }
00571 
00575     function get_page_start() {
00576         if (!$this->use_pages) {
00577             return '';
00578         }
00579         return $this->currpage * $this->pagesize;
00580     }
00581 
00585     function get_page_size() {
00586         if (!$this->use_pages) {
00587             return '';
00588         }
00589         return $this->pagesize;
00590     }
00591 
00595     function get_sql_where() {
00596         global $DB;
00597 
00598         $conditions = array();
00599         $params = array();
00600 
00601         if (isset($this->columns['fullname'])) {
00602             static $i = 0;
00603             $i++;
00604 
00605             if (!empty($this->sess->i_first)) {
00606                 $conditions[] = $DB->sql_like('firstname', ':ifirstc'.$i, false, false);
00607                 $params['ifirstc'.$i] = $this->sess->i_first.'%';
00608             }
00609             if (!empty($this->sess->i_last)) {
00610                 $conditions[] = $DB->sql_like('lastname', ':ilastc'.$i, false, false);
00611                 $params['ilastc'.$i] = $this->sess->i_last.'%';
00612             }
00613         }
00614 
00615         return array(implode(" AND ", $conditions), $params);
00616     }
00617 
00628     function add_data_keyed($rowwithkeys, $classname = '') {
00629         $this->add_data($this->get_row_from_keyed($rowwithkeys), $classname);
00630     }
00631 
00635     function add_separator() {
00636         if (!$this->setup) {
00637             return false;
00638         }
00639         $this->add_data(NULL);
00640     }
00641 
00653     function add_data($row, $classname = '') {
00654         if (!$this->setup) {
00655             return false;
00656         }
00657         if (!$this->started_output) {
00658             $this->start_output();
00659         }
00660         if ($this->exportclass!==null) {
00661             if ($row === null) {
00662                 $this->exportclass->add_seperator();
00663             } else {
00664                 $this->exportclass->add_data($row);
00665             }
00666         } else {
00667             $this->print_row($row, $classname);
00668         }
00669         return true;
00670     }
00671 
00677     function finish_output($closeexportclassdoc = true) {
00678         if ($this->exportclass!==null) {
00679             $this->exportclass->finish_table();
00680             if ($closeexportclassdoc) {
00681                 $this->exportclass->finish_document();
00682             }
00683         } else {
00684             $this->finish_html();
00685         }
00686     }
00687 
00693     function wrap_html_start() {
00694     }
00695 
00701     function wrap_html_finish() {
00702     }
00703 
00709     function format_row($row) {
00710         $formattedrow = array();
00711         foreach (array_keys($this->columns) as $column) {
00712             $colmethodname = 'col_'.$column;
00713             if (method_exists($this, $colmethodname)) {
00714                 $formattedcolumn = $this->$colmethodname($row);
00715             } else {
00716                 $formattedcolumn = $this->other_cols($column, $row);
00717                 if ($formattedcolumn===NULL) {
00718                     $formattedcolumn = $row->$column;
00719                 }
00720             }
00721             $formattedrow[$column] = $formattedcolumn;
00722         }
00723         return $formattedrow;
00724     }
00725 
00734     function col_fullname($row) {
00735         global $COURSE, $CFG;
00736 
00737         if (!$this->download) {
00738             $profileurl = new moodle_url('/user/profile.php', array('id' => $row->{$this->useridfield}));
00739             if ($COURSE->id != SITEID) {
00740                 $profileurl->param('course', $COURSE->id);
00741             }
00742             return html_writer::link($profileurl, fullname($row));
00743 
00744         } else {
00745             return fullname($row);
00746         }
00747     }
00748 
00753     function other_cols($column, $row) {
00754         return NULL;
00755     }
00756 
00764     function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL) {
00765         if (!$this->is_downloading()) {
00766             if (is_null($options)) {
00767                 $options = new stdClass;
00768             }
00769             //some sensible defaults
00770             if (!isset($options->para)) {
00771                 $options->para = false;
00772             }
00773             if (!isset($options->newlines)) {
00774                 $options->newlines = false;
00775             }
00776             if (!isset($options->smiley)) {
00777                 $options->smiley = false;
00778             }
00779             if (!isset($options->filter)) {
00780                 $options->filter = false;
00781             }
00782             return format_text($text, $format, $options);
00783         } else {
00784             $eci =& $this->export_class_instance();
00785             return $eci->format_text($text, $format, $options, $courseid);
00786         }
00787     }
00792     function print_html() {
00793         if (!$this->setup) {
00794             return false;
00795         }
00796         $this->finish_html();
00797     }
00798 
00803     function get_initial_first() {
00804         if (!$this->use_initials) {
00805             return NULL;
00806         }
00807 
00808         return $this->sess->i_first;
00809     }
00810 
00815     function get_initial_last() {
00816         if (!$this->use_initials) {
00817             return NULL;
00818         }
00819 
00820         return $this->sess->i_last;
00821     }
00822 
00831     protected function print_one_initials_bar($alpha, $current, $class, $title, $urlvar) {
00832         echo html_writer::start_tag('div', array('class' => 'initialbar ' . $class)) .
00833                 $title . ' : ';
00834         if ($current) {
00835             echo html_writer::link($this->baseurl->out(false, array($urlvar => '')), get_string('all'));
00836         } else {
00837             echo html_writer::tag('strong', get_string('all'));
00838         }
00839 
00840         foreach ($alpha as $letter) {
00841             if ($letter === $current) {
00842                 echo html_writer::tag('strong', $letter);
00843             } else {
00844                 echo html_writer::link($this->baseurl->out(false, array($urlvar => $letter)), $letter);
00845             }
00846         }
00847 
00848         echo html_writer::end_tag('div');
00849     }
00850 
00854     function print_initials_bar() {
00855         if ((!empty($this->sess->i_last) || !empty($this->sess->i_first) ||$this->use_initials)
00856                     && isset($this->columns['fullname'])) {
00857 
00858             $alpha  = explode(',', get_string('alphabet', 'langconfig'));
00859 
00860             // Bar of first initials
00861             if (!empty($this->sess->i_first)) {
00862                 $ifirst = $this->sess->i_first;
00863             } else {
00864                 $ifirst = '';
00865             }
00866             $this->print_one_initials_bar($alpha, $ifirst, 'firstinitial',
00867                     get_string('firstname'), $this->request[TABLE_VAR_IFIRST]);
00868 
00869             // Bar of last initials
00870             if (!empty($this->sess->i_last)) {
00871                 $ilast = $this->sess->i_last;
00872             } else {
00873                 $ilast = '';
00874             }
00875             $this->print_one_initials_bar($alpha, $ilast, 'lastinitial',
00876                     get_string('lastname'), $this->request[TABLE_VAR_ILAST]);
00877         }
00878     }
00879 
00883     function print_nothing_to_display() {
00884         global $OUTPUT;
00885         $this->print_initials_bar();
00886 
00887         echo $OUTPUT->heading(get_string('nothingtodisplay'));
00888     }
00889 
00893     function get_row_from_keyed($rowwithkeys) {
00894         if (is_object($rowwithkeys)) {
00895             $rowwithkeys = (array)$rowwithkeys;
00896         }
00897         $row = array();
00898         foreach (array_keys($this->columns) as $column) {
00899             if (isset($rowwithkeys[$column])) {
00900                 $row [] = $rowwithkeys[$column];
00901             } else {
00902                 $row[] ='';
00903             }
00904         }
00905         return $row;
00906     }
00910     function get_download_menu() {
00911         $allclasses= get_declared_classes();
00912         $exportclasses = array();
00913         foreach ($allclasses as $class) {
00914             $matches = array();
00915             if (preg_match('/^table\_([a-z]+)\_export\_format$/', $class, $matches)) {
00916                 $type = $matches[1];
00917                 $exportclasses[$type]= get_string("download$type", 'table');
00918             }
00919         }
00920         return $exportclasses;
00921     }
00922 
00926     function download_buttons() {
00927         if ($this->is_downloadable() && !$this->is_downloading()) {
00928             $downloadoptions = $this->get_download_menu();
00929             $html = '<form action="'. $this->baseurl .'" method="post">';
00930             $html .= '<div class="mdl-align">';
00931             $html .= '<input type="submit" value="'.get_string('downloadas', 'table').'"/>';
00932             $html .= html_writer::select($downloadoptions, 'download', $this->defaultdownloadformat, false);
00933             $html .= '</div></form>';
00934 
00935             return $html;
00936         } else {
00937             return '';
00938         }
00939     }
00946     function start_output() {
00947         $this->started_output = true;
00948         if ($this->exportclass!==null) {
00949             $this->exportclass->start_table($this->sheettitle);
00950             $this->exportclass->output_headers($this->headers);
00951         } else {
00952             $this->start_html();
00953             $this->print_headers();
00954         }
00955     }
00956 
00960     function print_row($row, $classname = '') {
00961         static $suppress_lastrow = NULL;
00962         static $oddeven = 1;
00963         $rowclasses = array('r' . $oddeven);
00964         $oddeven = $oddeven ? 0 : 1;
00965 
00966         if ($classname) {
00967             $rowclasses[] = $classname;
00968         }
00969 
00970         echo html_writer::start_tag('tr', array('class' => implode(' ', $rowclasses)));
00971 
00972         // If we have a separator, print it
00973         if ($row === NULL) {
00974             $colcount = count($this->columns);
00975             echo html_writer::tag('td', html_writer::tag('div', '',
00976                     array('class' => 'tabledivider')), array('colspan' => $colcount));
00977 
00978         } else {
00979             $colbyindex = array_flip($this->columns);
00980             foreach ($row as $index => $data) {
00981                 $column = $colbyindex[$index];
00982 
00983                 if (empty($this->sess->collapse[$column])) {
00984                     if ($this->column_suppress[$column] && $suppress_lastrow !== NULL && $suppress_lastrow[$index] === $data) {
00985                         $content = '&nbsp;';
00986                     } else {
00987                         $content = $data;
00988                     }
00989                 } else {
00990                     $content = '&nbsp;';
00991                 }
00992 
00993                 echo html_writer::tag('td', $content, array(
00994                         'class' => 'cell c' . $index . $this->column_class[$column],
00995                         'style' => $this->make_styles_string($this->column_style[$column])));
00996             }
00997         }
00998 
00999         echo html_writer::end_tag('tr');
01000 
01001         $suppress_enabled = array_sum($this->column_suppress);
01002         if ($suppress_enabled) {
01003             $suppress_lastrow = $row;
01004         }
01005     }
01006 
01010     function finish_html() {
01011         global $OUTPUT;
01012         if (!$this->started_output) {
01013             //no data has been added to the table.
01014             $this->print_nothing_to_display();
01015 
01016         } else {
01017             echo html_writer::end_tag('table');
01018             echo html_writer::end_tag('div');
01019             $this->wrap_html_finish();
01020 
01021             // Paging bar
01022             if(in_array(TABLE_P_BOTTOM, $this->showdownloadbuttonsat)) {
01023                 echo $this->download_buttons();
01024             }
01025 
01026             if($this->use_pages) {
01027                 $pagingbar = new paging_bar($this->totalrows, $this->currpage, $this->pagesize, $this->baseurl);
01028                 $pagingbar->pagevar = $this->request[TABLE_VAR_PAGE];
01029                 echo $OUTPUT->render($pagingbar);
01030             }
01031         }
01032     }
01033 
01041     protected function show_hide_link($column, $index) {
01042         global $OUTPUT;
01043         // Some headers contain <br /> tags, do not include in title, hence the
01044         // strip tags.
01045 
01046         if (!empty($this->sess->collapse[$column])) {
01047             return html_writer::link($this->baseurl->out(false, array($this->request[TABLE_VAR_SHOW] => $column)),
01048                     html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('t/switch_plus'), 'alt' => get_string('show'))),
01049                     array('title' => get_string('show') . ' ' . strip_tags($this->headers[$index])));
01050 
01051         } else if ($this->headers[$index] !== NULL) {
01052             return html_writer::link($this->baseurl->out(false, array($this->request[TABLE_VAR_HIDE] => $column)),
01053                     html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('t/switch_minus'), 'alt' => get_string('hide'))),
01054                     array('title' => get_string('hide') . ' ' . strip_tags($this->headers[$index])));
01055         }
01056     }
01057 
01061     function print_headers() {
01062         global $CFG, $OUTPUT;
01063 
01064         echo html_writer::start_tag('tr');
01065         foreach ($this->columns as $column => $index) {
01066 
01067             $icon_hide = '';
01068             if ($this->is_collapsible) {
01069                 $icon_hide = $this->show_hide_link($column, $index);
01070             }
01071 
01072             $primary_sort_column = '';
01073             $primary_sort_order  = '';
01074             if (reset($this->sess->sortby)) {
01075                 $primary_sort_column = key($this->sess->sortby);
01076                 $primary_sort_order  = current($this->sess->sortby);
01077             }
01078 
01079             switch ($column) {
01080 
01081                 case 'fullname':
01082                 if ($this->is_sortable($column)) {
01083                     $firstnamesortlink = $this->sort_link(get_string('firstname'),
01084                             'firstname', $primary_sort_column === 'firstname', $primary_sort_order);
01085 
01086                     $lastnamesortlink = $this->sort_link(get_string('lastname'),
01087                             'lastname', $primary_sort_column === 'lastname', $primary_sort_order);
01088 
01089                     $override = new stdClass();
01090                     $override->firstname = 'firstname';
01091                     $override->lastname = 'lastname';
01092                     $fullnamelanguage = get_string('fullnamedisplay', '', $override);
01093 
01094                     if (($CFG->fullnamedisplay == 'firstname lastname') or
01095                         ($CFG->fullnamedisplay == 'firstname') or
01096                         ($CFG->fullnamedisplay == 'language' and $fullnamelanguage == 'firstname lastname' )) {
01097                         $this->headers[$index] = $firstnamesortlink . ' / ' . $lastnamesortlink;
01098                     } else {
01099                         $this->headers[$index] = $lastnamesortlink . ' / ' . $firstnamesortlink;
01100                     }
01101                 }
01102                 break;
01103 
01104                 case 'userpic':
01105                     // do nothing, do not display sortable links
01106                 break;
01107 
01108                 default:
01109                 if ($this->is_sortable($column)) {
01110                     $this->headers[$index] = $this->sort_link($this->headers[$index],
01111                             $column, $primary_sort_column == $column, $primary_sort_order);
01112                 }
01113             }
01114 
01115             $attributes = array(
01116                 'class' => 'header c' . $index . $this->column_class[$column],
01117                 'scope' => 'col',
01118             );
01119             if ($this->headers[$index] === NULL) {
01120                 $content = '&nbsp;';
01121             } else if (!empty($this->sess->collapse[$column])) {
01122                 $content = $icon_hide;
01123             } else {
01124                 if (is_array($this->column_style[$column])) {
01125                     $attributes['style'] = $this->make_styles_string($this->column_style[$column]);
01126                 }
01127                 $content = $this->headers[$index] . html_writer::tag('div',
01128                         $icon_hide, array('class' => 'commands'));
01129             }
01130             echo html_writer::tag('th', $content, $attributes);
01131         }
01132 
01133         echo html_writer::end_tag('tr');
01134     }
01135 
01142     protected function sort_icon($isprimary, $order) {
01143         global $OUTPUT;
01144 
01145         if (!$isprimary) {
01146             return '';
01147         }
01148 
01149         if ($order == SORT_ASC) {
01150             return html_writer::empty_tag('img',
01151                     array('src' => $OUTPUT->pix_url('t/down'), 'alt' => get_string('asc')));
01152         } else {
01153             return html_writer::empty_tag('img',
01154                     array('src' => $OUTPUT->pix_url('t/up'), 'alt' => get_string('desc')));
01155         }
01156     }
01157 
01165     protected function sort_order_name($isprimary, $order) {
01166         if ($isprimary && $order != SORT_ASC) {
01167             return get_string('desc');
01168         } else {
01169             return get_string('asc');
01170         }
01171     }
01172 
01181     protected function sort_link($text, $column, $isprimary, $order) {
01182         return html_writer::link($this->baseurl->out(false,
01183                 array($this->request[TABLE_VAR_SORT] => $column)),
01184                 $text . get_accesshide(get_string('sortby') . ' ' .
01185                 $text . ' ' . $this->sort_order_name($isprimary, $order))) . ' ' .
01186                 $this->sort_icon($isprimary, $order);
01187     }
01188 
01192     function start_html() {
01193         global $OUTPUT;
01194         // Do we need to print initial bars?
01195         $this->print_initials_bar();
01196 
01197         // Paging bar
01198         if ($this->use_pages) {
01199             $pagingbar = new paging_bar($this->totalrows, $this->currpage, $this->pagesize, $this->baseurl);
01200             $pagingbar->pagevar = $this->request[TABLE_VAR_PAGE];
01201             echo $OUTPUT->render($pagingbar);
01202         }
01203 
01204         if (in_array(TABLE_P_TOP, $this->showdownloadbuttonsat)) {
01205             echo $this->download_buttons();
01206         }
01207 
01208         $this->wrap_html_start();
01209         // Start of main data table
01210 
01211         echo html_writer::start_tag('div', array('class' => 'no-overflow'));
01212         echo html_writer::start_tag('table', $this->attributes);
01213 
01214     }
01215 
01221     function make_styles_string($styles) {
01222         if (empty($styles)) {
01223             return null;
01224         }
01225 
01226         $string = '';
01227         foreach($styles as $property => $value) {
01228             $string .= $property . ':' . $value . ';';
01229         }
01230         return $string;
01231     }
01232 }
01233 
01234 
01240 class table_sql extends flexible_table {
01241 
01242     public $countsql = NULL;
01243     public $countparams = NULL;
01247     public $sql = NULL;
01251     public $rawdata = NULL;
01252 
01256     public $is_sortable    = true;
01260     public $is_collapsible = true;
01261 
01266     function __construct($uniqueid) {
01267         parent::__construct($uniqueid);
01268         // some sensible defaults
01269         $this->set_attribute('cellspacing', '0');
01270         $this->set_attribute('class', 'generaltable generalbox');
01271     }
01272 
01278     function table_sql($uniqueid) {
01279         debugging('Please update your code to user PHP5-style parent::__construct(...), ' .
01280                 'not parent::table_sql(...).');
01281         $this->__construct($uniqueid);
01282     }
01283 
01290     function build_table() {
01291         if ($this->rawdata) {
01292             foreach ($this->rawdata as $row) {
01293                 $formattedrow = $this->format_row($row);
01294                 $this->add_data_keyed($formattedrow,
01295                         $this->get_row_class($row));
01296             }
01297         }
01298     }
01299 
01305     function get_row_class($row) {
01306         return '';
01307     }
01308 
01318     function set_count_sql($sql, array $params = NULL) {
01319         $this->countsql = $sql;
01320         $this->countparams = $params;
01321     }
01322 
01329     function set_sql($fields, $from, $where, array $params = NULL) {
01330         $this->sql = new stdClass();
01331         $this->sql->fields = $fields;
01332         $this->sql->from = $from;
01333         $this->sql->where = $where;
01334         $this->sql->params = $params;
01335     }
01336 
01344     function query_db($pagesize, $useinitialsbar=true) {
01345         global $DB;
01346         if (!$this->is_downloading()) {
01347             if ($this->countsql === NULL) {
01348                 $this->countsql = 'SELECT COUNT(1) FROM '.$this->sql->from.' WHERE '.$this->sql->where;
01349                 $this->countparams = $this->sql->params;
01350             }
01351             $grandtotal = $DB->count_records_sql($this->countsql, $this->countparams);
01352             if ($useinitialsbar && !$this->is_downloading()) {
01353                 $this->initialbars($grandtotal > $pagesize);
01354             }
01355 
01356             list($wsql, $wparams) = $this->get_sql_where();
01357             if ($wsql) {
01358                 $this->countsql .= ' AND '.$wsql;
01359                 $this->countparams = array_merge($this->countparams, $wparams);
01360 
01361                 $this->sql->where .= ' AND '.$wsql;
01362                 $this->sql->params = array_merge($this->sql->params, $wparams);
01363 
01364                 $total  = $DB->count_records_sql($this->countsql, $this->countparams);
01365             } else {
01366                 $total = $grandtotal;
01367             }
01368 
01369             $this->pagesize($pagesize, $total);
01370         }
01371 
01372         // Fetch the attempts
01373         $sort = $this->get_sql_sort();
01374         if ($sort) {
01375             $sort = "ORDER BY $sort";
01376         }
01377         $sql = "SELECT
01378                 {$this->sql->fields}
01379                 FROM {$this->sql->from}
01380                 WHERE {$this->sql->where}
01381                 {$sort}";
01382 
01383         if (!$this->is_downloading()) {
01384             $this->rawdata = $DB->get_records_sql($sql, $this->sql->params, $this->get_page_start(), $this->get_page_size());
01385         } else {
01386             $this->rawdata = $DB->get_records_sql($sql, $this->sql->params);
01387         }
01388     }
01389 
01394     function out($pagesize, $useinitialsbar, $downloadhelpbutton='') {
01395         global $DB;
01396         if (!$this->columns) {
01397             $onerow = $DB->get_record_sql("SELECT {$this->sql->fields} FROM {$this->sql->from} WHERE {$this->sql->where}", $this->sql->params);
01398             //if columns is not set then define columns as the keys of the rows returned
01399             //from the db.
01400             $this->define_columns(array_keys((array)$onerow));
01401             $this->define_headers(array_keys((array)$onerow));
01402         }
01403         $this->setup();
01404         $this->query_db($pagesize, $useinitialsbar);
01405         $this->build_table();
01406         $this->finish_output();
01407     }
01408 }
01409 
01410 
01416 class table_default_export_format_parent {
01421     var $table;
01422 
01427     var $documentstarted = false;
01428     function table_default_export_format_parent(&$table) {
01429         $this->table =& $table;
01430     }
01431 
01432     function set_table(&$table) {
01433         $this->table =& $table;
01434     }
01435 
01436     function add_data($row) {
01437         return false;
01438     }
01439 
01440     function add_seperator() {
01441         return false;
01442     }
01443 
01444     function document_started() {
01445         return $this->documentstarted;
01446     }
01452     function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL) {
01453         //use some whitespace to indicate where there was some line spacing.
01454         $text = str_replace(array('</p>', "\n", "\r"), '   ', $text);
01455         return strip_tags($text);
01456     }
01457 }
01458 
01459 
01465 class table_spreadsheet_export_format_parent extends table_default_export_format_parent {
01466     var $rownum;
01467     var $workbook;
01468     var $worksheet;
01472     var $formatnormal;
01476     var $formatheaders;
01477 
01481     var $fileextension;
01482 
01486     function define_workbook() {
01487     }
01488 
01489     function start_document($filename) {
01490         $filename = $filename.'.'.$this->fileextension;
01491         $this->define_workbook();
01492         // format types
01493         $this->formatnormal =& $this->workbook->add_format();
01494         $this->formatnormal->set_bold(0);
01495         $this->formatheaders =& $this->workbook->add_format();
01496         $this->formatheaders->set_bold(1);
01497         $this->formatheaders->set_align('center');
01498         // Sending HTTP headers
01499         $this->workbook->send($filename);
01500         $this->documentstarted = true;
01501     }
01502 
01503     function start_table($sheettitle) {
01504         $this->worksheet =& $this->workbook->add_worksheet($sheettitle);
01505         $this->rownum=0;
01506     }
01507 
01508     function output_headers($headers) {
01509         $colnum = 0;
01510         foreach ($headers as $item) {
01511             $this->worksheet->write($this->rownum,$colnum,$item,$this->formatheaders);
01512             $colnum++;
01513         }
01514         $this->rownum++;
01515     }
01516 
01517     function add_data($row) {
01518         $colnum = 0;
01519         foreach ($row as $item) {
01520             $this->worksheet->write($this->rownum,$colnum,$item,$this->formatnormal);
01521             $colnum++;
01522         }
01523         $this->rownum++;
01524         return true;
01525     }
01526 
01527     function add_seperator() {
01528         $this->rownum++;
01529         return true;
01530     }
01531 
01532     function finish_table() {
01533     }
01534 
01535     function finish_document() {
01536         $this->workbook->close();
01537         exit;
01538     }
01539 }
01540 
01541 
01547 class table_excel_export_format extends table_spreadsheet_export_format_parent {
01548     var $fileextension = 'xls';
01549 
01550     function define_workbook() {
01551         global $CFG;
01552         require_once("$CFG->libdir/excellib.class.php");
01553         // Creating a workbook
01554         $this->workbook = new MoodleExcelWorkbook("-");
01555     }
01556 
01557 }
01558 
01559 
01565 class table_ods_export_format extends table_spreadsheet_export_format_parent {
01566     var $fileextension = 'ods';
01567     function define_workbook() {
01568         global $CFG;
01569         require_once("$CFG->libdir/odslib.class.php");
01570         // Creating a workbook
01571         $this->workbook = new MoodleODSWorkbook("-");
01572     }
01573 }
01574 
01575 
01581 class table_text_export_format_parent extends table_default_export_format_parent {
01582     protected $seperator = "\t";
01583     protected $mimetype = 'text/tab-separated-values';
01584     protected $ext = '.txt';
01585 
01586     public function start_document($filename) {
01587         $this->filename = $filename . $this->ext;
01588         header('Content-Type: ' . $this->mimetype . '; charset=UTF-8');
01589         header('Content-Disposition: attachment; filename="' . $this->filename . '"');
01590         header('Expires: 0');
01591         header('Cache-Control: must-revalidate,post-check=0,pre-check=0');
01592         header('Pragma: public');
01593         $this->documentstarted = true;
01594     }
01595 
01596     public function start_table($sheettitle) {
01597         //nothing to do here
01598     }
01599 
01600     public function output_headers($headers) {
01601         echo $this->format_row($headers);
01602     }
01603 
01604     public function add_data($row) {
01605         echo $this->format_row($row);
01606         return true;
01607     }
01608 
01609     public function finish_table() {
01610         echo "\n\n";
01611     }
01612 
01613     public function finish_document() {
01614         exit;
01615     }
01616 
01621     protected function format_row($data) {
01622         $escapeddata = array();
01623         foreach ($data as $value) {
01624             $escapeddata[] = '"' . str_replace('"', '""', $value) . '"';
01625         }
01626         return implode($this->seperator, $escapeddata) . "\n";
01627     }
01628 }
01629 
01630 
01636 class table_tsv_export_format extends table_text_export_format_parent {
01637     protected $seperator = "\t";
01638     protected $mimetype = 'text/tab-separated-values';
01639     protected $ext = '.txt';
01640 }
01641 
01642 
01648 class table_csv_export_format extends table_text_export_format_parent {
01649     protected $seperator = ",";
01650     protected $mimetype = 'text/csv';
01651     protected $ext = '.csv';
01652 }
01653 
01654 
01660 class table_xhtml_export_format extends table_default_export_format_parent {
01661     function start_document($filename) {
01662         header("Content-Type: application/download\n");
01663         header("Content-Disposition: attachment; filename=\"$filename.html\"");
01664         header("Expires: 0");
01665         header("Cache-Control: must-revalidate,post-check=0,pre-check=0");
01666         header("Pragma: public");
01667         //html headers
01668         echo <<<EOF
01669 <?xml version="1.0" encoding="UTF-8"?>
01670 <!DOCTYPE html
01671   PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
01672   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
01673 
01674 <html xmlns="http://www.w3.org/1999/xhtml"
01675   xml:lang="en" lang="en">
01676 <head>
01677 <style type="text/css">/*<![CDATA[*/
01678 
01679 .flexible th {
01680 white-space:normal;
01681 }
01682 th.header, td.header, div.header {
01683 border-color:#DDDDDD;
01684 background-color:lightGrey;
01685 }
01686 .flexible th {
01687 white-space:nowrap;
01688 }
01689 th {
01690 font-weight:bold;
01691 }
01692 
01693 .generaltable {
01694 border-style:solid;
01695 }
01696 .generalbox {
01697 border-style:solid;
01698 }
01699 body, table, td, th {
01700 font-family:Arial,Verdana,Helvetica,sans-serif;
01701 font-size:100%;
01702 }
01703 td {
01704     border-style:solid;
01705     border-width:1pt;
01706 }
01707 table {
01708     border-collapse:collapse;
01709     border-spacing:0pt;
01710     width:80%;
01711     margin:auto;
01712 }
01713 
01714 h1, h2 {
01715     text-align:center;
01716 }
01717 .bold {
01718 font-weight:bold;
01719 }
01720 .mdl-align {
01721     text-align:center;
01722 }
01723 /*]]>*/</style>
01724 <title>$filename</title>
01725 </head>
01726 <body>
01727 EOF;
01728         $this->documentstarted = true;
01729     }
01730 
01731     function start_table($sheettitle) {
01732         $this->table->sortable(false);
01733         $this->table->collapsible(false);
01734         echo "<h2>{$sheettitle}</h2>";
01735         $this->table->start_html();
01736     }
01737 
01738     function output_headers($headers) {
01739         $this->table->print_headers();
01740     }
01741 
01742     function add_data($row) {
01743         $this->table->print_row($row);
01744         return true;
01745     }
01746 
01747     function add_seperator() {
01748         $this->table->print_row(NULL);
01749         return true;
01750     }
01751 
01752     function finish_table() {
01753         $this->table->finish_html();
01754     }
01755 
01756     function finish_document() {
01757         echo "</body>\n</html>";
01758         exit;
01759     }
01760 
01761     function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL) {
01762         if (is_null($options)) {
01763             $options = new stdClass;
01764         }
01765         //some sensible defaults
01766         if (!isset($options->para)) {
01767             $options->para = false;
01768         }
01769         if (!isset($options->newlines)) {
01770             $options->newlines = false;
01771         }
01772         if (!isset($options->smiley)) {
01773             $options->smiley = false;
01774         }
01775         if (!isset($options->filter)) {
01776             $options->filter = false;
01777         }
01778         return format_text($text, $format, $options);
01779     }
01780 }
 All Data Structures Namespaces Files Functions Variables Enumerations