Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

lib/tablelib.php

From MoodleDocs
Revision as of 12:53, 22 May 2008 by Jamie Pratt (talk | contribs)

Status of this doc

This doc is a description of a proposed new api for using tablelib. It has not yet been agreed on. Seemed a good idea to create it at this url rather than some development notes page for instance so that the history of this page will include the changes made to the original proposal.

Why do we need a new api?

Currently the code for creating table often involves a lot of duplication of code for downloads / printed tables. Code for tables could be more concise in most cases AND tablelib internal code should be able to handle downloads of data in table. Displayed table is a paged table, downloaded data is unpaged.

New api improves things :

  • handles downloads
  • nice new way of handling data from db that needs to be processed before adding it to table.
  • more maintainable and readable code. No longer have to make sure that column data is added to the table in the same order as columns are declared. Can have the logic for choosing what columns to include in the table in one place. Appropriate code will be called to process the data to be put into the table.

Simple Usage

In order to check your sql query is working as expected when developing a page it can be useful just to output all the data from the query in the table before going on to work out how you want to format data. The code below will output all the data from your query in a collapsible, sortable table. It automatically displays all columns returned from the db.

You should go on to :

  • specify what columns to include in the table and what names to display for the columns using define_columms and define_headers
  • use your own child class of easy_table and define methods col_{columnname} to add hyperlinks etc to the table. You can also use method other_cols.

See below for examples of typical usage.

<?php  // $Id$
require "config.php";
require "$CFG->libdir/tablelib.php";

$courseid = get_site();

$download = optional_param('download', '', PARAM_ALPHA);

$table = new easy_table('uniqueid', $download);
if (!$table->download()) {
    // Only print headers if not asked to download data
    /// Print the page header
    $navigation = build_navigation('Testing table class');
    
    print_header_simple('Testing ', 'Testing table class', $navigation);

}

//work out the sql for the table.


$table->set_sql('*', "{$CFG->prefix}user", '1');

$thisurl = new moodle_url();
// Set up the table some of these settings will be ignored for downloads
$table->define_baseurl($thisurl->out(false));

$table->out(40, true, 'users', 'users');

echo $table->download_buttons();

if (!$table->download()) {
    print_footer();
}
?>


Typical Usage

Define table

Define table in file somethingsomthing_table.php

In the file define a child class of 'easy_table'. Define methods col_{colmname} to process data from db and to add it to table. Eg. Here is an example from table class quiz_report_overview_table

    function col_timefinish($attempt){
        if ($attempt->attempt) {
            if ($attempt->timefinish) {
                $timefinish = userdate($attempt->timefinish, $this->strtimeformat);
                if (!$this->download) {
                    return '<a href="review.php?q='.$this->quiz->id.'&attempt='.$attempt->attempt.'">'.$timefinish.'</a>';
                } else {
                    return $timefinish;
                }
            } else {
                return  '-';
            }
        } else {
            return  '-';
        }
    }

Where you do not know the names of the columns at the time of writing the class definition then you can use other_cols method. Eg.

    function other_cols($colname, $attempt){
        if (preg_match('/^qsgrade([0-9]+)$/', $colname, $matches)){
            $questionid = $matches[1];
            $question = $this->questions[$questionid];
            $state = new object();
            $state->event = $attempt->{'qsevent'.$questionid};
            if (question_state_is_graded($state)) {
                $grade = quiz_rescale_grade($attempt->{'qsgrade'.$questionid}, $this->quiz);
            } else {
                $grade = '--';
            }
            if (!$this->download) {
                $grade = $grade.'/'.quiz_rescale_grade($question->grade, $this->quiz);
                return link_to_popup_window('/mod/quiz/reviewquestion.php?state='.
                        $attempt->{'qsid'.$questionid}.'&number='.$question->number,
                        'reviewquestion', $grade, 450, 650, get_string('reviewresponse', 'quiz'),
                        'none', true);
            } else {
                return $grade;
            }     
        } else {
            return NULL;//no match for column name
        }
    }

If there is no method col_{column name} and other_cols returns NULL then the column data is put straight in the table unprocessed.

Use your table class

        //start page
        $download = optional_param('download', '', PARAM_ALPHA);

        $table = new name_of_your_table('uniqueid', $download);
        if (!$table->download()) {
            // Only print headers if not asked to download data
            $this->print_header_and_tabs($cm, $course, $quiz, "overview");
        }
        //various page set up stuff
        if (!$table->download()) { //do not print notices when downloading
            //wrap output of html in these if conditions
        }
        
        //work out the sql for the table.

        //use this method only if you want to specify some sql with less joins for 
        //counting the total records
        $table->set_count_sql("SELECT COUNT(1) FROM $from WHERE $where");

        if ($something) {
            // Add some more joins
        }
        
        $table->set_sql($fields, $from, $where);
        // Define table columns
        $columns = array();
        $headers = array();
        

        if (!$table->download() && $candelete) {
            $columns[]= 'checkbox';
            $headers[]= NULL;
        }
        
        if (!$table->download() && $CFG->grade_report_showuserimage) {
            $columns[]= 'picture';
            $headers[]= '';
        }
        if (!$table->download()){
            $columns[]= 'fullname';
            $headers[]= get_string('name');
        } else {
            $columns[]= 'lastname';
            $headers[]= get_string('lastname');
            $columns[]= 'firstname';
            $headers[]= get_string('firstname');
        }

        if ($CFG->grade_report_showuseridnumber) {
            $columns[]= 'idnumber';
            $headers[]= get_string('idnumber');
        }
        
        $columns[]= 'timestart';
        $headers[]= get_string('startedon', 'quiz');

        $columns[]= 'timefinish';
        $headers[]= get_string('timecompleted','quiz');

        $columns[]= 'duration';
        $headers[]= get_string('attemptduration', 'quiz');

        if ($detailedmarks) {
            foreach ($questions as $id => $question) {
                // Ignore questions of zero length
                $columns[] = 'qsgrade'.$id;
                $headers[] = '#'.$question->number;
            }
        }

        if ($showgrades) {
            $columns[] = 'sumgrades';
            $headers[] = get_string('grade', 'quiz').'/'.$quiz->grade;
        }

        if ($hasfeedback) {
            $columns[] = 'feedbacktext';
            $headers[] = get_string('feedback', 'quiz');
        }
        
        $table->define_columns($columns);
        $table->define_headers($headers);
        $table->sortable(true, 'uniqueid');
        
        // Set up the table some of these settings will be ignored for downloads
        $table->define_baseurl($reporturl->out(false, $displayoptions));


        $table->column_suppress('picture');
        $table->column_suppress('fullname');
        $table->column_suppress('idnumber');
        
        $table->no_sorting('feedbacktext');

        $table->column_class('picture', 'picture');
        $table->column_class('fullname', 'bold');
        $table->column_class('sumgrades', 'bold');

        $table->set_attribute('id', 'attempts');

        $table->out($pagesize, $useinitials, $filename, $sheettitle);
        
        if (!$table->download()) {
            //other html stuff to display
        }
        $table->download_buttons($helpbutton);