Basic model is mainly written, completely untested

This commit is contained in:
Christian Wolf 2019-05-22 11:35:28 +02:00
parent 51c910e51f
commit fd0a0f7f4d
2 changed files with 249 additions and 11 deletions

View File

@ -1,12 +1,15 @@
<?php
use Joomla\CMS\Factory;
// No direct access.
defined('_JEXEC') or die;
abstract class AbstractCommonClubsModel
{
protected $id; // TODO private possible?
protected $new;
public function getId()
{
@ -23,15 +26,227 @@ abstract class AbstractCommonClubsModel
protected function getValues()
{
if(is_null($this->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
}
}

View File

@ -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;
}
}