%PDF- %PDF-
| Direktori : /home1/lightco1/public_html/lightingrepublic.com.au/libraries/koowa/model/ |
| Current File : //home1/lightco1/public_html/lightingrepublic.com.au/libraries/koowa/model/table.php |
<?php
/**
* @version $Id$
* @package Koowa_Model
* @copyright Copyright (C) 2007 - 2012 Johan Janssens. All rights reserved.
* @license GNU GPLv3 <http://www.gnu.org/licenses/gpl.html>
* @link http://www.nooku.org
*/
/**
* Table Model Class
*
* Provides interaction with a database table
*
* @author Johan Janssens <johan@nooku.org>
* @package Koowa_Model
*/
class KModelTable extends KModelAbstract
{
/**
* Table object or identifier (APP::com.COMPONENT.table.TABLENAME)
*
* @var string|object
*/
protected $_table = false;
/**
* Constructor
*
* @param object An optional KConfig object with configuration options
*/
public function __construct(KConfig $config)
{
parent::__construct($config);
$this->_table = $config->table;
// Set the static states
$this->_state
->insert('limit' , 'int')
->insert('offset' , 'int')
->insert('sort' , 'cmd')
->insert('direction', 'word', 'asc')
->insert('search' , 'string')
// callback state for JSONP, needs to be filtered as cmd to prevent XSS
->insert('callback' , 'cmd');
//Try getting a table object
if($this->isConnected())
{
// Set the dynamic states based on the unique table keys
foreach($this->getTable()->getUniqueColumns() as $key => $column) {
$this->_state->insert($key, $column->filter, null, true, $this->getTable()->mapColumns($column->related, true));
}
}
}
/**
* Initializes the config for the object
*
* Called from {@link __construct()} as a first step of object instantiation.
*
* @param object An optional KConfig object with configuration options
* @return void
*/
protected function _initialize(KConfig $config)
{
$config->append(array(
'table' => $this->getIdentifier()->name,
));
parent::_initialize($config);
}
/**
* Set the model state properties
*
* This function overloads the KDatabaseTableAbstract::set() function and only acts on state properties.
*
* @param string|array|object The name of the property, an associative array or an object
* @param mixed The value of the property
* @return KModelTable
*/
public function set( $property, $value = null )
{
parent::set($property, $value);
// If limit has been changed, adjust offset accordingly
if($limit = $this->_state->limit) {
$this->_state->offset = $limit != 0 ? (floor($this->_state->offset / $limit) * $limit) : 0;
}
return $this;
}
/**
* Method to get a table object
*
* Function catches KDatabaseTableExceptions that are thrown for tables that
* don't exist. If no table object can be created the function will return FALSE.
*
* @return KDatabaseTableAbstract
*/
public function getTable()
{
if($this->_table !== false)
{
if(!($this->_table instanceof KDatabaseTableAbstract))
{
//Make sure we have a table identifier
if(!($this->_table instanceof KServiceIdentifier)) {
$this->setTable($this->_table);
}
try {
$this->_table = $this->getService($this->_table);
} catch (KDatabaseTableException $e) {
$this->_table = false;
}
}
}
return $this->_table;
}
/**
* Method to set a table object attached to the model
*
* @param mixed An object that implements KObjectServiceable, KServiceIdentifier object
* or valid identifier string
* @throws KDatabaseRowsetException If the identifier is not a table identifier
* @return KModelTable
*/
public function setTable($table)
{
if(!($table instanceof KDatabaseTableAbstract))
{
if(is_string($table) && strpos($table, '.') === false )
{
$identifier = clone $this->getIdentifier();
$identifier->path = array('database', 'table');
$identifier->name = KInflector::tableize($table);
}
else $identifier = $this->getIdentifier($table);
if($identifier->path[1] != 'table') {
throw new KDatabaseRowsetException('Identifier: '.$identifier.' is not a table identifier');
}
$table = $identifier;
}
$this->_table = $table;
return $this;
}
/**
* Test the connected status of the row.
*
* @return boolean Returns TRUE if we have a reference to a live KDatabaseTableAbstract object.
*/
public function isConnected()
{
return (bool) $this->getTable();
}
/**
* Method to get a item object which represents a table row
*
* If the model state is unique a row is fetched from the database based on the state.
* If not, an empty row is be returned instead.
*
* @return KDatabaseRow
*/
public function getItem()
{
if (!isset($this->_item))
{
if($this->isConnected())
{
$query = null;
if($this->_state->isUnique())
{
$query = $this->getTable()->getDatabase()->getQuery();
$this->_buildQueryColumns($query);
$this->_buildQueryFrom($query);
$this->_buildQueryJoins($query);
$this->_buildQueryWhere($query);
$this->_buildQueryGroup($query);
$this->_buildQueryHaving($query);
}
$this->_item = $this->getTable()->select($query, KDatabase::FETCH_ROW);
}
}
return $this->_item;
}
/**
* Get a list of items which represnts a table rowset
*
* @return KDatabaseRowset
*/
public function getList()
{
// Get the data if it doesn't already exist
if (!isset($this->_list))
{
if($this->isConnected())
{
$query = null;
if(!$this->_state->isEmpty())
{
$query = $this->getTable()->getDatabase()->getQuery();
$this->_buildQueryColumns($query);
$this->_buildQueryFrom($query);
$this->_buildQueryJoins($query);
$this->_buildQueryWhere($query);
$this->_buildQueryGroup($query);
$this->_buildQueryHaving($query);
$this->_buildQueryOrder($query);
$this->_buildQueryLimit($query);
}
$this->_list = $this->getTable()->select($query, KDatabase::FETCH_ROWSET);
}
}
return $this->_list;
}
/**
* Get the total amount of items
*
* @return int
*/
public function getTotal()
{
// Get the data if it doesn't already exist
if (!isset($this->_total))
{
if($this->isConnected())
{
//Excplicitly get a count query, build functions can then test if the
//query is a count query and decided how to build the query.
$query = $this->getTable()->getDatabase()->getQuery()->count();
$this->_buildQueryFrom($query);
$this->_buildQueryJoins($query);
$this->_buildQueryWhere($query);
$total = $this->getTable()->count($query);
$this->_total = $total;
}
}
return $this->_total;
}
/**
* Builds SELECT columns list for the query
*/
protected function _buildQueryColumns(KDatabaseQuery $query)
{
$query->select(array('tbl.*'));
}
/**
* Builds FROM tables list for the query
*/
protected function _buildQueryFrom(KDatabaseQuery $query)
{
$name = $this->getTable()->getName();
$query->from($name.' AS tbl');
}
/**
* Builds LEFT JOINS clauses for the query
*/
protected function _buildQueryJoins(KDatabaseQuery $query)
{
}
/**
* Builds a WHERE clause for the query
*/
protected function _buildQueryWhere(KDatabaseQuery $query)
{
//Get only the unique states
$states = $this->_state->getData(true);
if(!empty($states))
{
$states = $this->getTable()->mapColumns($states);
foreach($states as $key => $value)
{
if(isset($value)) {
$query->where('tbl.'.$key, 'IN', $value);
}
}
}
}
/**
* Builds a GROUP BY clause for the query
*/
protected function _buildQueryGroup(KDatabaseQuery $query)
{
}
/**
* Builds a HAVING clause for the query
*/
protected function _buildQueryHaving(KDatabaseQuery $query)
{
}
/**
* Builds a generic ORDER BY clasue based on the model's state
*/
protected function _buildQueryOrder(KDatabaseQuery $query)
{
$sort = $this->_state->sort;
$direction = strtoupper($this->_state->direction);
if($sort) {
$query->order($this->getTable()->mapColumns($sort), $direction);
}
if(array_key_exists('ordering', $this->getTable()->getColumns())) {
$query->order('tbl.ordering', 'ASC');
}
}
/**
* Builds LIMIT clause for the query
*/
protected function _buildQueryLimit(KDatabaseQuery $query)
{
$limit = $this->_state->limit;
if($limit)
{
$offset = $this->_state->offset;
$total = $this->getTotal();
//If the offset is higher than the total recalculate the offset
if($offset !== 0 && $total !== 0)
{
if($offset >= $total)
{
$offset = floor(($total-1) / $limit) * $limit;
$this->_state->offset = $offset;
}
}
$query->limit($limit, $offset);
}
}
}