From fd0a0f7f4d0a9424b0f671eeefbfbaa61a44a75b Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Wed, 22 May 2019 11:35:28 +0200 Subject: [PATCH] Basic model is mainly written, completely untested --- src/admin/common/abstract/model.php | 219 ++++++++++++++++++++- src/admin/common/abstract/modelfactory.php | 41 +++- 2 files changed, 249 insertions(+), 11 deletions(-) diff --git a/src/admin/common/abstract/model.php b/src/admin/common/abstract/model.php index 3c7bfca..6046df4 100644 --- a/src/admin/common/abstract/model.php +++ b/src/admin/common/abstract/model.php @@ -1,12 +1,15 @@ values)) - // FIXME fetch cache - return; + $this->loadDataFromDatabase(); return $this->values; } + public function isNew() + { + return $this->new; + } + public function setValues($values) { $this->values = $values; } + public function markAsNew($new) + { + $this->new = $new; + } + + public function fillDefaultValues() + {} + + /** + * @return AbstractCommonClubsModelFactory + */ + protected abstract function getFactory(); + + public function save() + { + $factory = $this->getFactory(); + $attribs = $factory->getAttributes(); + + $db = Factory::getDbo(); + $q = $db->getQuery(true); + + $db->transactionStart(); + + if($this->new) + $this->prepareInsert($attribs, $factory, $q); + else + $this->prepareUpdate($attribs, $factory, $q); + + $db->setQuery($q); + $db->execute(); + + if($this->new) + { + $this->finishInsert($db); + } + + $db->transactionCommit(); + } + + private function loadDataFromDatabase() + { + $factory = $this->getFactory(); + $attribs = $factory->getAttributes(); + + $db = Factory::getDbo(); + $q = $db->getQuery(true); + + foreach($attribs as $k => $v) + { + $q->select($q->qn($v['col'], $k)); + } + $q->from($factory->getTableName()); + $q->where("id = {$this->id}"); + + $db->setQuery($q); + $db->execute(); + + $this->values = $db->loadAssoc(); + } + + /** + * + * @param array $rawData + * @param array $attribs + * @param JDatabaseQuery $q + * @return string[]|number[]|NULL[] + */ + private function quoteData($rawData, $attribs, $q) + { + $quotedData = array(); + + foreach($attribs as $k => $v) + { + if(empty($v['type'])) + $v['type'] = 'string'; + + if($rawData[$k] === NULL) + $quotedData[$k] = 'NULL'; + + 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; + } + + protected function filterRawData($values) + { + return $values; + } + + protected function filterQuotedData($quoted) + { + return $quoted; + } + + /** + * + * @param array $attribs + * @param JDatabaseQuery $q + * @return array + */ + private function getQuotedData($attribs, $q) + { + $rawData = $this->getValues(); + $rawData = $this->filterRawData($rawData); + + $quotedData = $this->quoteData($rawData, $attribs, $q); + $quotedData = $this->filterQuotedData($quotedData); + + return $quotedData; + } + + /** + * + * @param array $attribs + * @param AbstractCommonClubsModelFactory $factory + * @param JDatabaseQuery $q + */ + private function prepareInsert($attribs, $factory, $q) + { + $q->insert($factory->getTableName()); + + $dbcols = array_map(function ($v){return $v['col'];}, $attribs); + + $q->columns($q->qn($dbcols)); + + $quotedData = $this->getQuotedData($attribs, $q); + + $q->values(join(', ', $quotedData)); + } + + /** + * + * @param JDatabaseDriver $db + */ + private function finishInsert($db) + { + $this->id = $db->insertid(); + $this->new = false; + } + + /** + * + * @param array $attribs + * @param AbstractCommonClubsModelFactory $factory + * @param JDatabaseQuery $q + */ + private function prepareUpdate($attribs, $factory, $q) + { + $q->update($factory->getTableName()); + + $dbcols = array_map(function ($v){return $v['col'];}, $attribs); + + $quotedData = $this->getQuotedData($attribs, $q); + + $q->set(array_map(function($col, $data){ + return "$col = $data"; + }, $dbcols, $quotedData)); + + $q->where("id = {$this->id}"); + } + + public function delete() + { + $db = Factory::getDbo(); + $q = $db->getQuery(true); + + $factory = $this->getFactory(); + + $q->delete($factory->getTableName()); + $q->where("id = {$this->id}"); + + $db->transactionStart(); + $db->setQuery($q); + $db->execute(); + $db->transactionCommit(); + } + + public function pack() + { + // TODO + } + + public function unpack($str) + { + // TODO + } + } diff --git a/src/admin/common/abstract/modelfactory.php b/src/admin/common/abstract/modelfactory.php index 8b8b8cb..7eafc1b 100644 --- a/src/admin/common/abstract/modelfactory.php +++ b/src/admin/common/abstract/modelfactory.php @@ -8,7 +8,7 @@ defined('_JEXEC') or die; class ElementNotFoundException extends Exception {} -abstract class AbstractClubsModelFactory +abstract class AbstractCommonClubsModelFactory { /* @@ -30,7 +30,7 @@ abstract class AbstractClubsModelFactory * - ref * - ref: (only with type='ref') The name of the class that is referenced */ - protected abstract function getAttributes(); + public abstract function getAttributes(); private $attributes = null; private function fetchAttributes() @@ -38,18 +38,18 @@ abstract class AbstractClubsModelFactory if($this->attributes === null) $this->attributes = $this->getAttributes(); - return $this->attributes; + return $this->attributes; } - protected abstract function getTableName(); - protected abstract function getClassName(); + public abstract function getTableName(); + public abstract function getClassName(); /** * * @param string $condition * @return array */ - protected function loadElements($condition = null) + public function loadElements($condition = null) { $db = Factory::getDbo(); $q = $db->getQuery(true); @@ -88,7 +88,7 @@ abstract class AbstractClubsModelFactory * * @param int $id */ - protected function loadById($id) { + public function loadById($id) { $arr = $this->loadElements("main.id = " . ((int)$id) ); if(sizeof($arr) == 0) throw new ElementNotFoundException(); @@ -96,16 +96,39 @@ abstract class AbstractClubsModelFactory return $arr[0]; } - protected function generateObject($row) + private function generatePlainObject($id) { $name = $this->getClassName(); $obj = new $name(); - $obj->setId($row['id']); + $obj->setId($id); + + return $obj; + } + + protected function generateObject($row) + { + $obj = $this->generatePlainObject($row['id']); + $obj->marksAsNew(false); unset($row['id']); $obj->setValues($row); return $obj; } + + public function createNew() + { + $obj = $this->generatePlainObject('new'); + $obj->markAsNew(true); + + $attribs = array_map(function($v){ + return Null; + }, $this->fetchAttributes()); + $obj->setValues($attribs); + + $obj->fillDefaultValues(); + + return $obj; + } }