Scripts
OO Html Tabel
Omdat ik laatste dagen wat table classen ben tegen gekomen zal ik diegene die ik ook altijd gebruik ook posten. Dit is volledig OO opgezet en maakt ook gebruik van SPL interfaces. Heb poor mans namespacing toegepast omdat ik het voor 5.x compatible wil hebben.
oo-html-tabel
library/My/Html/Element/Abstract.php:
<?php
/**
*
*/
/**
* Class from which every html should be extended
*
* @abstract
*/
abstract class My_Html_Element_Abstract {
/**
* Are the elements defined in XHTML?
* @static
* @var bool
*/
protected static $_xhtml = true;
/**
* Set/get whether xhtml will be used
*
* @param bool|null $bool
*
* @return void|bool
*/
public static function xhtml ( $bool = null ) {
if ( $bool === null ) {
return self::$_xhtml;
}
self::$_xhtml = (bool)$bool;
}
/**
* Holds all the attributes for this element.
* @var array
*/
protected $_attribs = array ();
/**
* Class constructor
*
* @param array $attribs
*/
public function __construct ( array $attribs = array () ) {
if ( count ( $attribs ) ) {
$this->setAttribs ( $attribs );
}
}
/**
* Try to render the element
*
* @return string
*/
public function __toString () {
try {
return $this->render ();
} catch ( Exception $e ) {
return '';
}
}
/**
* The method for rendering
*
* @abstract
*
* @return string
*/
public abstract function render ();
/**
* Set an attribute
*
* @param string $attrib
* @param string $value
*
* @return My_Html_Element_Abstract
*/
public function setAttrib ( $attrib, $value ) {
$this->_attribs [ $attrib ] = $value;
return $this;
}
/**
* Set attributes
*
* @param array $attribs
*
* @return My_Html_Element_Abstract
*/
public function setAttribs ( $attribs ) {
$this->_attribs = array_merge ( $this->_attribs, $attribs );
return $this;
}
/**
* Has this elment an attribute?
*
* @param string $attrib
*
* @return bool
*/
public function hasAttrib ( $attrib ) {
return array_key_exists ( $attrib, $this->_attribs );
}
/**
* Method for rendering the attribute string
*
* @param array $extras OPTIONAL
*
* @return string
*/
protected function _attribString ( array $extras = array () ) {
// First initialize
$return = array ();
$attribs = $this->_attribs;
// Maybe some extra attributes were given
foreach ( $extras as $attrib => $value ) {
if ( empty ( $value ) ) {
continue;
}
// Maybe special functions are used? (+, -)
$first = substr ( $attrib, 0, 1 );
$key = substr ( $attrib, 1 );
// Switch on special function
switch ( $first ) {
case '+': // Append this new value to the current value
if ( isset ( $attribs [ $key ] ) ) {
$attribs [ $key ] .= ' ' . $value;
} else {
$attribs [ $key ] = $value;
}
break;
case '-': // Remove this new value from the current value
if ( isset ( $attribs [ $key ] ) ) {
$exploded = explode ( ' ', $attribs [ $key ] );
foreach ( $exploded as $k => $v ) {
if ( $v === $value ) {
unset ( $exploded [ $k ] );
}
}
$attribs [ $key ] = implode ( ' ', $exploded );
}
break;
default: // Just set the value
$attribs [ $attrib ] = $value;
}
}
// Render the string
foreach ( $attribs as $attrib => $value ) {
if ( $value === null ) {
continue;
}
$return [] = $attrib . '=' . '"' . htmlentities ( $value ) . '"';
}
// Return nothing on empty, else separated by spaces
if ( count ( $return ) === 0 ) {
return '';
} else {
return ' ' . implode ( ' ', $return );
}
}
}
?>
library/My/Html/Element/Table.php:
<?php
/**
*
*/
/**
* Base class for the table element
*/
class My_Html_Element_Table extends My_Html_Element_Abstract implements IteratorAggregate, Countable, ArrayAccess {
const TAG = 'table';
/**
* The head element
* @var My_Html_Element_THead
*/
protected $_head;
/**
* The body element
* @var My_Html_Element_TBody
*/
protected $_body;
/**
* Class constructor
*
* @param array $rows
* @param array $attribs
*
* @return void
*/
public function __construct ( array $rows = array (), array $attribs = array () ) {
parent::__construct ( $attribs );
$this->addRows ( $rows );
}
/**
* Overloads to body when possible
*
* @param string $method
* @param array $argumentsS
*
* @return mixed
*/
public function __call ( $method, array $arguments ) {
// Check if method exists in the body, if so proxy to it.
if ( method_exists ( $this->getBody (), $method ) ) {
$result = call_user_func_array ( array ( $this->getBody (), $method ), $arguments );
// Maybe the method had a fluent interface, make sure we redirect to this object
return ($result instanceof My_Html_Element_TBody) ? $this : $result;
}
trigger_error ( 'Call to undefined method ' . get_class ( $this ) . '::' . $method . '()', E_USER_ERROR );
}
/**
* Returns the head element of this table.
*
* @return My_Html_Element_THead
*/
public function getHead () {
if ( $this->_head === null ) {
$this->_head = new My_Html_Element_THead;
}
return $this->_head;
}
/**
* If instance of THead, it sets the head value of this class
* else it proxies to THead::setRow
*
* @param My_Html_Element_THead|My_Html_Element_TR|array $head
*
* @return My_Html_Element_Table
*/
public function setHead ( $head ) {
if ( $head instanceof My_Html_Element_THead ) {
$this->_head = $head;
} else {
$this->getHead ()->setRow ( $head );
}
return $this;
}
/**
* Returns the body element of this table.
*
* @return My_Html_Element_TBody
*/
public function getBody () {
if ( $this->_body === null ) {
$this->_body = new My_Html_Element_TBody;
}
return $this->_body;
}
/**
* Sets the body element of this table.
*
* @param My_Html_Element_TBody $body
*
* @return My_Html_Element_Table
*/
public function setBody ( My_Html_Element_TBody $body ) {
$this->_body = $body;
return $this;
}
/**
* Returns the element as a string
*
* @return string
*/
public function render () {
$return = '<' . self::TAG . $this->_attribString () . '>';
$return .= PHP_EOL;
$return .= $this->getHead ()->render ();
$return .= PHP_EOL;
$return .= $this->getBody ()->render ();
$return .= PHP_EOL;
$return .= '</' . self::TAG . '>';
return $return;
}
// INTERFACES
/**
* IteratorAggregate implementation
*
* @return Iterator
*/
public function getIterator () {
return $this->getBody ()->getIterator ();
}
/**
* Countable implementation
*
* @return int
*/
public function count () {
return count ( $this->getBody () );
}
/**
* Partial ArrayAccess implementation
*
* @return My_Html_Element_TR
*/
public function offsetGet ( $offset ) {
return $this->getBody ()->offsetGet ( $offset );
}
/**
* Partial ArrayAccess implementation
*
* @return void
*/
public function offsetSet ( $offset, $value ) {
$this->getBody ()->offsetSet ( $offset );
}
/**
* Partial ArrayAccess implementation
*
* @return bool
*/
public function offsetExists ( $offset ) {
return $this->getBody ()->offsetExists ( $offset );
}
/**
* Partial ArrayAccess implementation
*
* @return void
*/
public function offsetUnset ( $offset ) {
$this->getBody ()->offsetUnset ( $offset );
}
}
?>
library/My/Html/Element/THead.php:
<?php
/**
*
*/
/**
* Base class for the thead element
*/
class My_Html_Element_THead extends My_Html_Element_Abstract {
const TAG = 'thead';
/**
* Holds the row for thead element
* @var My_Html_Element_TR
*/
protected $_row = null;
/**
* Class constructor
*
* @return void
*/
public function __construct () {
$this->_row = new My_Html_Element_TR ( array (), true );
}
/**
* Set the row values for this element
*
* @param My_Html_Element_TR|array $row
*
* @return My_Html_Element_THead
*/
public function setRow ( $row ) {
if ( $row instanceof My_Html_Element_TR ) {
$this->_row = $row;
} elseif ( is_array ( $row ) ) {
$this->_row->setCells ( $row );
} else {
throw new InvalidArgumentException ( gettype ( $row ) . ' given where array or instanceof My_Html_Element_TR expected' );
}
return $this;
}
/**
* Returns the row for this element
*
* @return My_Html_Element_TR
*/
public function getRow () {
if ( $this->_row === null ) {
$this->_row = new My_Html_Element_TR;
}
return $this->_row;
}
/**
* Returns this element as a string
*
* @return string
*/
public function render () {
$return = '<' . self::TAG . $this->_attribString () . '>';
$return .= PHP_EOL;
$return .= $this->getRow ()->render ();
$return .= PHP_EOL;
$return .= '</' . self::TAG . '>';
return $return;
}
}
?>
library/My/Html/Element/TR.php:
<?php
/**
*
*/
/**
* Base class for the tr element
*/
class My_Html_Element_TR extends My_Html_Element_Abstract implements IteratorAggregate, Countable, ArrayAccess {
const TAG = 'tr';
/**
* Holds the cells
* @var array
*/
protected $_cells = array ();
/**
* The class which this class excepts as cell element
* @var string
*/
protected $_accept = 'My_Html_Element_TD';
/**
* Class constructor
*
* @param array $cells
* @param bool $head Is this tr part of THead?
*/
public function __construct ( array $cells = array (), $head = false ) {
if ( $head ) {
$this->_accept = 'My_Html_Element_TH';
}
$this->setCells ( $cells );
}
/**
* Get a cell
*
* @param int $cell
*
* @return My_Html_Element_TD|My_Html_Element_TH
*/
public function getCell ( $cell ) {
if ( !isset ( $this->_cells [ $cell ] ) ) {
throw new OutOfBoundsException ( 'Offset does not exist' );
}
return $this->_cells [ $cell ];
}
/**
* Set a cell
*
* @param int $cell
* @param My_Html_Element_TD|My_Html_Element_TH $value
*
* @return My_Html_Element_TR
*/
public function setCell ( $cell, $value ) {
$this->_cells [ $cell ] = $value;
return $this;
}
/**
* Set multiple cells
*
* @param array $cells
*
* @return My_Html_Element_TR
*/
public function setCells ( array $cells ) {
$store = array ();
foreach ( $cells as $cell ) {
if ( is_object ( $cell ) && get_class ( $cell ) === $this->_accept ) {
throw new RuntimeException ( 'Cell should be of type ' . $this->_accept );
} elseif ( is_object ( $cell ) ) {
$store [] = $cell;
} else {
$store [] = new $this->_accept ( $cell );
}
}
$this->_cells = $store;
return $this;
}
/**
* Returns this element as a string
*
* @return string
*/
public function render () {
$args = func_get_args ();
$class = isset ( $args [ 0 ] ) && is_string ( $args [ 0 ] ) ? $args [ 0 ] : '';
$return = '<' . self::TAG . $this->_attribString ( array ( '+class' => $class ) ) . '>';
$return .= PHP_EOL;
foreach ( $this as $cell ) {
$return .= $cell->render ();
$return .= PHP_EOL;
}
$return .= '</' . self::TAG . '>';
return $return;
}
// INTERFACES
/**
* IteratorAggregate implementation
*
* @return Iterator
*/
public function getIterator () {
return new ArrayIterator ( $this->_cells );
}
/**
* Countable implementation
*
* @return int
*/
public function count () {
return count ( $this->_cells );
}
/**
* Partial ArrayAccess implementation
*
* @return My_Html_Element_TR
*/
public function offsetGet ( $offset ) {
return $this->getCell ( $offset );
}
/**
* Partial ArrayAccess implementation
*
* @return void
*/
public function offsetSet ( $offset, $value ) {
$this->_cells [ $offset ] = $value;
}
/**
* Partial ArrayAccess implementation
*
* @return bool
*/
public function offsetExists ( $offset ) {
try {
$this->getCell ( $offset );
} catch ( Exception $e ) {
return false;
}
return true;
}
/**
* Partial ArrayAccess implementation
*
* @return void
*/
public function offsetUnset ( $offset ) {
unset ( $this->_cells [ $offset ] );
}
}
?>
library/My/Html/Element/TH.php:
<?php
/**
*
*/
/**
* Base class for the th element
*/
class My_Html_Element_TH extends My_Html_Element_Abstract {
const TAG = 'th';
/**
* Holds the value of this element
* @var string
*/
protected $_value;
/**
* Class constructor
*
* @param string $value OPTIONAL
*
* @return void
*/
public function __construct ( $value = null ) {
$this->_value = $value;
}
/**
* Returns the value of this element
*
* @return string
*/
public function getValue () {
return $this->_value;
}
/**
* Sets the value of this element
*
* @param string $value
*
* @return My_Html_Element_TD
*/
public function setValue ( $value ) {
$this->_value = $value;
return $this;
}
/**
* Returns this element as a string
*
* @return string
*/
public function render () {
$return = '<' . self::TAG . $this->_attribString () . '>';
$return .= $this->getValue ();
$return .= '</' . self::TAG . '>';
return $return;
}
}
?>
library/My/Html/Element/TBody.php:
<?php
/**
*
*/
/**
* Base class for the tbody element
*/
class My_Html_Element_TBody extends My_Html_Element_Abstract implements IteratorAggregate, Countable, ArrayAccess {
const TAG = 'tbody';
/**
* Holds the classes for rows
* @var array
*/
protected $_rowClasses = array ();
/**
* Holds the rows of this body.
* @var array
*/
protected $_rows = array ();
/**
* Class constructor
*
* @param array $rows
* @param array $attribs
*
* @return void
*/
public function __construct ( array $rows = array (), array $attribs = array () ) {
parent::__construct ( $attribs );
}
/**
* Returns the row classes for this table.
*
* @return array
*/
public function getRowClasses () {
return $this->_rowClasses;
}
/**
* Sets the row classes for this table.
*
* @param array $classes
*
* @return My_Html_Element_Table
*/
public function setRowClasses ( array $classes ) {
$this->_rowClasses = $classes;
return $this;
}
/**
* Adds a new row
*
* @param My_Html_Element_TR|array $row
*
* @return My_Html_Element_TBody
*/
public function addRow ( $row ) {
if ( $row instanceof My_Html_Element_TR ) {
$this->_rows [] = $row;
} elseif ( is_array ( $row ) ) {
$this->_rows [] = new My_Html_Element_TR ( $row );
} else {
throw new InvalidArgumentException ( gettype ( $row ) . ' given where array or instanceof My_Html_Element_TR expected' );
}
return $this;
}
/**
* Adds rows
*
* @param array $rows
*
* @return My_Html_Element_TBody
*/
public function addRows ( array $rows ) {
foreach ( $rows as $row ) {
$this->addRow ( $row );
}
return $this;
}
/**
* Removes a row
*
* @param My_Html_Element_TR|int $row
*
* @return My_Html_Element_TBody
*/
public function removeRow ( $row ) {
// Make sure we have a My_Html_Element_TR
$row = $this->getRow ( $row );
foreach ( $this->_rows as $key => $r ) {
if ( $row === $r ) {
unset ( $this->_rows [ $key ] );
}
}
return $this;
}
/**
* Returns the given row for this index
*
* @param My_Html_Element_TR|int $row
*
* @return My_Html_Element_TR
*/
public function getRow ( $tr ) {
if ( $tr instanceof My_Html_Element_TR ) {
return $tr;
} elseif ( ctype_digit ( (string)$tr ) ) {
if ( !isset ( $this->_rows [ $tr ] ) ) {
throw new OutOfRangeException ( 'Index not set' );
}
return $this->_rows [ $tr ];
} else {
throw new InvalidArgumentException ( 'Row type not supported' );
}
}
/**
* Returns all the rows in this element
*
* @returns array
*/
public function getRows () {
return $this->_rows;
}
/**
* Returns this element as a string
*
* @return string
*/
public function render () {
$return = '<' . self::TAG . $this->_attribString () . '>';
$return .= PHP_EOL;
$classCount = count ( $this->_rowClasses );
foreach ( $this as $key => $row ) {
$return .= $classCount > 0 ? $row->render ( $this->_rowClasses [ $key % $classCount ] ) : $row->render ();
$return .= PHP_EOL;
}
$return .= '</' . self::TAG . '>';
return $return;
}
// INTERFACES
/**
* IteratorAggregate implementation
*
* @return Iterator
*/
public function getIterator () {
return new ArrayIterator ( $this->_rows );
}
/**
* Countable implementation
*
* @return int
*/
public function count () {
return count ( $this->_rows );
}
/**
* Partial ArrayAccess implementation
*
* @return My_Html_Element_TR
*/
public function offsetGet ( $offset ) {
return $this->getRow ( $offset );
}
/**
* Partial ArrayAccess implementation
*
* @return void
*/
public function offsetSet ( $offset, $value ) {
$this->_rows [ $offset ] = $value;
}
/**
* Partial ArrayAccess implementation
*
* @return bool
*/
public function offsetExists ( $offset ) {
try {
$this->getRow ( $offset );
} catch ( Exception $e ) {
return false;
}
return true;
}
/**
* Partial ArrayAccess implementation
*
* @return void
*/
public function offsetUnset ( $offset ) {
unset ( $this->_rows [ $offset ] );
}
}
?>
library/My/Html/Element/TD.php:
<?php
/**
*
*/
/**
* Base class for the td element
*/
class My_Html_Element_TD extends My_Html_Element_Abstract {
const TAG = 'td';
/**
* Holds the value of this element
* @var string
*/
protected $_value;
/**
* Class constructor
*
* @param string $value OPTIONAL
*
* @return void
*/
public function __construct ( $value = null ) {
$this->_value = $value;
}
/**
* Returns the value of this element
*
* @return string
*/
public function getValue () {
return $this->_value;
}
/**
* Sets the value of this element
*
* @param string $value
*
* @return My_Html_Element_TD
*/
public function setValue ( $value ) {
$this->_value = $value;
return $this;
}
/**
* Returns this element as a string
*
* @return string
*/
public function render () {
$return = '<' . self::TAG . $this->_attribString () . '>';
$return .= $this->getValue ();
$return .= '</' . self::TAG . '>';
return $return;
}
}
?>
index.php:
<?php
require_once 'library/My/Html/Element/Abstract.php';
require_once 'library/My/Html/Element/Table.php';
require_once 'library/My/Html/Element/THead.php';
require_once 'library/My/Html/Element/TR.php';
require_once 'library/My/Html/Element/TH.php';
require_once 'library/My/Html/Element/TBody.php';
require_once 'library/My/Html/Element/TD.php';
$table = new My_Html_Element_Table ( array (
array ( 'alkd', ' dddd' ),
array ( 'adf333', 'dd' ),
array ( 'asdfkasdf', 'dd' )
) );
$table->setAttrib ( 'id', 'bla' )
->setHead ( array ( 'col1', 'col2', 'col3' ) )
->addRow ( array ( 'test', 'test', 'test' ) )
->setRowClasses ( array ( 'odd', 'even', 'drie' ) );
$table->getBody ()->setAttrib ( 'id', 'kkkkk' );
$table [ 1 ] [ 0 ]->setAttrib ( 'id', 'blaaaa' );
$table->getBody ()->getRow ( 0 )->setAttrib ( 'class', 'test-class' );
echo $table;
foreach ( $table as $row ) {
foreach ( $row as $cell ) {
echo $cell->getValue () . ', ';
}
echo '<br />';
}
?>
Reacties
0