(root)/shared-tablehandler.php - Rev 435
Rev 410 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
<?php
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* This file is part of Travelsized CMS
* A content management system with modules, based on wiki syntax
*
* Author: Dan Jensen <admin@leinir.dk>
* Copyright 2003/2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License is available at: http://www.gnu.org/copyleft/
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
The table class contains and manages the model of a table, including CSS classes and cell spans
Sample code for the Table class:
\code
$testtable = new Table("table", "defaultrow", "defaultcell");
$testtable->addRow( null );
$testtable->addRow( "row2" );
$testtable->addRows( 5 );
$testtable->addColumn();
$testtable->addColumn( "column2" );
$testtable->addColumns( 5 );
$testtable->setContent( 0, 0, "0-0" );
$testtable->setContent( 0, 1, "0-1" );
$testtable->setContent( 0, 2, "0-2" );
$testtable->setContent( 0, 3, "0-3" );
$testtable->setContent( 0, 4, "0-4" );
$testtable->setContent( 0, 5, "0-5" );
$testtable->setRowContent( 1, true, "1-0", "1-1", "1-2", "1-3", "1-4", "1-5" );
$testtable->setRowContent( 2, true, "2-0", "2-1", "2-2", "2-3", "2-4", "2-5" );
$testtable->setRowContent( 3, true, "3-0", "3-1", "3-2", "3-3", "3-4", "3-5" );
$testtable->setRowContent( 4, true, "4-0", "4-1", "4-2", "4-3", "4-4", "4-5" );
$testtable->setRowContent( 5, true, "5-0", "5-1", "5-2", "5-3", "5-4", "5-5" );
$testtable->setSpan( 1, 1, null, 3 );
$testtable->setSpan( 2, 1, 2, null );
$testtable->setSpan( 3, 3, 2, 2 );
echo $testtable->render();
$testtable2 = new Table("table", "defaultrow", "defaultcell");
$testtable2->newRow();
$testtable2->newCell("0.0");
$testtable2->newCell("0.1");
$testtable2->newRow();
$testtable2->newCell("1.0");
$testtable2->newCell("1.1", 2);
echo $testtable2->render();
\endcode
*/
class Table
{
var $cells; ///< @var Array containing the table's cells in the form [row][col] = array( content => "", styleClass => "", rowSpan => "", colSpan => "", $pageData = true, inSpan => false) If styleClass == null, columnClass is used
var $rows; ///< @var Array containing the styles for the rows, and wether the row is a header row rows[] = array( styleClass => "", headerRow => false )
var $columns; ///< @var Array cointaining the styles for each cell in the column. If != null, this overrides the table's default style
var $tableClass; ///< @var What is this table's CSS class
var $defaultRowClass; ///< @var What is the default class for rows
var $defaultCellClass; ///< @var What is the default class cells will be given if they have no class, and the column they are in has no class assigned to them
///\private
var $currentRow; ///< @var Points to the current row - used for sequential table construction
var $currentCell; ///< @var Points to the current cell in the current row - used for sequential table construction
/**
* Construct a new table instance
*
* @param tableClass The table's CSS class
* @param defaultRowClass The default class of news rows
* @param defaultCellClass The fallback class for contained cells. This will be used if the cell has no class assigned, and it is contained in a column with no class assigned
* @param rows How many rows are in this table. Most often this will be 0, to be added later using addRow and addRows
* @param columns How many columns are in this table. Most often this will be 0, to be added later using addColumn and addColumns
*/
function Table
( $tableClass = "setup", $defaultRowClass = "setup", $defaultCellClass = "setup", $rows = 0, $columns = 0 )
{
$this->tableClass = $tableClass;
$this->defaultRowClass = $defaultRowClass;
$this->defaultCellClass = $defaultCellClass;
$this->cells = array();
$this->rows = array();
$this->columns = array();
if( $rows > 0 )
for( $i = 0; $i < $rows; $i++ )
$this->addRow();
if( $columns > 0 )
for( $i = 0; $i < $columns; $i++ )
$this->addColumn();
}
/**
* This will add a range of rows to the table, at an optional specified position
*
* @param thisRowClass A string describing which class to give the row
* @param headerRow A boolean describing wether this is a header row
* @param where An optional integer describing which row to add the row after. Defaults to the end
*/
function addRow
( $thisRowClass = null, $headerRow = false, $where = null )
{
if( $where == null )
{
$where = count($this->rows);
}
else
{
///\todo Make this work!
// Move the existing rows and cells out of the way to make space for the new row
for( $i = count($this->rows) - 1; $i > $where; $i-- )
{
$this->rows[$i + 1] = $this->rows[$i];
$this->cells[$i + 1] = $this->cells[$i];
}
}
$this->rows[$where] = array( "styleClass" => $thisRowClass, "headerRow" => $headerRow );
}
/**
* This will add a range of rows to the table, at an optional specified position
*
* @param howMany A string describing how many rows you wish to add to the table
* @param headerRow A boolean describing wether these are header rows
* @param where An optional integer describing which row to add the rows after. Defaults to the end
* @param theseRowClass A string describing which class to give the rows
*/
function addRows
( $howMany, $theseRowClass = null, $headerRow = false, $where = null )
{
if( $where == null )
{
for( $i = 1; $i < $howMany; $i++ )
$this->addRow( $theseRowClass, $headerRow );
}
else
{
$stopHere = $where + $howMany;
for( $i = $where; $i < $stopHere; $i++ )
$this->addRow( $theseRowClass, $headerRow, $i );
}
}
/**
* Set wether a row contains a line of headers
*
* @param row The row to set header status for
* @param headerRow Boolean describing wether the row is a header row or not
*/
function setRowHeader
( $row, $headerRow = true )
{
$this->rows[$row]["headerRow"] = $headerRow;
}
/**
* Add a new column to the table as an optional position and with an optional class
*
* @param thisColumnClass The class to assign to this row
* @param where An optional integer describing which column to add this column after. Defaults to the end
*/
function addColumn
( $thisColumnClass = null, $where = null )
{
if( $where == null )
$where = count($this->columns);
else
{
///\todo Make this work!
for( $i = count($this->columns); $i > $where; $i-- )
$this->columns[$i + 1] = $this->columns[$i];
// Remember to move all cells out of the way when $where != null!
foreach( $this->cells as $key => $value )
{
for( $i = count($this->columns); $i > $where; $i-- )
$this->cells[$key][$i + 1] = $this->cells[$key][$i];
}
}
$this->columns[$where] = array( "styleClass" => $thisColumnClass );
}
/**
* This will add a range of columns to the table, at an optional specified position
*
* @param howMany A string describing how many rows you wish to add to the table
* @param theseRowClass A string describing which class to give the rows
* @param where An optional integer describing which row to add the rows after. Defaults to the end
*/
function addColumns
( $howMany, $theseColumnClass = null, $where = null )
{
if( $where == null )
{
for( $i = 1; $i < $howMany; $i++ )
$this->addColumn( $theseColumnClass );
}
else
{
$stopHere = $where + $howMany;
for( $i = $where; $i < $stopHere; $i++ )
$this->addColumn( $theseColumnClass, $i );
}
}
/**
* Set the contents of the specified cell with either rendered HTML or pagedata
*
* @param row The cell's identifying row
* @param column The cell's identifying column
* @param content The new content for this cell
* @param pageData Are the contents to be interpreted as pagedata
*/
function setContent
( $row, $column, $content, $pageData = true )
{
$this->cells[$row][$column]["content"] = $content;
$this->cells[$row][$column]["pageData"] = $pageData;
}
/**
* Set the content of an entire row in one go
*
* @param row The row to set the content of
* @param pageData Are the contents to be interpreted as pagedata
* @param contents All remaining arguments are interpreted as content to set for the cells in the row
*/
function setRowContent
( $row, $pageData = true )
{
$contents = func_get_args();
$contents = array_slice( $contents, 2 );
foreach( $contents as $key => $value )
$this->setContent( $row, $key, $value, $pageData );
}
/**
* Set the span of a single cell. If one or both of the spanranges is null, the cell is reset to not span
*
* @param row The cell's identifying row
* @param column The cell's identifying column
* @param rowSpan An integer defining how many rows to span. If null, the cell is reset to not span any rows
* @param colSpan An integer defining how many columns to span. If null, the cell is reset to not span any columns
*/
function setSpan
( $row, $column, $rowSpan = null, $colSpan = null )
{
// First, reset the old span-range
$oldRowSpan = $this->cells[$row][$column]["rowSpan"] + $row;
$oldColSpan = $this->cells[$row][$column]["colSpan"] + $column;
for( $theRow = $row; $theRow < $oldRowSpan; $theRow++ )
for( $theCol = $column; $theCol < $oldColSpan; $theCol++ )
$this->cells[$theRow][$theCol]["inSpan"] = false;
// Mark cells as part of span
$newRowSpan = $row + $rowSpan;
$newColSpan = $column + $colSpan;
if( $rowSpan == null )
{
$theRow = $row;
for( $theCol = $column; $theCol < $newColSpan; $theCol++ )
{
$this->cells[$theRow][$theCol]["inSpan"] = true;
$this->cells[$theRow][$theCol]["rowSpan"] = null;
$this->cells[$theRow][$theCol]["colSpan"] = null;
}
}
else if( $colSpan == null )
{
$theCol = $column;
for( $theRow = $row; $theRow < $newRowSpan; $theRow++ )
{
$this->cells[$theRow][$theCol]["inSpan"] = true;
$this->cells[$theRow][$theCol]["rowSpan"] = null;
$this->cells[$theRow][$theCol]["colSpan"] = null;
}
}
else
{
for( $theRow = $row; $theRow < $newRowSpan; $theRow++ )
{
for( $theCol = $column; $theCol < $newColSpan; $theCol++ )
{
$this->cells[$theRow][$theCol]["inSpan"] = true;
$this->cells[$theRow][$theCol]["rowSpan"] = null;
$this->cells[$theRow][$theCol]["colSpan"] = null;
}
}
}
// Then set the new span-range
$this->cells[$row][$column]["inSpan"] = false;
$this->cells[$row][$column]["rowSpan"] = $rowSpan;
$this->cells[$row][$column]["colSpan"] = $colSpan;
}
/**
* Set the row span of a single cell. If spanrange is null, the cell is reset to not span
*
* @param row The cell's identifying row
* @param column The cell's identifying column
* @param spanrange An integer defining how many rows to span. If null, the cell is reset to not span any rows
*/
function setRowSpan
( $row, $column, $spanrange = null )
{
$this->setSpan( $row, $column, $spanrange, $this->cells[$row][$column]["colSpan"] );
}
/**
* Set the column span of a single cell. If spanrange is null, the cell is reset to not span
*
* @param row The cell's identifying row
* @param column The cell's identifying column
* @param spanrange An integer defining how many columns to span. If null, the cell is reset to not span any columns
*/
function setColSpan
( $row, $column, $spanrange = null )
{
$this->setSpan( $row, $column, $this->cells[$row][$column]["rowSpan"], $spanrange );
}
/**
* Set the CSS style of a single cell. If className is null, the cell is reset to not have a style set (column class will then override)
*
* @param row The cell's identifying row
* @param column The cell's identifying column
* @param className A string defining which special class to assign this cell. If null, the cell is reset to fallback style
*/
function setStyleClass
( $row, $column, $className = null )
{
$this->cells[$row][$column]["styleClass"] = $className;
}
/**
* Get the contents of a specified cell.
*
* @param row The cell's identifying row
* @param column The cell's identifying column
*/
function getContent
( $row, $column )
{
return $this->cells[$row][$column]["content"];
}
/**
* Sequentially create a new row at the end of the table and set the current column to none
*
* @param thisRowClass A string describing which class to give the row
* @param headerRow A boolean describing wether this is a header row
*/
function newRow
( $thisRowClass = null, $headerRow = false )
{
$this->addRow( $thisRowClass, $headerRow );
$this->currentRow = endKey
($this->rows);
$this->currentCell = -1;
}
/**
* Sequentially add a new cell and set the contents of it, at the end of the current row
*
* @param content The contents for the new cell
* @param colSpan Optional. If the cell is to span a number of cells, input it here
*/
function newCell
( $content, $colSpan = null, $styleClass = null )
{
$this->currentCell++;
$nextCurrent = $this->currentCell;
// Make sure the column(s) actually exists
if( !array_key_exists( $this->currentCell, $this->columns ) && $colSpan == null )
$this->addColumn();
else if( $colSpan != null )
{
for( $i = 0 ; $i < $colSpan ; $i++ )
if( !array_key_exists( $this->currentCell + $i , $this->columns ) )
$this->addColumn();
$nextCurrent = endkey
($this->columns) + $i;
$this->setColSpan( $this->currentRow, $this->currentCell, $colSpan );
}
$this->setContent( $this->currentRow, $this->currentCell, $content );
$this->setStyleClass( $this->currentRow, $this->currentCell, $styleClass );
// Make sure the next current cell doesn't overwrite column spans...
$this->currentCell = $nextCurrent;
}
/**
* This function returns the rendered table
*
* @return Renders the table and returns a string containing this
*/
function render
()
{
$renderedContent = "<table class=\"" . $this->tableClass . "\">";
foreach( $this->rows as $rowID => $row )
{
$styleClass = ( $this->rows[$rowID]["styleClass"] == null ) ?
$this->defaultRowClass : $this->rows[$rowID]["styleClass"];
$renderedContent .= "\n <tr class=\"$styleClass\">";
foreach( $this->columns as $columnID => $column )
{
// We have to make sure first that the cell actually exists
if( ! array_key_exists( $rowID, $this->cells ) )
{
if( $this->columns[$columnID]["styleClass"] == null )
$cellClass = $this->defaultCellClass;
else
$cellClass = $this->columns[$columnID]["styleClass"];
$cellType = ( $row["headerRow"] ) ?
"th" : "td";
$rowSpan = ( $this->cells[$rowID][$columnID]["rowSpan"] > 0 ) ?
" rowspan=\"" . $this->cells[$rowID][$columnID]["rowSpan"] . "\"" : "";
$columnSpan = ( $this->cells[$rowID][$columnID]["colSpan"] > 0 ) ?
" colspan=\"" . $this->cells[$rowID][$columnID]["colSpan"] . "\"" : "";
$renderedContent .= "\n <$cellType class=\"$cellClass\"></$cellType>";
}
// And in case it does exist, we don't render the cell if it's part of a span field
else if( ! $this->cells[$rowID][$columnID]["inSpan"] )
{
if( $this->cells[$rowID][$columnID]["styleClass"] == null )
{
if( $this->columns[$columnID]["styleClass"] == null )
$cellClass = $this->defaultCellClass;
else
$cellClass = $this->columns[$columnID]["styleClass"];
}
else
$cellClass = $this->cells[$rowID][$columnID]["styleClass"];
$cellType = ( $row["headerRow"] ) ?
"th" : "td";
$rowSpan = ( $this->cells[$rowID][$columnID]["rowSpan"] != 0 ) ?
" rowspan=\"" . $this->cells[$rowID][$columnID]["rowSpan"] . "\"" : "";
$columnSpan = ( $this->cells[$rowID][$columnID]["colSpan"] != 0 ) ?
" colspan=\"" . $this->cells[$rowID][$columnID]["colSpan"] . "\"" : "";
$cellContent = ( $this->cells[$rowID][$columnID]["pageData"] ) ? parse_page_data
( $this->cells[$rowID][$columnID]["content"] ) : $this->cells[$rowID][$columnID]["content"];
$renderedContent .= "\n <" . $cellType . $rowSpan . $columnSpan . " class=\"$cellClass\">" . $cellContent . "</$cellType>";
}
}
$renderedContent .= "\n </tr>";
}
$renderedContent .= "</table>";
return $renderedContent;
}
}
?>