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