mirror of
https://github.com/torrentpier/torrentpier-lts.git
synced 2025-03-01 15:21:02 +03:00
361 lines
8.9 KiB
PHP
361 lines
8.9 KiB
PHP
<?php
|
|
/**
|
|
* Zend Framework (http://framework.zend.com/)
|
|
*
|
|
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
|
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
|
*/
|
|
|
|
namespace Zend\Db\RowGateway;
|
|
|
|
use ArrayAccess;
|
|
use Countable;
|
|
use Zend\Db\Sql\Sql;
|
|
use Zend\Db\Sql\TableIdentifier;
|
|
|
|
abstract class AbstractRowGateway implements ArrayAccess, Countable, RowGatewayInterface
|
|
{
|
|
/**
|
|
* @var bool
|
|
*/
|
|
protected $isInitialized = false;
|
|
|
|
/**
|
|
* @var string|TableIdentifier
|
|
*/
|
|
protected $table = null;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $primaryKeyColumn = null;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $primaryKeyData = null;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $data = array();
|
|
|
|
/**
|
|
* @var Sql
|
|
*/
|
|
protected $sql = null;
|
|
|
|
/**
|
|
* @var Feature\FeatureSet
|
|
*/
|
|
protected $featureSet = null;
|
|
|
|
/**
|
|
* initialize()
|
|
*/
|
|
public function initialize()
|
|
{
|
|
if ($this->isInitialized) {
|
|
return;
|
|
}
|
|
|
|
if (!$this->featureSet instanceof Feature\FeatureSet) {
|
|
$this->featureSet = new Feature\FeatureSet;
|
|
}
|
|
|
|
$this->featureSet->setRowGateway($this);
|
|
$this->featureSet->apply('preInitialize', array());
|
|
|
|
if (!is_string($this->table) && !$this->table instanceof TableIdentifier) {
|
|
throw new Exception\RuntimeException('This row object does not have a valid table set.');
|
|
}
|
|
|
|
if ($this->primaryKeyColumn === null) {
|
|
throw new Exception\RuntimeException('This row object does not have a primary key column set.');
|
|
} elseif (is_string($this->primaryKeyColumn)) {
|
|
$this->primaryKeyColumn = (array) $this->primaryKeyColumn;
|
|
}
|
|
|
|
if (!$this->sql instanceof Sql) {
|
|
throw new Exception\RuntimeException('This row object does not have a Sql object set.');
|
|
}
|
|
|
|
$this->featureSet->apply('postInitialize', array());
|
|
|
|
$this->isInitialized = true;
|
|
}
|
|
|
|
/**
|
|
* Populate Data
|
|
*
|
|
* @param array $rowData
|
|
* @param bool $rowExistsInDatabase
|
|
* @return AbstractRowGateway
|
|
*/
|
|
public function populate(array $rowData, $rowExistsInDatabase = false)
|
|
{
|
|
$this->initialize();
|
|
|
|
$this->data = $rowData;
|
|
if ($rowExistsInDatabase == true) {
|
|
$this->processPrimaryKeyData();
|
|
} else {
|
|
$this->primaryKeyData = null;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param mixed $array
|
|
* @return array|void
|
|
*/
|
|
public function exchangeArray($array)
|
|
{
|
|
return $this->populate($array, true);
|
|
}
|
|
|
|
/**
|
|
* Save
|
|
*
|
|
* @return int
|
|
*/
|
|
public function save()
|
|
{
|
|
$this->initialize();
|
|
|
|
if ($this->rowExistsInDatabase()) {
|
|
// UPDATE
|
|
|
|
$data = $this->data;
|
|
$where = array();
|
|
$isPkModified = false;
|
|
|
|
// primary key is always an array even if its a single column
|
|
foreach ($this->primaryKeyColumn as $pkColumn) {
|
|
$where[$pkColumn] = $this->primaryKeyData[$pkColumn];
|
|
if ($data[$pkColumn] == $this->primaryKeyData[$pkColumn]) {
|
|
unset($data[$pkColumn]);
|
|
} else {
|
|
$isPkModified = true;
|
|
}
|
|
}
|
|
|
|
$statement = $this->sql->prepareStatementForSqlObject($this->sql->update()->set($data)->where($where));
|
|
$result = $statement->execute();
|
|
$rowsAffected = $result->getAffectedRows();
|
|
unset($statement, $result); // cleanup
|
|
|
|
// If one or more primary keys are modified, we update the where clause
|
|
if ($isPkModified) {
|
|
foreach ($this->primaryKeyColumn as $pkColumn) {
|
|
if ($data[$pkColumn] != $this->primaryKeyData[$pkColumn]) {
|
|
$where[$pkColumn] = $data[$pkColumn];
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// INSERT
|
|
$insert = $this->sql->insert();
|
|
$insert->values($this->data);
|
|
|
|
$statement = $this->sql->prepareStatementForSqlObject($insert);
|
|
|
|
$result = $statement->execute();
|
|
if (($primaryKeyValue = $result->getGeneratedValue()) && count($this->primaryKeyColumn) == 1) {
|
|
$this->primaryKeyData = array($this->primaryKeyColumn[0] => $primaryKeyValue);
|
|
} else {
|
|
// make primary key data available so that $where can be complete
|
|
$this->processPrimaryKeyData();
|
|
}
|
|
$rowsAffected = $result->getAffectedRows();
|
|
unset($statement, $result); // cleanup
|
|
|
|
$where = array();
|
|
// primary key is always an array even if its a single column
|
|
foreach ($this->primaryKeyColumn as $pkColumn) {
|
|
$where[$pkColumn] = $this->primaryKeyData[$pkColumn];
|
|
}
|
|
}
|
|
|
|
// refresh data
|
|
$statement = $this->sql->prepareStatementForSqlObject($this->sql->select()->where($where));
|
|
$result = $statement->execute();
|
|
$rowData = $result->current();
|
|
unset($statement, $result); // cleanup
|
|
|
|
// make sure data and original data are in sync after save
|
|
$this->populate($rowData, true);
|
|
|
|
// return rows affected
|
|
return $rowsAffected;
|
|
}
|
|
|
|
/**
|
|
* Delete
|
|
*
|
|
* @return int
|
|
*/
|
|
public function delete()
|
|
{
|
|
$this->initialize();
|
|
|
|
$where = array();
|
|
// primary key is always an array even if its a single column
|
|
foreach ($this->primaryKeyColumn as $pkColumn) {
|
|
$where[$pkColumn] = $this->primaryKeyData[$pkColumn];
|
|
}
|
|
|
|
// @todo determine if we need to do a select to ensure 1 row will be affected
|
|
|
|
$statement = $this->sql->prepareStatementForSqlObject($this->sql->delete()->where($where));
|
|
$result = $statement->execute();
|
|
|
|
$affectedRows = $result->getAffectedRows();
|
|
if ($affectedRows == 1) {
|
|
// detach from database
|
|
$this->primaryKeyData = null;
|
|
}
|
|
|
|
return $affectedRows;
|
|
}
|
|
|
|
/**
|
|
* Offset Exists
|
|
*
|
|
* @param string $offset
|
|
* @return bool
|
|
*/
|
|
public function offsetExists($offset)
|
|
{
|
|
return array_key_exists($offset, $this->data);
|
|
}
|
|
|
|
/**
|
|
* Offset get
|
|
*
|
|
* @param string $offset
|
|
* @return mixed
|
|
*/
|
|
public function offsetGet($offset)
|
|
{
|
|
return $this->data[$offset];
|
|
}
|
|
|
|
/**
|
|
* Offset set
|
|
*
|
|
* @param string $offset
|
|
* @param mixed $value
|
|
* @return RowGateway
|
|
*/
|
|
public function offsetSet($offset, $value)
|
|
{
|
|
$this->data[$offset] = $value;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Offset unset
|
|
*
|
|
* @param string $offset
|
|
* @return AbstractRowGateway
|
|
*/
|
|
public function offsetUnset($offset)
|
|
{
|
|
$this->data[$offset] = null;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function count()
|
|
{
|
|
return count($this->data);
|
|
}
|
|
|
|
/**
|
|
* To array
|
|
*
|
|
* @return array
|
|
*/
|
|
public function toArray()
|
|
{
|
|
return $this->data;
|
|
}
|
|
|
|
/**
|
|
* __get
|
|
*
|
|
* @param string $name
|
|
* @throws Exception\InvalidArgumentException
|
|
* @return mixed
|
|
*/
|
|
public function __get($name)
|
|
{
|
|
if (array_key_exists($name, $this->data)) {
|
|
return $this->data[$name];
|
|
} else {
|
|
throw new Exception\InvalidArgumentException('Not a valid column in this row: ' . $name);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* __set
|
|
*
|
|
* @param string $name
|
|
* @param mixed $value
|
|
* @return void
|
|
*/
|
|
public function __set($name, $value)
|
|
{
|
|
$this->offsetSet($name, $value);
|
|
}
|
|
|
|
/**
|
|
* __isset
|
|
*
|
|
* @param string $name
|
|
* @return bool
|
|
*/
|
|
public function __isset($name)
|
|
{
|
|
return $this->offsetExists($name);
|
|
}
|
|
|
|
/**
|
|
* __unset
|
|
*
|
|
* @param string $name
|
|
* @return void
|
|
*/
|
|
public function __unset($name)
|
|
{
|
|
$this->offsetUnset($name);
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function rowExistsInDatabase()
|
|
{
|
|
return ($this->primaryKeyData !== null);
|
|
}
|
|
|
|
/**
|
|
* @throws Exception\RuntimeException
|
|
*/
|
|
protected function processPrimaryKeyData()
|
|
{
|
|
$this->primaryKeyData = array();
|
|
foreach ($this->primaryKeyColumn as $column) {
|
|
if (!isset($this->data[$column])) {
|
|
throw new Exception\RuntimeException('While processing primary key data, a known key ' . $column . ' was not found in the data array');
|
|
}
|
|
$this->primaryKeyData[$column] = $this->data[$column];
|
|
}
|
|
}
|
|
}
|