Made definition of columns based on objects
This commit is contained in:
parent
8dbbb4d245
commit
d93a02e779
@ -6,12 +6,9 @@ use Joomla\CMS\Factory;
|
|||||||
// No direct access.
|
// No direct access.
|
||||||
defined('_JEXEC') or die;
|
defined('_JEXEC') or die;
|
||||||
|
|
||||||
class AssociatedObjectUnsavedException extends Exception
|
|
||||||
{}
|
|
||||||
|
|
||||||
abstract class AbstractCommonClubsModel
|
abstract class AbstractCommonClubsModel
|
||||||
{
|
{
|
||||||
// TODO Adddata validator
|
// TODO Add data validator
|
||||||
// TODO Make setting of values attribute fail in case of problems
|
// TODO Make setting of values attribute fail in case of problems
|
||||||
// FIXME Add Joins in select statements
|
// FIXME Add Joins in select statements
|
||||||
|
|
||||||
@ -103,10 +100,9 @@ abstract class AbstractCommonClubsModel
|
|||||||
$db = Factory::getDbo();
|
$db = Factory::getDbo();
|
||||||
$q = $db->getQuery(true);
|
$q = $db->getQuery(true);
|
||||||
|
|
||||||
foreach($attribs as $k => $v)
|
foreach($attribs as $a)
|
||||||
{
|
{
|
||||||
$rawColName = isset($v['col']) ? $v['col'] : $k;
|
$a->select($q);
|
||||||
$q->select($q->qn($rawColName, $k));
|
|
||||||
}
|
}
|
||||||
$q->from($factory->getTableName());
|
$q->from($factory->getTableName());
|
||||||
$q->where("id = {$this->id}");
|
$q->where("id = {$this->id}");
|
||||||
@ -123,22 +119,10 @@ abstract class AbstractCommonClubsModel
|
|||||||
|
|
||||||
private function packExternalReferencesAsKeys($vals)
|
private function packExternalReferencesAsKeys($vals)
|
||||||
{
|
{
|
||||||
foreach($this->getFactory()->getAttributes() as $k => $v)
|
foreach($this->getFactory()->getAttributes() as $a)
|
||||||
{
|
{
|
||||||
if($v['type'] !== 'ref')
|
$alias = $a->getAlias();
|
||||||
continue;
|
$vals[$alias] = $a->packValue($vals[$alias]);
|
||||||
|
|
||||||
if(is_null($vals[$k]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$id = $vals[$k]->getId();
|
|
||||||
|
|
||||||
if($id === 'new')
|
|
||||||
{
|
|
||||||
throw new AssociatedObjectUnsavedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
$vals[$k] = $id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $vals;
|
return $vals;
|
||||||
@ -146,64 +130,20 @@ abstract class AbstractCommonClubsModel
|
|||||||
|
|
||||||
private function unpackExternalReferencesFromKeys($vals)
|
private function unpackExternalReferencesFromKeys($vals)
|
||||||
{
|
{
|
||||||
foreach($this->getFactory()->getAttributes() as $k => $v)
|
foreach($this->getFactory()->getAttributes() as $a)
|
||||||
{
|
{
|
||||||
if(empty($v['type']) || $v['type'] !== 'ref')
|
$alias = $a->getAlias();
|
||||||
continue;
|
$vals[$alias] = $a->unpackValue($vals[$alias]);
|
||||||
|
|
||||||
if(empty($v['ref']))
|
|
||||||
throw new Exception('External reference of unknown class found.');
|
|
||||||
|
|
||||||
if(empty($vals[$k]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$vals[$k] = $this->loadExternalReferenceAsObject($v['ref'], $vals[$k]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $vals;
|
return $vals;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadExternalReferenceAsObject($className, $value)
|
|
||||||
{
|
|
||||||
if(is_string($value) && preg_match('/^[0-9]+$/', $value))
|
|
||||||
$value = (int) $value;
|
|
||||||
|
|
||||||
if(! is_int($value))
|
|
||||||
throw new Exception('Reference with non-integer value');
|
|
||||||
|
|
||||||
$factoryName = $this->getFactoryNameOfClass($className);
|
|
||||||
$factory = new $factoryName();
|
|
||||||
return $factory->loadById($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private const CLASSNAME_MAP = array(
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @todo This must be done better and more cleanly
|
|
||||||
* @param string $className
|
|
||||||
* @return AbstractCommonClubsModelFactory
|
|
||||||
*/
|
|
||||||
private function getFactoryNameOfClass($className)
|
|
||||||
{
|
|
||||||
if(empty(self::CLASSNAME_MAP[$className]))
|
|
||||||
{
|
|
||||||
$parts = array();
|
|
||||||
if(preg_match('/^CommonClubsModel(.*)/', $className, $parts))
|
|
||||||
{
|
|
||||||
return "CommonClubsModelFactory{$parts[1]}";
|
|
||||||
}
|
|
||||||
throw new Exception("Unknown mapping of class $className");
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::CLASSNAME_MAP[$className];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param array $rawData
|
* @param array $rawData
|
||||||
* @param array $attribs
|
* @param AbstractCommonClubsModelColumn[] $attribs
|
||||||
* @param JDatabaseQuery $q
|
* @param JDatabaseQuery $q
|
||||||
* @return string[]|number[]|NULL[]
|
* @return string[]|number[]|NULL[]
|
||||||
*/
|
*/
|
||||||
@ -211,38 +151,10 @@ abstract class AbstractCommonClubsModel
|
|||||||
{
|
{
|
||||||
$quotedData = array();
|
$quotedData = array();
|
||||||
|
|
||||||
foreach($attribs as $k => $v)
|
foreach($attribs as $a)
|
||||||
{
|
{
|
||||||
if(empty($v['type']))
|
$alias = $a->getAlias();
|
||||||
$v['type'] = 'string';
|
$quotedData[$alias] = $a->getQuotedValue($q, $rawData[$alias]);
|
||||||
|
|
||||||
if($rawData[$k] === NULL)
|
|
||||||
{
|
|
||||||
$quotedData[$k] = 'NULL';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch($v['type'])
|
|
||||||
{
|
|
||||||
case 'string':
|
|
||||||
$quotedData[$k] = $q->q($rawData[$k]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'int':
|
|
||||||
$quotedData[$k] = (int) $rawData[$k];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'float':
|
|
||||||
$quotedData[$k] = (float) $rawData[$k];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'ref':
|
|
||||||
if($v['ref'] === null)
|
|
||||||
$quotedData[$k] = 'NULL';
|
|
||||||
else
|
|
||||||
$quotedData[$k] = $rawData[$k]->getId();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $quotedData;
|
return $quotedData;
|
||||||
@ -277,7 +189,7 @@ abstract class AbstractCommonClubsModel
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param array $attribs
|
* @param AbstractCommonClubsModelColumn[] $attribs
|
||||||
* @param AbstractCommonClubsModelFactory $factory
|
* @param AbstractCommonClubsModelFactory $factory
|
||||||
* @param JDatabaseQuery $q
|
* @param JDatabaseQuery $q
|
||||||
*/
|
*/
|
||||||
@ -286,9 +198,9 @@ abstract class AbstractCommonClubsModel
|
|||||||
$q->insert($factory->getTableName());
|
$q->insert($factory->getTableName());
|
||||||
|
|
||||||
$dbcols = array();
|
$dbcols = array();
|
||||||
foreach($attribs as $k => $v)
|
foreach($attribs as $a)
|
||||||
{
|
{
|
||||||
$dbcols[] = isset($v['col']) ? $v['col'] : $k;
|
$dbcols[] = $a->getColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
$q->columns($q->qn($dbcols));
|
$q->columns($q->qn($dbcols));
|
||||||
@ -310,7 +222,7 @@ abstract class AbstractCommonClubsModel
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param array $attribs
|
* @param AbstractCommonClubsModelColumn[] $attribs
|
||||||
* @param AbstractCommonClubsModelFactory $factory
|
* @param AbstractCommonClubsModelFactory $factory
|
||||||
* @param JDatabaseQuery $q
|
* @param JDatabaseQuery $q
|
||||||
*/
|
*/
|
||||||
@ -319,8 +231,8 @@ abstract class AbstractCommonClubsModel
|
|||||||
$q->update($factory->getTableName());
|
$q->update($factory->getTableName());
|
||||||
|
|
||||||
$dbcols = array();
|
$dbcols = array();
|
||||||
foreach($attribs as $k => $v)
|
foreach($attribs as $a)
|
||||||
$dbcols[] = isset($v['col']) ? $v['col'] : $k;
|
$dbcols[] = $a->getColumn();
|
||||||
|
|
||||||
$quotedData = $this->getQuotedData($attribs, $q);
|
$quotedData = $this->getQuotedData($attribs, $q);
|
||||||
|
|
||||||
|
74
src/admin/common/abstract/model/column.php
Normal file
74
src/admin/common/abstract/model/column.php
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// No direct access.
|
||||||
|
defined('_JEXEC') or die;
|
||||||
|
|
||||||
|
abstract class AbstractCommonClubsModelColumn
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $alias;
|
||||||
|
protected $column;
|
||||||
|
protected $required;
|
||||||
|
|
||||||
|
public function getAlias()
|
||||||
|
{
|
||||||
|
return $this->alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getColumn()
|
||||||
|
{
|
||||||
|
return $this->column;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isRequired()
|
||||||
|
{
|
||||||
|
return $this->required;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract function isSimpleType();
|
||||||
|
|
||||||
|
public function __construct($alias, $required = true, $column = null)
|
||||||
|
{
|
||||||
|
$this->alias = $alias;
|
||||||
|
$this->required = $required;
|
||||||
|
if(isset($column))
|
||||||
|
$this->column = $column;
|
||||||
|
else
|
||||||
|
$this->column = $alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param JDatabaseQuery $q
|
||||||
|
*/
|
||||||
|
public function select($q)
|
||||||
|
{
|
||||||
|
$q->select($q->qn($this->column, $this->alias));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param JDatabaseQuery $q
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public abstract function getQuotedValue($q,$value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param JDatabaseQuery $q
|
||||||
|
*/
|
||||||
|
public function getQuotedColumnName($q)
|
||||||
|
{
|
||||||
|
return $q->qn($this->column);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function packValue($value)
|
||||||
|
{
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unpackValue($value)
|
||||||
|
{
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -36,6 +36,10 @@ abstract class AbstractCommonClubsModelFactory
|
|||||||
protected abstract function fetchAttributes();
|
protected abstract function fetchAttributes();
|
||||||
|
|
||||||
private $attributes = null;
|
private $attributes = null;
|
||||||
|
/**
|
||||||
|
* @param boolean $force
|
||||||
|
* @return AbstractCommonClubsModelColumn[]
|
||||||
|
*/
|
||||||
public function getAttributes($force = False)
|
public function getAttributes($force = False)
|
||||||
{
|
{
|
||||||
if($this->attributes === null || $force)
|
if($this->attributes === null || $force)
|
||||||
@ -164,10 +168,15 @@ abstract class AbstractCommonClubsModelFactory
|
|||||||
$obj = $this->generatePlainObject('new');
|
$obj = $this->generatePlainObject('new');
|
||||||
$obj->markAsNew(true);
|
$obj->markAsNew(true);
|
||||||
|
|
||||||
$attribs = array_map(function($v){
|
$values = array();
|
||||||
return Null;
|
foreach($this->getAttributes() as $a)
|
||||||
}, $this->getAttributes());
|
{
|
||||||
$obj->setValues($attribs);
|
$values[$a->getAlias()] = null;
|
||||||
|
}
|
||||||
|
// $attribs = array_map(function($v){
|
||||||
|
// return Null;
|
||||||
|
// }, $this->getAttributes());
|
||||||
|
$obj->setValues($values);
|
||||||
|
|
||||||
$obj->fillDefaultValues();
|
$obj->fillDefaultValues();
|
||||||
|
|
||||||
|
22
src/admin/common/models/column/float.php
Normal file
22
src/admin/common/models/column/float.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// No direct access.
|
||||||
|
defined('_JEXEC') or die;
|
||||||
|
|
||||||
|
class CommonClubsModelColumnFloat extends AbstractCommonClubsModelColumn
|
||||||
|
{
|
||||||
|
public function isSimpleType()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuotedValue($q, $value)
|
||||||
|
{
|
||||||
|
if(is_null($value))
|
||||||
|
return 'NULL';
|
||||||
|
else
|
||||||
|
return (float) $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
22
src/admin/common/models/column/int.php
Normal file
22
src/admin/common/models/column/int.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// No direct access.
|
||||||
|
defined('_JEXEC') or die;
|
||||||
|
|
||||||
|
class CommonClubsModelColumnInt extends AbstractCommonClubsModelColumn
|
||||||
|
{
|
||||||
|
public function isSimpleType()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuotedValue($q, $value)
|
||||||
|
{
|
||||||
|
if(is_null($value))
|
||||||
|
return 'NULL';
|
||||||
|
else
|
||||||
|
return (int) $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
105
src/admin/common/models/column/ref.php
Normal file
105
src/admin/common/models/column/ref.php
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// No direct access.
|
||||||
|
defined('_JEXEC') or die;
|
||||||
|
|
||||||
|
class WrongRefTypeException extends Exception
|
||||||
|
{}
|
||||||
|
|
||||||
|
class AssociatedObjectUnsavedException extends Exception
|
||||||
|
{}
|
||||||
|
|
||||||
|
class CommonClubsModelColumnRef extends AbstractCommonClubsModelColumn
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $className;
|
||||||
|
|
||||||
|
public function __construct($alias, $className, $required=true, $column=null)
|
||||||
|
{
|
||||||
|
parent::__construct($alias, $required, $column);
|
||||||
|
|
||||||
|
if(empty($className))
|
||||||
|
throw new Exception('Classname must be non-empty.');
|
||||||
|
|
||||||
|
$this->className = $className;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSimpleType()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuotedValue($q, $value)
|
||||||
|
{
|
||||||
|
if(is_null($value))
|
||||||
|
return 'NULL';
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(! ( $value instanceof $this->className ) )
|
||||||
|
throw new WrongRefTypeException();
|
||||||
|
|
||||||
|
$id = $value->getId();
|
||||||
|
if($id === 'new')
|
||||||
|
throw new AssociatedObjectUnsavedException();
|
||||||
|
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function packValue($value)
|
||||||
|
{
|
||||||
|
if(is_null($value))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if(! ($value instanceof $this->className) )
|
||||||
|
throw new WrongRefTypeException();
|
||||||
|
|
||||||
|
$id = $value->getId();
|
||||||
|
|
||||||
|
if($id === 'new')
|
||||||
|
throw new AssociatedObjectUnsavedException();
|
||||||
|
|
||||||
|
return (int) $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unpackValue($value)
|
||||||
|
{
|
||||||
|
if(empty($value))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if(is_string($value) && preg_match('/^[0-9]+$/', $value))
|
||||||
|
$value = (int) $value;
|
||||||
|
|
||||||
|
if(! is_int($value))
|
||||||
|
throw new Exception('Reference with non-integer value');
|
||||||
|
|
||||||
|
$factoryName = $this->getFactoryNameOfClass($this->className); // XXX Use attribute?
|
||||||
|
$factory = new $factoryName();
|
||||||
|
return $factory->loadById($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private const CLASSNAME_MAP = array(
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo This must be done better and more cleanly
|
||||||
|
* @param string $className
|
||||||
|
* @return AbstractCommonClubsModelFactory
|
||||||
|
*/
|
||||||
|
private function getFactoryNameOfClass($className)
|
||||||
|
{
|
||||||
|
if(empty(self::CLASSNAME_MAP[$className]))
|
||||||
|
{
|
||||||
|
$parts = array();
|
||||||
|
if(preg_match('/^CommonClubsModel(.*)/', $className, $parts))
|
||||||
|
{
|
||||||
|
return "CommonClubsModelFactory{$parts[1]}";
|
||||||
|
}
|
||||||
|
throw new Exception("Unknown mapping of class $className");
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::CLASSNAME_MAP[$className];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
src/admin/common/models/column/string.php
Normal file
22
src/admin/common/models/column/string.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// No direct access.
|
||||||
|
defined('_JEXEC') or die;
|
||||||
|
|
||||||
|
class CommonClubsModelColumnString extends AbstractCommonClubsModelColumn
|
||||||
|
{
|
||||||
|
public function isSimpleType()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuotedValue($q, $value)
|
||||||
|
{
|
||||||
|
if(is_null($value))
|
||||||
|
return 'NULL';
|
||||||
|
else
|
||||||
|
return $q->q($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -8,15 +8,15 @@ class CommonClubsModelFactoryClub extends AbstractCommonClubsModelFactory
|
|||||||
public function fetchAttributes()
|
public function fetchAttributes()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'name'=>array(),
|
new CommonClubsModelColumnString('name'),
|
||||||
'address'=>array(),
|
new CommonClubsModelColumnString('address'),
|
||||||
'city'=>array(),
|
new CommonClubsModelColumnString('city'),
|
||||||
'homepage'=>array(),
|
new CommonClubsModelColumnString('homepage'),
|
||||||
'mail'=>array(),
|
new CommonClubsModelColumnString('mail'),
|
||||||
'iban'=>array(),
|
new CommonClubsModelColumnString('iban'),
|
||||||
'bic'=>array(),
|
new CommonClubsModelColumnString('bic'),
|
||||||
'charitable'=>array('type'=>'int'),
|
new CommonClubsModelColumnInt('charitable'),
|
||||||
'president'=>array('type'=>'ref', 'ref'=>'CommonClubsModelUser')
|
new CommonClubsModelColumnRef('president', 'CommonClubsModelUser')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,9 @@ class CommonClubsModelFactoryPlace extends AbstractCommonClubsModelFactory
|
|||||||
public function fetchAttributes()
|
public function fetchAttributes()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'name'=>array(),
|
new CommonClubsModelColumnString('name'),
|
||||||
'club'=>array('col'=>'clubid', 'type'=>'ref', 'ref'=>'CommonClubsModelClub'),
|
new CommonClubsModelColumnRef('club', 'CommonClubsModelClub', true, 'clubid'),
|
||||||
'area'=>array('type'=>'int', 'optional'=>true)
|
new CommonClubsModelColumnInt('area', false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ class CommonClubsModelFactoryUser extends AbstractCommonClubsModelFactory
|
|||||||
public function fetchAttributes()
|
public function fetchAttributes()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'user'=>array(),
|
new CommonClubsModelColumnString('user'),
|
||||||
'name'=>array()
|
new CommonClubsModelColumnString('name')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user