1
0
mirror of https://github.com/dg/dibi.git synced 2025-08-05 21:58:10 +02:00

- renamed configuration keys result:object, result:withtables and format:* to resultObject resp. resultWithTables (due compatibility with PHP 5.3 INI parser)

- updated class Object
This commit is contained in:
David Grudl
2008-08-25 18:55:50 +00:00
parent c438b72972
commit 119d5a1995
8 changed files with 104 additions and 45 deletions

View File

@@ -51,9 +51,9 @@
* Adding method to class (i.e. to all instances) works similar to JavaScript
* prototype property. The syntax for adding a new method is:
* <code>
* function MyClass_prototype_newMethod(MyClass $obj, $arg, ...) { ... }
* MyClass::extensionMethod('newMethod', function(MyClass $obj, $arg, ...) { ... });
* $obj = new MyClass;
* $obj->newMethod($x); // equivalent to MyClass_prototype_newMethod($obj, $x);
* $obj->newMethod($x);
* </code>
*
* @author David Grudl
@@ -62,15 +62,19 @@
*/
abstract class Object
{
/** @var array (method => array(type => callback)) */
private static $extMethods;
/**
* Returns the name of the class of this object.
*
* @return string
*/
final public function getClass()
final public /*static*/ function getClass()
{
return get_class($this);
return /*get_called_class()*/ /**/get_class($this)/**/;
}
@@ -104,7 +108,7 @@ abstract class Object
}
// event functionality
if (self::hasEvent($class, $name)) {
if (property_exists($class, $name) && preg_match('#^on[A-Z]#', $name)) {
$list = $this->$name;
if (is_array($list) || $list instanceof Traversable) {
foreach ($list as $handler) {
@@ -114,15 +118,11 @@ abstract class Object
return;
}
// object prototypes support Class__method()
// (or use class Class__method { static function ... } with autoloading?)
$cl = $class;
do {
if (function_exists($nm = $cl . '_prototype_' . $name)) {
// extension methods
if ($cb = self::extensionMethod("$class::$name")) {
array_unshift($args, $this);
return call_user_func_array($nm, $args);
return call_user_func_array($cb, $args);
}
} while ($cl = get_parent_class($cl));
throw new /*::*/MemberAccessException("Call to undefined method $class::$name().");
}
@@ -145,6 +145,69 @@ abstract class Object
/**
* Adding method to class.
*
* @param string method name
* @param mixed callback or closure
* @return mixed
*/
public static function extensionMethod($name, $callback = NULL)
{
if (self::$extMethods === NULL || $name === NULL) { // for backwards compatibility
$list = get_defined_functions();
foreach ($list['user'] as $fce) {
$pair = explode('_prototype_', $fce);
if (count($pair) === 2) {
self::$extMethods[$pair[1]][$pair[0]] = $fce;
self::$extMethods[$pair[1]][''] = NULL;
}
}
if ($name === NULL) return;
}
$name = strtolower($name);
$a = strrpos($name, ':'); // search ::
if ($a === FALSE) {
$class = strtolower(get_called_class());
$l = & self::$extMethods[$name];
} else {
$class = substr($name, 0, $a - 1);
$l = & self::$extMethods[substr($name, $a + 1)];
}
if ($callback !== NULL) { // works as setter
$l[$class] = $callback;
$l[''] = NULL;
return;
}
// works as getter
if (empty($l)) {
return FALSE;
} elseif (isset($l[''][$class])) { // cached value
return $l[''][$class];
}
$cl = $class;
do {
$cl = strtolower($cl);
if (isset($l[$cl])) {
return $l[''][$class] = $l[$cl];
}
} while (($cl = get_parent_class($cl)) !== FALSE);
foreach (class_implements($class) as $cl) {
$cl = strtolower($cl);
if (isset($l[$cl])) {
return $l[''][$class] = $l[$cl];
}
}
return $l[''][$class] = FALSE;
}
/**
* Returns property value. Do not call directly.
*
@@ -260,18 +323,4 @@ abstract class Object
return isset($cache[$c][$m]);
}
/**
* Is property an event?
*
* @param string class name
* @param string method name
* @return bool
*/
private static function hasEvent($c, $m)
{
return preg_match('#^on[A-Z]#', $m) && property_exists($c, $m);
}
}

View File

@@ -196,7 +196,7 @@ class dibi
/**
* Creates a new DibiConnection object and connects it to specified database.
*
* @param array|string|Nette::Collections::Hashtable connection parameters
* @param array|string|ArrayObject connection parameters
* @param string connection name
* @return DibiConnection
* @throws DibiException

View File

@@ -27,8 +27,8 @@
* - 'persistent' - try to find a persistent link?
* - 'unbuffered' - sends query without fetching and buffering the result rows automatically?
* - 'lazy' - if TRUE, connection will be established only when required
* - 'format:date' - how to format date in SQL (@see date)
* - 'format:datetime' - how to format datetime in SQL (@see date)
* - 'formatDate' - how to format date in SQL (@see date)
* - 'formatDateTime' - how to format datetime in SQL (@see date)
*
* @author David Grudl
* @copyright Copyright (c) 2005, 2008 David Grudl
@@ -87,8 +87,8 @@ class DibiSqliteDriver extends /*Nette::*/Object implements IDibiDriver
public function connect(array &$config)
{
DibiConnection::alias($config, 'database', 'file');
$this->fmtDate = isset($config['format:date']) ? $config['format:date'] : 'U';
$this->fmtDateTime = isset($config['format:datetime']) ? $config['format:datetime'] : 'U';
$this->fmtDate = isset($config['formatDate']) ? $config['formatDate'] : 'U';
$this->fmtDateTime = isset($config['formatDateTime']) ? $config['formatDateTime'] : 'U';
$errorMsg = '';
if (empty($config['persistent'])) {

View File

@@ -58,7 +58,7 @@ class DibiConnection extends /*Nette::*/Object
/**
* Creates object and (optionally) connects to a database.
*
* @param array|string|Nette::Collections::Hashtable connection parameters
* @param array|string|ArrayObject connection parameters
* @param string connection name
* @throws DibiException
*/
@@ -72,11 +72,11 @@ class DibiConnection extends /*Nette::*/Object
if (is_string($config)) {
parse_str($config, $config);
} elseif ($config instanceof /*Nette::Collections::*/Hashtable) {
} elseif ($config instanceof ArrayObject) {
$config = (array) $config;
} elseif (!is_array($config)) {
throw new InvalidArgumentException('Configuration must be array, string or Nette::Collections::Hashtable.');
throw new InvalidArgumentException('Configuration must be array, string or ArrayObject.');
}
if (!isset($config['driver'])) {
@@ -93,10 +93,20 @@ class DibiConnection extends /*Nette::*/Object
}
}
if (isset($config['result:withtables'])) {
$config['resultWithTables'] = $config['result:withtables'];
unset($config['result:withtables']);
}
if (isset($config['result:objects'])) {
$config['resultObjects'] = $config['result:objects'];
unset($config['result:objects']);
}
if (isset($config['resultObjects'])) {
// normalize
$val = $config['result:objects'];
$config['result:objects'] = is_string($val) && !is_numeric($val) ? $val : (bool) $val;
$val = $config['resultObjects'];
$config['resultObjects'] = is_string($val) && !is_numeric($val) ? $val : (bool) $val;
}
$config['name'] = $name;

View File

@@ -89,12 +89,12 @@ class DibiResult extends /*Nette::*/Object implements IDataSource
{
$this->driver = $driver;
if (!empty($config['result:withtables'])) {
if (!empty($config['resultWithTables'])) {
$this->setWithTables(TRUE);
}
if (isset($config['result:objects'])) {
$this->setObjects($config['result:objects']);
if (isset($config['resultObjects'])) {
$this->setObjects($config['resultObjects']);
}
}

View File

@@ -254,7 +254,7 @@ abstract class DibiTable extends /*Nette::*/Object
$row = $this->blankRow;
$row[$this->primary] = NULL;
if ($class = $this->connection->getConfig('result:objects')) {
if ($class = $this->connection->getConfig('resultObjects')) {
if ($class === TRUE) {
$row = (object) $row;
} else {

View File

@@ -10,7 +10,7 @@ try {
dibi::connect(array(
'driver' => 'sqlite',
'database' => 'sample.sdb',
'result:objects' => TRUE, // fetch rows as objects
'resultObjects' => TRUE, // fetch rows as objects
));
echo 'OK';

View File

@@ -13,8 +13,8 @@ date_default_timezone_set('Europe/Prague');
dibi::connect(array(
'driver' => 'sqlite',
'database' => 'sample.sdb',
'format:date' => "'Y-m-d'",
'format:datetime' => "'Y-m-d H-i-s'",
'formatDate' => "'Y-m-d'",
'formatDateTime' => "'Y-m-d H-i-s'",
));