386 lines
9.0 KiB
PHP
386 lines
9.0 KiB
PHP
<?php
|
|
|
|
|
|
use Joomla\CMS\Factory;
|
|
|
|
// No direct access.
|
|
defined('_JEXEC') or die;
|
|
|
|
abstract class AbstractCommonClubsModel
|
|
{
|
|
// TODO Add data validator
|
|
// TODO Make setting of values attribute fail in case of problems
|
|
// FIXME Add Joins in select statements
|
|
|
|
private $id;
|
|
private $new;
|
|
|
|
public function getId()
|
|
{
|
|
return $this->id;
|
|
}
|
|
|
|
public function setId($id)
|
|
{
|
|
$this->id = $id;
|
|
}
|
|
|
|
private $values = null;
|
|
|
|
protected function getValues($force = false)
|
|
{
|
|
if(is_null($this->values) || $force)
|
|
$this->loadDataFromDatabase();
|
|
|
|
return $this->values;
|
|
}
|
|
|
|
public function isNew()
|
|
{
|
|
return $this->new;
|
|
}
|
|
|
|
public function setValues($values, $unpack = false)
|
|
{
|
|
if($unpack)
|
|
$this->values = $this->unpackExternalReferencesFromKeys($values);
|
|
else
|
|
$this->values = $values;
|
|
}
|
|
|
|
public function applyAndMergeValues($values, $unpack = true)
|
|
{
|
|
$vals = $this->getValues();
|
|
|
|
if($unpack)
|
|
$vals = $this->packExternalReferencesAsKeys($vals);
|
|
|
|
foreach($this->getFactory()->getAttributes() as $column)
|
|
{
|
|
if(array_key_exists($column->getAlias(), $values))
|
|
{
|
|
$vals[$column->getAlias()] = $values[$column->getAlias()];
|
|
}
|
|
}
|
|
|
|
if($unpack)
|
|
$vals = $this->unpackExternalReferencesFromKeys($vals);
|
|
|
|
$this->setValues($vals, false);
|
|
}
|
|
|
|
protected function setValue($key, $value)
|
|
{
|
|
if(is_null($this->values))
|
|
$this->loadDataFromDatabase();
|
|
|
|
$this->values[$key] = $value;
|
|
}
|
|
|
|
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 $a)
|
|
{
|
|
$a->select($q);
|
|
}
|
|
$q->from($factory->getTableName());
|
|
$q->where("id = {$this->id}");
|
|
|
|
$joins = $factory->getJoins();
|
|
foreach($joins as $j)
|
|
{
|
|
$j->join($q);
|
|
}
|
|
|
|
$db->setQuery($q);
|
|
$db->execute();
|
|
|
|
$values = $db->loadAssoc();
|
|
|
|
$values = $this->unpackExternalReferencesFromKeys($values);
|
|
|
|
$this->values = $values;
|
|
}
|
|
|
|
private function packExternalReferencesAsKeys($vals)
|
|
{
|
|
foreach($this->getFactory()->getAttributes() as $a)
|
|
{
|
|
$alias = $a->getAlias();
|
|
$vals[$alias] = $a->packValue($vals[$alias]);
|
|
}
|
|
|
|
// XXX Joins
|
|
return $vals;
|
|
}
|
|
|
|
private function unpackExternalReferencesFromKeys($vals)
|
|
{
|
|
$factory = $this->getFactory();
|
|
|
|
foreach($factory->getAttributes() as $a)
|
|
{
|
|
$alias = $a->getAlias();
|
|
if(isset($vals[$alias]))
|
|
$vals[$alias] = $a->unpackValue($vals[$alias]);
|
|
}
|
|
|
|
$joins = $factory->getJoins();
|
|
foreach($joins as $join)
|
|
{
|
|
$join->unpackExternalReferencesFromKeys($vals);
|
|
}
|
|
|
|
return $vals;
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* @param array $rawData
|
|
* @param AbstractCommonClubsModelColumn[] $attribs
|
|
* @param JDatabaseQuery $q
|
|
* @return string[]|number[]|NULL[]
|
|
*/
|
|
private function quoteData($rawData, $attribs, $q)
|
|
{
|
|
$quotedData = array();
|
|
|
|
foreach($attribs as $a)
|
|
{
|
|
$alias = $a->getAlias();
|
|
$quotedData[$alias] = $a->getQuotedValue($q, $rawData[$alias]);
|
|
}
|
|
|
|
return $quotedData;
|
|
}
|
|
|
|
protected function filterDatabaseRawData($values)
|
|
{
|
|
return $values;
|
|
}
|
|
|
|
protected function filterDatabaseQuotedData($quoted)
|
|
{
|
|
return $quoted;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param array $attribs
|
|
* @param JDatabaseQuery $q
|
|
* @return array
|
|
*/
|
|
private function getQuotedData($attribs, $q)
|
|
{
|
|
$rawData = $this->getValues();
|
|
$rawData = $this->filterDatabaseRawData($rawData);
|
|
|
|
$quotedData = $this->quoteData($rawData, $attribs, $q);
|
|
$quotedData = $this->filterDatabaseQuotedData($quotedData);
|
|
|
|
return $quotedData;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param AbstractCommonClubsModelColumn[] $attribs
|
|
* @param AbstractCommonClubsModelFactory $factory
|
|
* @param JDatabaseQuery $q
|
|
*/
|
|
private function prepareInsert($attribs, $factory, $q)
|
|
{
|
|
$q->insert($factory->getTableName());
|
|
|
|
$dbcols = array();
|
|
foreach($attribs as $a)
|
|
{
|
|
$dbcols[] = $a->getColumn();
|
|
}
|
|
|
|
$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 AbstractCommonClubsModelColumn[] $attribs
|
|
* @param AbstractCommonClubsModelFactory $factory
|
|
* @param JDatabaseQuery $q
|
|
*/
|
|
private function prepareUpdate($attribs, $factory, $q)
|
|
{
|
|
$q->update($factory->getTableName());
|
|
|
|
$dbcols = array();
|
|
foreach($attribs as $a)
|
|
$dbcols[] = $a->getColumn();
|
|
|
|
$quotedData = $this->getQuotedData($attribs, $q);
|
|
|
|
$q->set(array_map(function($col, $data){
|
|
return "$col = $data";
|
|
}, $dbcols, $quotedData));
|
|
|
|
$q->where("id = {$this->id}");
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param JDatabaseDriver $db
|
|
*/
|
|
protected function prepareDelete($db)
|
|
{}
|
|
|
|
public function delete()
|
|
{
|
|
$db = Factory::getDbo();
|
|
$q = $db->getQuery(true);
|
|
|
|
$factory = $this->getFactory();
|
|
|
|
$q->delete($factory->getTableName());
|
|
$q->where("id = {$this->id}");
|
|
|
|
$db->transactionStart(true);
|
|
$this->prepareDelete($db);
|
|
$db->setQuery($q);
|
|
$db->execute();
|
|
$db->transactionCommit(true);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param AbstractCommonClubsModelFactory $factory
|
|
* @param string $colName
|
|
* @param array $constraints
|
|
*/
|
|
protected function fetchAssociatedElements($factory, $colName, $constraints = null, $sorting = null)
|
|
{
|
|
$condition = "main.$colName = {$this->id}";
|
|
|
|
if(isset($constraints))
|
|
{
|
|
if(is_array($constraints))
|
|
$allConstraints = clone $constraints;
|
|
elseif(is_string($constraints))
|
|
$allConstraints = array($constraints);
|
|
else
|
|
throw new Exception('Unknown type of constraint');
|
|
|
|
// Add the manual condition to match the current object
|
|
$allConstraints[] = $condition;
|
|
|
|
return $factory->loadElements($allConstraints, $sorting);
|
|
}
|
|
else
|
|
return $factory->loadElements($condition, $sorting);
|
|
}
|
|
|
|
protected function filterPackData($values)
|
|
{
|
|
return $values;
|
|
}
|
|
|
|
protected function filterUnpackData($values)
|
|
{
|
|
return $values;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function pack()
|
|
{
|
|
$vals = $this->getValues();
|
|
|
|
$vals = $this->packExternalReferencesAsKeys($vals);
|
|
$vals = $this->filterPackData($vals);
|
|
|
|
$json = json_encode($vals);
|
|
return urlencode($json);
|
|
}
|
|
|
|
/**
|
|
* @param string $str
|
|
* @param boolean $decode
|
|
*/
|
|
public function unpack($str, $decode = false)
|
|
{
|
|
if($decode)
|
|
$json = urldecode($str);
|
|
else
|
|
$json = $str;
|
|
$data = json_decode($json, true);
|
|
|
|
$vals = $this->unpackExternalReferencesFromKeys($data);
|
|
$vals = $this->filterUnpackData($vals);
|
|
|
|
$this->setValues($vals);
|
|
}
|
|
|
|
public function dataIsValid()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
}
|