Skip to content

Instantly share code, notes, and snippets.

@renepardon
Created October 6, 2011 18:01
Show Gist options
  • Save renepardon/1268130 to your computer and use it in GitHub Desktop.
Save renepardon/1268130 to your computer and use it in GitHub Desktop.
Entity Manager for Zend_Db_Table objects
<?php
/**
* YelaCMS
*
* LICENSE
*
* This file is part of YelaCMS.
*
* YelaCMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* YelaCMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with YelaCMS. If not, see <http://www.gnu.org/licenses/>.
*
* @category Yela
* @package Yela\Entity
* @subpackage
* @copyright Copyright (c) 2011 BoonWeb
* @license GNU/GPL
* @version 0.0.1
*/
namespace Yela\Entity;
use Yela\Db\Table\TableAbstract;
use Yela\Entity\Exception;
use Yela\Entity\Collection;
/**
* @category Yela
* @package Yela\Entity
* @subpackage
* @copyright Copyright (c) 2011 BoonWeb
* @license GNU/GPL
*/
class Manager
{
const TABLE_PREFIX = 'Application_Model_DbTable_';
const ENTITY_PREFIX = 'Application_Model_';
/**
* @var TableAbstract
*/
private $_table = null;
/**
* @var \Zend_Filter_Word_CamelCaseToUnderscore
*/
private $_filter = null;
/**
* Create entity manager instance with table to use for storage.
*
* @param string|TableAbstract $table
*
* @return void
*/
public function __construct($table = null)
{
// May throw Yela\Entity\Exception
$this->_setTable($table);
$this->_filter = new \Zend_Filter_Word_CamelCaseToUnderscore();
}
/**
* Sets $_table.
*
* @param string|TableAbstract $table
*
* @return Manager
*/
public function setTable($table)
{
// May throw Yela\Entity\Exception
$this->_setTable($table);
return $this;
}
/**
* Gets Table instance.
*
* @return TableAbstract
*/
public function getTable()
{
return $this->_table;
}
/**
* Sets $_table.
*
* @param string|TableAbstract $table
*
* @return void
*/
private function _setTable($table)
{
if ($table instanceof TableAbstract) {
// Table instance.
$this->_table = $table;
} else if (is_string($table)) {
if (class_exists($table)) {
// Use of table class name.
$this->_table = new $table();
} else {
// Table name.
$class = self::TABLE_PREFIX . ucfirst($table);
if (class_exists($class)) {
$this->_table = new $class();
} else {
throw new Exception('Undefined table name.');
}
}
}
}
/**
* Save entity - check if it exist and update elsewhere insert.
*
* @param EntityInterface $entity
*
* @return
*/
public function save(EntityInterface $entity)
{
$result = $this->_fetchByPrimary($entity);
if ($result) {
$this->update($entity);
} else {
$this->insert($entity);
}
}
public function insert(EntityInterface $entity)
{
// Insert new entity object
$this->_table->insert($entity->toArray());
}
public function update(EntityInterface $entity)
{
// Update entity
$this->_table->update(
$entity->toArray(),
$this->_retrieveWhere($entity)
);
}
public function delete(EntityInterface $entity)
{
// Delete with references?
$this->_table->delete($this->_retrieveWhere($entity));
}
/**
* Try to search for dynamic column and return the result as collection.
*
* Proxy for dbTable class. Methods and requested parameters will be passed
* to corresponding class and return values are returnd either./
*
* @param string $name
* @param string $arguments
*
* @throws Yela\Entity\Exception
* @return EntityCollection
*/
public function __call($name, $arguments)
{
if (preg_match('#^findBy(.*)#', $name, $matches)) {
$colName = strtolower($this->_filter->filter($matches[1]));
return $this->_returnCollection(
$this->_table->fetchAll(array($colName . '=?' => $arguments[0]))
);
} else {
return $this->_returnCollection(
call_user_func_array(array($this->_table, $name), $arguments)
);
}
}
/**
* Fetch all rows from table.
*
* @param mixed $where
* @param mixed $order
* @param integer $count
* @param integer $offset
*
* @return EntityCollection
*/
public function fetchAll(
$where = null,
$order = null,
$count = null,
$offset = null
)
{
$resultset = $this->_table->fetchAll($where, $order, $count, $offset);
return $this->_returnCollection($resultset);
}
public function findDependentRowset(EntityInterface $entity, $dependentTable, $ruleKey = null)
{
$where = $this->_retrieveWhere($entity);
$rowset = $this->_table->fetchAll($where);
if (count($rowset) == 0) {
// Return empty collection.
return $this->_returnCollection();
}
$result = $rowset->current()->findDependentRowset(
$dependentTable,
$ruleKey
);
return $this->_returnCollection($result);
}
public function findParentRow(EntityInterface $entity, $parentTable, $ruleKey = null)
{
$where = $this->_retrieveWhere($entity);
$rowset = $this->_table->fetchAll($where);
if (count($rowset) == 0) {
// Return empty collection.
return $this->_returnCollection();
}
$result = $rowset->current()->findParentRow(
$parentTable,
$ruleKey
);
return $this->_returnCollection($result);
}
public function findManyToManyRowset(
EntityInterface $entity,
$matchTable,
$intersectionTable,
$callerRefRule = null,
$matchRefRule = null)
{
$rowset = $this->_table->find($this->_retrieveWhere($entity));
$resultset = $rowset->current()->findManyToManyRowset(
$matchTable,
$intersectionTable,
$callerRefRule,
$matchRefRule
);
return $this->_returnCollection($resultset);
}
/**
* Fetch entitie(s) by its primary key(s).
*
* @param EntityInterface $entity
*
* @return mixed
*/
protected function _fetchByPrimary(EntityInterface $entity)
{
$rowset = $this->_table->find($this->_retrieveWhere($entity));
if ($rowset->count() > 0) {
return $this->_returnCollection($rowset->current());
}
return null;
}
/**
* Gets the where condition for a find() search filled with primary keys.
*
* @param EntityInterface $entity
*
* @throws Yela\Entity\Exception
* @return array
*/
private function _retrieveWhere(EntityInterface $entity)
{
$keys = $entity->getPrimaryKeys();
$where = array();
$cols = $entity->toArray();
if (is_string($keys)) {
$where[$keys . '=?'] = $cols[$keys];
} else if (is_array($keys)) {
foreach ($keys as $key) {
$where[$key . '=?'] = $cols[$key];
}
} else {
throw new Exception('No primary key available');
}
return $where;
}
/**
* Returns a collection for the current entity.
*
* @param mixed $rowdata
*
* @return EntityCollection
*/
private function _returnCollection($rowdata)
{
$entityName = str_replace(
self::TABLE_PREFIX, '', get_class($this->_table)
);
$entityClass = self::ENTITY_PREFIX . $entityName;
$collection = new Collection();
if ($rowdata instanceof \Zend_Db_Table_Row_Abstract) {
$collection->setData($rowdata->toArray());
} else if ($rowdata instanceof \Zend_Db_Table_Rowset_Abstract) {
foreach ($rowdata as $row) {
$entity = new $entityClass();
$collection->add($entity->setOptions($row->toArray()));
}
}
return $collection;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment