From bdff6d93df8cbaa99e84b571703b0c1569b7b108 Mon Sep 17 00:00:00 2001
From: David Mudrak <david.mudrak@gmail.com>
Date: Thu, 9 Jul 2009 16:07:36 +0200
Subject: [PATCH] MDL-19077 print_table replaced with $OUTPUT->table

rowclass property has been deprecated, rowclasses should be used.
Direct assigning of the class has been deprecated, moodle_html_elements
should be used instead. In both cases, debugging message is displayed.
Please enter the commit message for your changes. Lines starting
---
 lib/deprecatedlib.php |   28 +++++
 lib/outputlib.php     |  272 +++++++++++++++++++++++++++++++++++++++++++++++++
 lib/weblib.php        |  185 ---------------------------------
 3 files changed, 300 insertions(+), 185 deletions(-)

diff --git a/lib/deprecatedlib.php b/lib/deprecatedlib.php
index 57cc441..d02df98 100644
--- a/lib/deprecatedlib.php
+++ b/lib/deprecatedlib.php
@@ -2347,3 +2347,31 @@ function blocks_preferred_width($instances) {
     $width = 210;
 }
 
+/**
+ * Print a nicely formatted table.
+ *
+ * @deprecated since Moodle 2.0
+ *
+ * @param array $table is an object with several properties.
+ */
+function print_table($table, $return=false) {
+    global $OUTPUT;
+    debugging('print_table() has been deprecated. Please change your code to use $OUTPUT->table().');
+    $newtable = new html_table();
+    foreach ($table as $property => $value) {
+        if (property_exists($newtable, $property)) {
+            $newtable->{$property} = $value;
+        }
+    }
+    if (isset($table->rowclass) && is_array($table->rowclass)) {
+        debugging('rowclass[] has been deprecated for html_table and should be replaced by rowclasses[]. please fix the code.');
+        $newtable->rowclasses = $table->rowclass;
+    }
+    $output = $OUTPUT->table($newtable);
+    if ($return) {
+        return $output;
+    } else {
+        echo $output;
+        return true;
+    }
+}
diff --git a/lib/outputlib.php b/lib/outputlib.php
index 7b750cc..848d5bb 100644
--- a/lib/outputlib.php
+++ b/lib/outputlib.php
@@ -2301,6 +2301,179 @@ class moodle_core_renderer extends moodle_renderer_base {
     }
 
     /**
+     * Render a HTML table
+     *
+     * @param object $table {@link html_table} instance containing all the information needed
+     * @return string the HTML to output.
+     */
+    public function table(html_table $table) {
+        $table->prepare();
+        if (!empty($table->align)) {
+            foreach ($table->align as $key => $aa) {
+                if ($aa) {
+                    $align[$key] = ' text-align:'. fix_align_rtl($aa) .';';  // Fix for RTL languages
+                } else {
+                    $align[$key] = '';
+                }
+            }
+        }
+        if (!empty($table->size)) {
+            foreach ($table->size as $key => $ss) {
+                if ($ss) {
+                    $size[$key] = ' width:'. $ss .';';
+                } else {
+                    $size[$key] = '';
+                }
+            }
+        }
+        if (!empty($table->wrap)) {
+            foreach ($table->wrap as $key => $ww) {
+                if ($ww) {
+                    $wrap[$key] = ' white-space:nowrap;';
+                } else {
+                    $wrap[$key] = '';
+                }
+            }
+        }
+        if (!empty($table->tablealign)) {
+            $table->add_class('boxalign' . $table->tablealign);
+        }
+        if (!empty($table->rotateheaders)) {
+            $table->add_class('rotateheaders');
+        } else {
+            $table->rotateheaders = false; // Makes life easier later.
+        }
+
+        $attributes = array(
+                'id'            => $table->id,
+                'width'         => $table->width,
+                'summary'       => $table->summary,
+                'cellpadding'   => $table->cellpadding,
+                'cellspacing'   => $table->cellspacing,
+                'class'         => $table->get_classes_string());
+        $output = $this->output_start_tag('table', $attributes) . "\n";
+
+        $countcols = 0;
+
+        if (!empty($table->head)) {
+            $countcols = count($table->head);
+            $output .= $this->output_start_tag('thead', array()) . "\n";
+            $output .= $this->output_start_tag('tr', array()) . "\n";
+            $keys = array_keys($table->head);
+            $lastkey = end($keys);
+            foreach ($table->head as $key => $heading) {
+                $classes = array('header', 'c' . $key);
+                if (!isset($size[$key])) {
+                    $size[$key] = '';
+                } else {
+                    // assure it ends with ';' because it is going to be part of style attribute
+                    $size[$key] = substr($size[$key], -1) == ';' ? $size[$key] : $size[$key] . ';';
+                }
+                if (!isset($align[$key])) {
+                    $align[$key] = '';
+                } else {
+                    // assure it ends with ';' because it is going to be part of style attribute
+                    $align[$key] = substr($align[$key], -1) == ';' ? $align[$key] : $align[$key] . ';';
+                }
+                if (isset($table->headspan[$key]) && $table->headspan[$key] > 1) {
+                    $colspan = $table->headspan[$key];
+                } else {
+                    $colspan = '';
+                }
+                if ($key == $lastkey) {
+                    $classes[] = 'lastcol';
+                }
+                if (isset($table->colclasses[$key])) {
+                    $classes[] = $table->colclasses[$key];
+                }
+                if ($table->rotateheaders) {
+                    // we need to wrap the heading content
+                    $heading = $this->output_tag('span', '', $heading);
+                }
+                $attributes = array(
+                        'style'     => $align[$key] . $size[$key] . 'white-space:nowrap;',
+                        'class'     => moodle_renderer_base::prepare_classes($classes),
+                        'scope'     => 'col',
+                        'colspan'   => $colspan);
+                $output .= $this->output_tag('th', $attributes, $heading) . "\n";
+            }
+            $output .= $this->output_end_tag('tr') . "\n";
+            $output .= $this->output_end_tag('thead') . "\n";
+        }
+
+        if (!empty($table->data)) {
+            $oddeven    = 1;
+            $keys       = array_keys($table->data);
+            $lastrowkey = end($keys);
+            $output .= $this->output_start_tag('tbody', array()) . "\n";
+            foreach ($table->data as $key => $row) {
+                $oddeven = $oddeven ? 0 : 1;
+                if (isset($table->rowclasses[$key])) {
+                    $classes = array_unique(moodle_html_component::clean_classes($table->rowclasses[$key]));
+                } else {
+                    $classes = array();
+                }
+                $classes[] = 'r' . $oddeven;
+                if ($key == $lastrowkey) {
+                    $classes[] = 'lastrow';
+                }
+                $output .= $this->output_start_tag('tr', array('class' => moodle_renderer_base::prepare_classes($classes))) . "\n";
+                if (($row === 'hr') && ($countcols)) {
+                    $output .= $this->output_tag('td', array('colspan' => $countcols),
+                                                 $this->output_tag('div', array('class' => 'tabledivider'))) . "\n";
+                } else {  /// it's a normal row of data
+                    $keys2 = array_keys($row);
+                    $lastkey = end($keys2);
+                    foreach ($row as $key => $item) {
+                        if (isset($table->colclasses[$key])) {
+                            $classes = array_unique(moodle_html_component::clean_classes($table->colclasses[$key]));
+                        } else {
+                            $classes = array();
+                        }
+                        $classes[] = 'cell';
+                        $classes[] = 'c' . $key;
+                        if ($key == $lastkey) {
+                            $classes[] = 'lastcol';
+                        }
+                        if (!isset($size[$key])) {
+                            $size[$key] = '';
+                        } else {
+                            // assure it ends with ';' because it is going to be part of style attribute
+                            $size[$key] = substr($size[$key], -1) == ';' ? $size[$key] : $size[$key] . ';';
+                        }
+                        if (!isset($align[$key])) {
+                            $align[$key] = '';
+                        } else {
+                            // assure it ends with ';' because it is going to be part of style attribute
+                            $align[$key] = substr($align[$key], -1) == ';' ? $align[$key] : $align[$key] . ';';
+                        }
+                        if (!isset($wrap[$key])) {
+                            $wrap[$key] = '';
+                        } else {
+                            // assure it ends with ';' because it is going to be part of style attribute
+                            $wrap[$key] = substr($wrap[$key], -1) == ';' ? $wrap[$key] : $wrap[$key] . ';';
+                        }
+                        $output .= $this->output_tag('td',
+                                                     array('style' => $align[$key] . $size[$key] . $wrap[$key],
+                                                           'class' => moodle_renderer_base::prepare_classes($classes)),
+                                                     $item) . "\n";
+                    }
+                }
+                $output .= $this->output_end_tag('tr') . "\n";
+            }
+            $output .= $this->output_end_tag('tbody') . "\n";
+        }
+        $output .= $this->output_end_tag('table') . "\n";
+
+        if ($table->rotateheaders && can_use_rotated_text()) {
+            $this->page->requires->yui_lib('event');
+            $this->page->requires->js('course/report/progress/textrotate.js');
+        }
+
+        return $output;
+    }
+
+    /**
      * Output the place a skip link goes to.
      * @param $id The target name from the corresponding $PAGE->requires->skip_link_to($target) call.
      * @return string the HTML to output.
@@ -2641,6 +2814,105 @@ class block_contents extends moodle_html_component {
 
 
 /**
+ * Holds all the information required to render a <table> by
+ * {@link moodle_core_renderer::table()} or by an overridden version of that
+ * method in a subclass.
+ *
+ * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since     Moodle 2.0
+ */
+class html_table extends moodle_html_component {
+    /**
+     * @var array of heading names
+     */
+    public $head;
+    /**
+     * @var array can be used to make a heading span multiple columns
+     */
+    public $headspan;
+    /**
+     * @var array of column alignments
+     */
+    public $align;
+    /**
+     * @var array of column sizes
+     */
+    public $size;
+    /**
+     * @var array of "nowrap"s or nothing
+     */
+    public $wrap;
+    /**
+     * @var array of arrays containing the data. Alternatively, if you have
+     * $head specified, the string 'hr' (for horizontal ruler) can be used
+     * instead of an array of cells data resulting in a divider rendered.
+     */
+    public $data;
+    /**
+     * @var string width of the table, percentage of the page prefered
+     */
+    public $width = '80%';
+    /**
+     * @var string alignment the whole table
+     */
+    public $tablealign = 'center';
+    /**
+     * @var int padding on each cell, in pixels
+     */
+    public $cellpadding = 5;
+    /**
+     * @var int spacing between cells, in pixels
+     */
+    public $cellspacing = 1;
+    /**
+     * @var array classes to add to particular rows, space-separated string
+     */
+    public $rowclasses;
+    /**
+     * @var array classes to add to every cell in a particular colummn, space-separated string
+     */
+    public $colclasses;
+    /**
+     * @var string description of the contents for screen readers.
+     */
+    public $summary;
+    /**
+     * @var bool true causes the contents of the heading cells to be rotated 90 degrees.
+     */
+    public $rotateheaders = false;
+
+    /**
+     * Constructor allows to pass the required data
+     */
+    public function __construct($data=null) {
+        $this->data = $data;
+    }
+
+    /**
+     * @see moodle_html_component::prepare()
+     */
+    public function prepare() {
+        if (empty($this->classes)) {
+            $this->set_classes(array('generaltable'));
+        }
+        parent::prepare();
+    }
+
+    public function __set($name, $value) {
+        if ($name == 'rowclass') {
+            debugging('rowclass[] has been deprecated for html_table and should be replaced by rowclasses[]. please fix the code.');
+            $this->rowclasses = $value;
+        }
+        if ($name == 'class') {
+            debugging('this way of setting css class has been deprecated. use set_classes() method instead.');
+            $this->set_classes($value);
+        }
+    }
+}
+
+
+/**
  * A renderer that generates output for commandlines scripts.
  *
  * The implementation of this renderer is probably incomplete.
diff --git a/lib/weblib.php b/lib/weblib.php
index 9b84b37..4036bfe 100644
--- a/lib/weblib.php
+++ b/lib/weblib.php
@@ -3628,191 +3628,6 @@ function print_png($url, $sizex, $sizey, $return, $parameters='alt=""') {
     }
 }
 
-/**
- * Print a nicely formatted table.
- *
- * @param array $table is an object with several properties.
- * <ul>
- *     <li>$table->head - An array of heading names.
- *     <li>$table->align - An array of column alignments
- *     <li>$table->size  - An array of column sizes
- *     <li>$table->wrap - An array of "nowrap"s or nothing
- *     <li>$table->data[] - An array of arrays containing the data.
- *     <li>$table->width  - A percentage of the page
- *     <li>$table->tablealign  - Align the whole table
- *     <li>$table->cellpadding  - Padding on each cell
- *     <li>$table->cellspacing  - Spacing between cells
- *     <li>$table->class - class attribute to put on the table
- *     <li>$table->id - id attribute to put on the table.
- *     <li>$table->rowclass[] - classes to add to particular rows. (space-separated string)
- *     <li>$table->colclass[] - classes to add to every cell in a particular colummn. (space-separated string)
- *     <li>$table->summary - Description of the contents for screen readers.
- *     <li>$table->headspan can be used to make a heading span multiple columns.
- *     <li>$table->rotateheaders - Causes the contents of the heading cells to be rotated 90 degrees.
- * </ul>
- * @param bool $return whether to return an output string or echo now
- * @return boolean|string depending on $return
- */
-function print_table($table, $return=false) {
-    $output = '';
-
-    if (isset($table->align)) {
-        foreach ($table->align as $key => $aa) {
-            if ($aa) {
-                $align[$key] = ' text-align:'. fix_align_rtl($aa) .';';  // Fix for RTL languages
-            } else {
-                $align[$key] = '';
-            }
-        }
-    }
-    if (isset($table->size)) {
-        foreach ($table->size as $key => $ss) {
-            if ($ss) {
-                $size[$key] = ' width:'. $ss .';';
-            } else {
-                $size[$key] = '';
-            }
-        }
-    }
-    if (isset($table->wrap)) {
-        foreach ($table->wrap as $key => $ww) {
-            if ($ww) {
-                $wrap[$key] = ' white-space:nowrap;';
-            } else {
-                $wrap[$key] = '';
-            }
-        }
-    }
-
-    if (empty($table->width)) {
-        $table->width = '80%';
-    }
-
-    if (empty($table->tablealign)) {
-        $table->tablealign = 'center';
-    }
-
-    if (!isset($table->cellpadding)) {
-        $table->cellpadding = '5';
-    }
-
-    if (!isset($table->cellspacing)) {
-        $table->cellspacing = '1';
-    }
-
-    if (empty($table->class)) {
-        $table->class = 'generaltable';
-    }
-    if (!empty($table->rotateheaders)) {
-        $table->class .= ' rotateheaders';
-    } else {
-        $table->rotateheaders = false; // Makes life easier later.
-    }
-
-    $tableid = empty($table->id) ? '' : 'id="'.$table->id.'"';
-
-    $output .= '<table width="'.$table->width.'" ';
-    if (!empty($table->summary)) {
-        $output .= " summary=\"$table->summary\"";
-    }
-    $output .= " cellpadding=\"$table->cellpadding\" cellspacing=\"$table->cellspacing\" class=\"$table->class boxalign$table->tablealign\" $tableid>\n";
-
-    $countcols = 0;
-
-    if (!empty($table->head)) {
-        $countcols = count($table->head);
-        $output .= '<tr>';
-        $keys = array_keys($table->head);
-        $lastkey = end($keys);
-        foreach ($table->head as $key => $heading) {
-            $classes = array('header', 'c' . $key);
-            if (!isset($size[$key])) {
-                $size[$key] = '';
-            }
-            if (!isset($align[$key])) {
-                $align[$key] = '';
-            }
-            if (isset($table->headspan[$key]) && $table->headspan[$key] > 1) {
-                $colspan = ' colspan="' . $table->headspan[$key] . '"';
-            } else {
-                $colspan = '';
-            }
-            if ($key == $lastkey) {
-                $classes[] = 'lastcol';
-            }
-            if (isset($table->colclasses[$key])) {
-                $classes[] = $table->colclasses[$key];
-            }
-            if ($table->rotateheaders) {
-                $wrapperstart = '<span>';
-                $wrapperend = '</span>';
-            } else {
-                $wrapperstart = '';
-                $wrapperend = '';
-            }
-
-            $output .= '<th style="'. $align[$key].$size[$key] .
-                    ';white-space:nowrap;" class="'.implode(' ', $classes).'" scope="col"' . $colspan . '>'.
-                    $wrapperstart . $heading . $wrapperend . '</th>';
-        }
-        $output .= '</tr>'."\n";
-    }
-
-    if (!empty($table->data)) {
-        $oddeven = 1;
-        $keys=array_keys($table->data);
-        $lastrowkey = end($keys);
-        foreach ($table->data as $key => $row) {
-            $oddeven = $oddeven ? 0 : 1;
-            if (!isset($table->rowclass[$key])) {
-                $table->rowclass[$key] = '';
-            }
-            if ($key == $lastrowkey) {
-                $table->rowclass[$key] .= ' lastrow';
-            }
-            $output .= '<tr class="r'.$oddeven.' '.$table->rowclass[$key].'">'."\n";
-            if ($row == 'hr' and $countcols) {
-                $output .= '<td colspan="'. $countcols .'"><div class="tabledivider"></div></td>';
-            } else {  /// it's a normal row of data
-                $keys2 = array_keys($row);
-                $lastkey = end($keys2);
-                foreach ($row as $key => $item) {
-                    $classes = array('cell', 'c' . $key);
-                    if (!isset($size[$key])) {
-                        $size[$key] = '';
-                    }
-                    if (!isset($align[$key])) {
-                        $align[$key] = '';
-                    }
-                    if (!isset($wrap[$key])) {
-                        $wrap[$key] = '';
-                    }
-                    if ($key == $lastkey) {
-                        $classes[] = 'lastcol';
-                    }
-                    if (isset($table->colclasses[$key])) {
-                        $classes[] = $table->colclasses[$key];
-                    }
-                    $output .= '<td style="'. $align[$key].$size[$key].$wrap[$key] .'" class="'.implode(' ', $classes).'">'. $item .'</td>';
-                }
-            }
-            $output .= '</tr>'."\n";
-        }
-    }
-    $output .= '</table>'."\n";
-
-    if ($table->rotateheaders && can_use_rotated_text()) {
-        $PAGE->requires->yui_lib('event');
-        $PAGE->requires->js('course/report/progress/textrotate.js');
-    }
-
-    if ($return) {
-        return $output;
-    }
-
-    echo $output;
-    return true;
-}
 
 /**
  * Display a recent activity note
-- 
1.6.0.6

