Subversion Repositories PHPX

Compare Revisions

Last modification

Ignore whitespace Rev 50 → Rev 51

/trunk/Controller.php
1,24 → 1,10
<?php
 
namespace PointedEars\PHPX;
 
require_once __DIR__ . '/Application.php';
require_once __DIR__ . '/View.php';
 
/* lcfirst() is unavailable before PHP 5.3 */
if (false === function_exists('lcfirst'))
{
/**
* Make a string's first character lowercase
*
* @param string $str The input string.
* @return string The resulting string.
* @link http://www.php.net/manual/en/function.lcfirst.php
*/
function lcfirst($str)
{
return strtolower(substr($str, 0, 1)) . substr($str, 1);
}
}
 
/**
* A general controller that can handle views according to
* the MVC pattern
/trunk/AbstractModel.php
1,5 → 1,7
<?php
 
namespace PointedEars\PHPX;
 
/**
* Interface to be implemented if the model should be localizable
*/
/trunk/Db/Database.php
1,5 → 1,7
<?php
 
namespace PointedEars\PHPX\Db;
 
require_once __DIR__ . '/../global.inc';
require_once __DIR__ . '/../AbstractModel.php';
 
21,7 → 23,7
* Last success value of the database operation
* @author Thomas Lahn
*/
class Database extends AbstractModel
class Database extends \PointedEars\PHPX\AbstractModel
{
/* Access properties */
 
189,7 → 191,7
if ($this->_connection === null)
{
$this->_connection =
new PDO($this->_dsn, $this->_username, $this->_password, $this->_options);
new \PDO($this->_dsn, $this->_username, $this->_password, $this->_options);
}
 
return $this->_connection;
479,7 → 481,7
* @see PDOStatement::fetchAll()
*/
public function select($tables, $columns = null, $where = null,
$order = null, $limit = null, $fetch_style = PDO::FETCH_ASSOC)
$order = null, $limit = null, $fetch_style = \PDO::FETCH_ASSOC)
{
if (is_null($columns))
{
839,7 → 841,7
 
if (is_null($fetch_style))
{
$fetch_style = PDO::FETCH_ASSOC;
$fetch_style = \PDO::FETCH_ASSOC;
}
 
if (!is_null($ctor_args))
/trunk/Db/Mapper.php
1,5 → 1,7
<?php
 
namespace PointedEars\PHPX\Db;
 
require_once __DIR__ . '/../AbstractModel.php';
require_once __DIR__ . '/Table.php';
 
8,7 → 10,7
*
* @author Thomas Lahn
*/
abstract class Mapper extends AbstractModel
abstract class Mapper extends \PointedEars\PHPX\AbstractModel
{
/**
* Class name of the associated table model
/trunk/Db/Table.php
1,8 → 1,12
<?php
 
namespace PointedEars\PHPX\Db;
 
require_once __DIR__ . '/../Application.php';
require_once __DIR__ . '/../AbstractModel.php';
 
use \PointedEars\PHPX\Application;
 
/**
* Generic database table model class
*
12,7 → 16,7
* ID of the last inserted row, or the last value from
a sequence object, depending on the underlying driver.
*/
class Table extends AbstractModel
class Table extends \PointedEars\PHPX\AbstractModel
{
/**
* Name of the table
/trunk/Db/MySQLDB.php
1,5 → 1,7
<?php
 
namespace PointedEars\PHPX\Db;
 
require_once __DIR__ . '/Database.php';
 
class MySQLDB extends Database
49,7 → 51,7
public function __construct()
{
$this->readConfig();
 
$this->_dsn = "mysql:host={$this->_host}"
. (!is_null($this->_dbname) ? ";dbname={$this->_dbname}" : '')
. (!is_null($this->_charset) ? ";charset={$this->_charset}" : '');
56,7 → 58,7
 
if (!is_null($this->_charset))
{
$this->_options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES " . $this->_charset;
$this->_options[\PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES " . $this->_charset;
}
 
parent::__construct();
/trunk/Model.php
3,44 → 3,165
require_once __DIR__ . '/AbstractModel.php';
 
/**
* Abstract model class
* Abstract model class for Object-Relational Mapping
*
* Provides basic setters and getters for protected/private properties
* and a constructor to initialize properties using setters and getters.
* Provides simple mapping of a model object to records of
* a table of a relational database.
*
* @author Thomas Lahn
*/
abstract class Model extends AbstractModel
{
/* ORM */
const persistentPrimaryKey = 'id';
/**
* @var Adapter
* The <code>Table</code> for instances of this model
*
* @type Table|string
*/
protected static $persistentAdapter;
protected $_persistentTable;
 
/**
* The name(s) of the property or properties whose value(s)
* identify this object in the <code>Table</code>. They are
* used for comparing against the primary key column(s) of
* the <code>Table</code>.
*
* @type string|array[string]
*/
protected $_persistentId = 'id';
 
/**
* The names of the properties that should be used in database
* queries, and their mapping to the columns of
* the <code>Table</code>, if specified (keys are property names,
* values are column names, or both if the key is numeric).
*
* @type array
*/
protected $_persistentProperties = array('id');
 
/**
* Creates a new model object
*
* @param array $data Initialization data (optional)
* @param array $mapping Mapping for initialization data (optional)
* @see AbstractModel::__construct()
*/
public function __construct(array $data = null, array $mapping = null)
public function __construct (array $data = null, array $mapping = null)
{
$this->setAdapter();
parent::__construct($data, $mapping);
}
 
public function getPersistentTable ()
{
if (is_string($this->_persistentTable))
{
/* Call setter to convert to Table */
$this->persistentTable = $this->_persistentTable;
}
 
return $this->_persistentTable;
}
 
public function setPersistentTable ($value)
{
if ($value instanceof Table)
{
$this->_persistentTable = $value;
}
else
{
$table = new $value();
if (!($table instanceof Table))
{
throw new \InvalidArgumentException(
'Expected Table instance or string for table name, saw '
. (\get_class($value) || \gettype($value))
);
}
 
$this->_persistentTable = $table;
}
}
 
/**
* Finds the record for the model object in a database, and fills the object
* with missing data
* @see Adapter::find(Model)
* Returns an array for database queries containing the
* property values of this object, using the specified
* property-to-column mapping.
*
* @param array $propertyNames = null
* Names of the properties that should be included.
* The default is to include all persistent properties.
* @return array
*/
public function find()
public function getPropertyArray (array $propertyNames = null)
{
$class = get_class($this);
return $class::$persistentAdapter->find($this);
$a = array();
 
if ($propertyNames === null)
{
$propertyNames = $this->_persistentProperties;
}
 
foreach ($propertyNames as $propertyName => $columnName)
{
if (is_numeric($propertyName))
{
$propertyName = $columnName;
}
 
$a[$columnName] = $this->$propertyName;
}
 
return $a;
}
 
/**
* Finds the record for the model object in a database, fills
* the object with missing data, and returns the result.
*
* @see Table::find(Model)
* @return Model|null
* This object filled with missing data, or <code>null</code>
* if there is no data for this object
*/
public function find ()
{
$result = $this->persistentTable->find(
$this->{$this->__persistentId});
if ($result)
{
return $this->map($result);
}
 
return null;
}
 
/**
* Saves a model object in the <code>Table</code>
*
* @param array $propertyNames = null
* Names of the properties whose values should be saved
* in the database. The default is to save the values
* of all persistent properties.
* @return boolean
* @see Model::getPropertyArray()
* @see Table::updateOrInsert()
*/
public function save (array $propertyNames = null)
{
return $this->persistentTable->updateOrInsert(
$this->getPropertyArray($propertyNames), array(
$this->persistentTable->id => $this->{$this->_persistentId}
)
);
}
 
/**
* Deletes a model object from the <code>Table</code>
*
* @return bool
* @see Table::delete()
*/
public function delete ()
{
return $this->persistentTable->delete($this->{$this->_persistentId});
}
}
/trunk/Application.php
1,5 → 1,7
<?php
 
namespace PointedEars\PHPX;
 
require_once __DIR__ . '/AbstractModel.php';
require_once __DIR__ . '/Registry.php';
 
179,7 → 181,7
* @return string Registry key
* @see Application::setDefaultDatabase()
*/
public function registerDatabase ($key, Database $database)
public function registerDatabase ($key, Db\Database $database)
{
Registry::set($key, $database);
return $key;
/trunk/Registry.php
1,5 → 1,7
<?php
 
namespace PointedEars\PHPX;
 
/**
* Basic registry class
*
/trunk/View.php
1,5 → 1,7
<?php
 
namespace PointedEars\PHPX;
 
require_once __DIR__ . '/Application.php';
require_once __DIR__ . '/AbstractModel.php';
 
16,7 → 18,7
* @var string
*/
protected $_template = '';
 
/**
* Content that can be inserted in the template
*
23,7 → 25,7
* @var string
*/
protected $_content = '';
 
/**
* Template variables. The variable name serves as item key, the item's value
* is the variable value.
31,7 → 33,7
* @var array
*/
protected $_template_vars = array();
 
/**
* Creates a new view
*
42,7 → 44,7
{
$this->_template = $template;
}
 
/**
* Magic setter method used for defining template variables
*
66,7 → 68,7
{
return $this->_template_vars[$name];
}
 
/**
* Returns <var>$v</var> with occurences of '&' (ampersand), '"' (double quote),
* "'" (single quote), '<' (less than), and '>' (greater than) replaced by their
91,7 → 93,7
$value->$varName = self::escape($value->$varName);
}
}
 
return $value;
}
else
105,11 → 107,11
}
return htmlspecialchars($value, ENT_QUOTES, $encoding);
}
 
return $value;
}
}
 
/**
* Assigns a value to a template variable
*
134,7 → 136,7
$this->$name = $value;
return $value;
}
 
/**
* Renders the view by including a template
*
145,7 → 147,7
*/
public function render($template = null, $content = null)
{
if (!is_null($content))
if (!is_null($content))
{
ob_start();
require_once $content;
152,7 → 154,7
$this->_content = ob_get_contents();
ob_end_clean();
}
 
if (!is_null($template))
{
require $template;
166,7 → 168,7
throw new Exception('No template defined');
}
}
 
/**
* Returns the content for insertion into the template
*/
174,7 → 176,7
{
return $this->_content;
}
 
/**
* @param string[optional] $controller
* @param string[optional] $action