Basic model is mainly written, completely untested

This commit is contained in:
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
}
}