Note:

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

lib/tablelib.php: Difference between revisions

From MoodleDocs
(→‎Simple Usage: -- update skeleton code)
Line 25: Line 25:
<pre>
<pre>
<?php  // $Id$
<?php  // $Id$
/**
* Simple file test.php to drop into root of Moodle installation.
* This is the skeleton code to print a downloadable, paged, sorted table of
* data from a sql query.
*/
require "config.php";
require "config.php";
require "$CFG->libdir/tablelib.php";
require "$CFG->libdir/tablelib.php";
Line 30: Line 35:
$download = optional_param('download', '', PARAM_ALPHA);
$download = optional_param('download', '', PARAM_ALPHA);


$table = new easy_table('uniqueid', $download);
$table = new table_sql('uniqueid');
if (!$table->download()) {
$table->is_downloading($download, 'test',
                    'testing123');
if (!$table->is_downloading()) {
     // Only print headers if not asked to download data
     // Only print headers if not asked to download data
     /// Print the page header
     /// Print the page header
Line 41: Line 48:


//work out the sql for the table.
//work out the sql for the table.
$table->set_sql('*', "{$CFG->prefix}user", '1');
$table->set_sql('*', "{$CFG->prefix}user", '1');


$thisurl = new moodle_url();
$table->define_baseurl("$CFG->wwwroot/test.php");
 
$table->define_baseurl($thisurl->out(false));


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


if (!$table->download()) {
if (!$table->is_downloading()) {
     print_footer();
     print_footer();
}
}
?>
?>
</pre>
</pre>



Revision as of 08:50, 3 June 2008

Status of this doc

This doc is a description of proposed additions to the 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 additions to the 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$
/**
 * Simple file test.php to drop into root of Moodle installation.
 * This is the skeleton code to print a downloadable, paged, sorted table of
 * data from a sql query.
 */
require "config.php";
require "$CFG->libdir/tablelib.php";

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

$table = new table_sql('uniqueid');
$table->is_downloading($download, 'test',
                    'testing123');
if (!$table->is_downloading()) {
    // 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');

$table->define_baseurl("$CFG->wwwroot/test.php");

$table->out(40, true);

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

Typical Usage

Define table

Define table class in file somethingsomthing_table.php

In the file define a child class of 'easy_table'. Mostly this child class will just contain methods to format data for display.

Format data for display

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, $useinitialsbar, $filenamefordownload, $sheettitle, $downloadhelpbutton);
        
        if (!$table->download()) {
            //other html stuff to display
        }

See also