diff --git a/src/admin/common/abstract/model.php b/src/admin/common/abstract/model.php index c24aa46..2a7dce1 100644 --- a/src/admin/common/abstract/model.php +++ b/src/admin/common/abstract/model.php @@ -6,12 +6,9 @@ use Joomla\CMS\Factory; // No direct access. defined('_JEXEC') or die; -class AssociatedObjectUnsavedException extends Exception -{} - abstract class AbstractCommonClubsModel { - // TODO Adddata validator + // TODO Add data validator // TODO Make setting of values attribute fail in case of problems // FIXME Add Joins in select statements @@ -103,10 +100,9 @@ abstract class AbstractCommonClubsModel $db = Factory::getDbo(); $q = $db->getQuery(true); - foreach($attribs as $k => $v) + foreach($attribs as $a) { - $rawColName = isset($v['col']) ? $v['col'] : $k; - $q->select($q->qn($rawColName, $k)); + $a->select($q); } $q->from($factory->getTableName()); $q->where("id = {$this->id}"); @@ -123,22 +119,10 @@ abstract class AbstractCommonClubsModel private function packExternalReferencesAsKeys($vals) { - foreach($this->getFactory()->getAttributes() as $k => $v) + foreach($this->getFactory()->getAttributes() as $a) { - if($v['type'] !== 'ref') - continue; - - if(is_null($vals[$k])) - continue; - - $id = $vals[$k]->getId(); - - if($id === 'new') - { - throw new AssociatedObjectUnsavedException(); - } - - $vals[$k] = $id; + $alias = $a->getAlias(); + $vals[$alias] = $a->packValue($vals[$alias]); } return $vals; @@ -146,64 +130,20 @@ abstract class AbstractCommonClubsModel private function unpackExternalReferencesFromKeys($vals) { - foreach($this->getFactory()->getAttributes() as $k => $v) + foreach($this->getFactory()->getAttributes() as $a) { - if(empty($v['type']) || $v['type'] !== 'ref') - continue; - - 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]); + $alias = $a->getAlias(); + $vals[$alias] = $a->unpackValue($vals[$alias]); } 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 $attribs + * @param AbstractCommonClubsModelColumn[] $attribs * @param JDatabaseQuery $q * @return string[]|number[]|NULL[] */ @@ -211,38 +151,10 @@ abstract class AbstractCommonClubsModel { $quotedData = array(); - foreach($attribs as $k => $v) + foreach($attribs as $a) { - if(empty($v['type'])) - $v['type'] = 'string'; - - 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; - } + $alias = $a->getAlias(); + $quotedData[$alias] = $a->getQuotedValue($q, $rawData[$alias]); } return $quotedData; @@ -277,7 +189,7 @@ abstract class AbstractCommonClubsModel /** * - * @param array $attribs + * @param AbstractCommonClubsModelColumn[] $attribs * @param AbstractCommonClubsModelFactory $factory * @param JDatabaseQuery $q */ @@ -286,9 +198,9 @@ abstract class AbstractCommonClubsModel $q->insert($factory->getTableName()); $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)); @@ -310,7 +222,7 @@ abstract class AbstractCommonClubsModel /** * - * @param array $attribs + * @param AbstractCommonClubsModelColumn[] $attribs * @param AbstractCommonClubsModelFactory $factory * @param JDatabaseQuery $q */ @@ -319,8 +231,8 @@ abstract class AbstractCommonClubsModel $q->update($factory->getTableName()); $dbcols = array(); - foreach($attribs as $k => $v) - $dbcols[] = isset($v['col']) ? $v['col'] : $k; + foreach($attribs as $a) + $dbcols[] = $a->getColumn(); $quotedData = $this->getQuotedData($attribs, $q); diff --git a/src/admin/common/abstract/model/column.php b/src/admin/common/abstract/model/column.php new file mode 100644 index 0000000..a21ceee --- /dev/null +++ b/src/admin/common/abstract/model/column.php @@ -0,0 +1,74 @@ +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; + } + +} diff --git a/src/admin/common/abstract/model/factory.php b/src/admin/common/abstract/model/factory.php index a0f2aac..391ad64 100644 --- a/src/admin/common/abstract/model/factory.php +++ b/src/admin/common/abstract/model/factory.php @@ -36,6 +36,10 @@ abstract class AbstractCommonClubsModelFactory protected abstract function fetchAttributes(); private $attributes = null; + /** + * @param boolean $force + * @return AbstractCommonClubsModelColumn[] + */ public function getAttributes($force = False) { if($this->attributes === null || $force) @@ -164,10 +168,15 @@ abstract class AbstractCommonClubsModelFactory $obj = $this->generatePlainObject('new'); $obj->markAsNew(true); - $attribs = array_map(function($v){ - return Null; - }, $this->getAttributes()); - $obj->setValues($attribs); + $values = array(); + foreach($this->getAttributes() as $a) + { + $values[$a->getAlias()] = null; + } +// $attribs = array_map(function($v){ +// return Null; +// }, $this->getAttributes()); + $obj->setValues($values); $obj->fillDefaultValues(); diff --git a/src/admin/common/models/column/float.php b/src/admin/common/models/column/float.php new file mode 100644 index 0000000..be81642 --- /dev/null +++ b/src/admin/common/models/column/float.php @@ -0,0 +1,22 @@ +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]; + } + +} diff --git a/src/admin/common/models/column/string.php b/src/admin/common/models/column/string.php new file mode 100644 index 0000000..fe2140f --- /dev/null +++ b/src/admin/common/models/column/string.php @@ -0,0 +1,22 @@ +q($value); + } + + +} diff --git a/src/admin/common/models/factory/club.php b/src/admin/common/models/factory/club.php index d3ee0c8..6331ad6 100644 --- a/src/admin/common/models/factory/club.php +++ b/src/admin/common/models/factory/club.php @@ -8,15 +8,15 @@ class CommonClubsModelFactoryClub extends AbstractCommonClubsModelFactory public function fetchAttributes() { return array( - 'name'=>array(), - 'address'=>array(), - 'city'=>array(), - 'homepage'=>array(), - 'mail'=>array(), - 'iban'=>array(), - 'bic'=>array(), - 'charitable'=>array('type'=>'int'), - 'president'=>array('type'=>'ref', 'ref'=>'CommonClubsModelUser') + new CommonClubsModelColumnString('name'), + new CommonClubsModelColumnString('address'), + new CommonClubsModelColumnString('city'), + new CommonClubsModelColumnString('homepage'), + new CommonClubsModelColumnString('mail'), + new CommonClubsModelColumnString('iban'), + new CommonClubsModelColumnString('bic'), + new CommonClubsModelColumnInt('charitable'), + new CommonClubsModelColumnRef('president', 'CommonClubsModelUser') ); } diff --git a/src/admin/common/models/factory/place.php b/src/admin/common/models/factory/place.php index fcae159..01b40c6 100644 --- a/src/admin/common/models/factory/place.php +++ b/src/admin/common/models/factory/place.php @@ -8,9 +8,9 @@ class CommonClubsModelFactoryPlace extends AbstractCommonClubsModelFactory public function fetchAttributes() { return array( - 'name'=>array(), - 'club'=>array('col'=>'clubid', 'type'=>'ref', 'ref'=>'CommonClubsModelClub'), - 'area'=>array('type'=>'int', 'optional'=>true) + new CommonClubsModelColumnString('name'), + new CommonClubsModelColumnRef('club', 'CommonClubsModelClub', true, 'clubid'), + new CommonClubsModelColumnInt('area', false) ); } diff --git a/src/admin/common/models/factory/user.php b/src/admin/common/models/factory/user.php index 5c55bea..437bd73 100644 --- a/src/admin/common/models/factory/user.php +++ b/src/admin/common/models/factory/user.php @@ -8,8 +8,8 @@ class CommonClubsModelFactoryUser extends AbstractCommonClubsModelFactory public function fetchAttributes() { return array( - 'user'=>array(), - 'name'=>array() + new CommonClubsModelColumnString('user'), + new CommonClubsModelColumnString('name') ); }