<?php
/**
* provides {@link r3_Domain} class
*
*
* Copyright (c) 2007 Yahoo! Inc. All rights reserved.
* The copyrights embodied in the content of this file are licensed under the BSD
* open source license
*
* @package r3
* @author Robin Baker <hide@address.com>
* @version CVS: $Id: Domain.php,v 1.53 2008-09-15 20:02:10 zandstra Exp $
*/
/**
* required
*/
require_once("r3/domain/Location.php");
require_once("r3/Iterator.php");
require_once("r3/util/IdentityMap.php");
require_once("r3/util/Exception.php");
require_once("r3/util/UTF8.php");
/**
* domains are places that store entities of a particular type
*
* @package r3
* @author Robin Baker <hide@address.com>
*/
abstract class r3_Domain {
private $mapper;
private $identity_map;
/**
* __construct( r3_Mapper $mapper )
*
* This constructor should be called by the child of the r3_Domain
* class (i.e r3_domain_TemplateDomain)
*
* @param r3_Mapper $mapper a valid child Mapper object for the
* child of r3_Domain (i.e. r3_mapper_TemplateMapper)
*/
function __construct( r3_Mapper $mapper ) {
$this->mapper = $mapper;
$this->identity_map = new r3_util_IdentityMap();
}
/**
* function getMapper()
*
* accessor method
*
* @return r3_Mapper The r3_Mapper child passed to the constructor
*/
function getMapper() {
return $this->mapper;
}
/**
* Locates first valid r3_domain_DomainObject in inheritance chain
* starting with $loc.
* uses r3_Iterator to call get the inheritance chain of
* r3_domain_Location objects (using getInheritance) with $loc
* as the starting r3_domain_Location. Iterates through the chain
* until a valid child of r3_domain_DomainObject is found and
* returned.
* If no valid r3_domain_DomainObject is found, Locate will throw
* an exception. There should always be a generic item at the end
* of the chain returned.
*
* @param r3_domain_Location $loc starting r3_domain_Location for
* getting inheritance chain.
* @param r3_util_UTF8 $name target to locate. A template
* file name for r3_domain_TemplateDomain, a record id for
* r3_TranslationDomain etc.
* @return r3_domain_DomainObject first valid child of
* r3_domain_DomainObject found in inheritance chain
* (null if not found).
*/
function locate(r3_domain_Location $loc, r3_util_UTF8 $name) {
$iter = $this->getIterator($loc);
foreach ($iter as $location) {
if (($domain_object = $this->mapper->locate($location, $name)) != null) {
$domain_object = $this->unique($domain_object);
return $domain_object;
}
}
return null;
}
/**
* locates all valid r3_domain_DomainObject in the inheritance path
* starting with $loc.
* Similar to Locate above, but returns an r3_domain_FoundObject
* containing all the domain objects plus the iterator that was used
* to locate them.
*
* @param r3_domain_Location $location the start location.
* @param r3_util_UTF8 $name the name of the object to find.
* @return r3_domain_FoundObject the found object(s)
*/
function locateAll(r3_domain_Location $location, r3_util_UTF8 $name) {
$iter = $this->getIterator( $location );
$objects = array();
foreach ($iter as $loc) {
if (($domain_object =
$this->mapper->locate($loc, $name)) != null) {
$objects[] = $this->unique($domain_object);
}
}
return $this->createFoundObject($iter, $objects);
}
/**
* gets an iterator for the current domain rooted at the argument location
*
* @param r3_domain_Location $location location to iterate from
*
* @return r3_Iterator an iterator
*/
function getIterator(r3_domain_Location $location) {
return new r3_Iterator($location, $this);
}
/**
* constructs a found object of the appropriate type (factory method (TM))
*
* @param r3_Iterator $iterator the iterator used to find the objects
* @param array $objects the found objects
* @return r3_domain_FoundObject one of r3_domain_FoundPage,
* r3_domain_FoundTemplate or r3_domain_FoundTranslation.
*/
abstract protected function createFoundObject(r3_Iterator $iterator, array $objects);
/**
* function getInheritanceManager()
*
* @return $mapper - implementation of r3_mapper_InheritanceManager
* (in reality a r3_mapper_GenericInheritanceManager)
*/
function getInheritanceManager() {
return reg()->GenericInheritanceManager();
}
/**
* ensures argument is unique
*
* @param r3_domain_DomainObject $object
* @return r3_domain_DomainObject
*/
function unique(r3_domain_DomainObject $object) {
return $this->identity_map->cache($object->getID(), $object);
}
/**
* inserts domain object
*
* @param r3_domain_DomainObject $object the object to insert
*/
function insert(r3_domain_DomainObject $object) {
$this->getMapper()->insert($object);
}
function update(r3_domain_DomainObject $object) {
$this->getMapper()->update($object);
}
function save(r3_domain_DomainObject $object) {
$id = $object->getId();
if ( $id > 0 ) {
$this->update( $object );
} else {
$this->insert( $object );
}
}
/**
* inserts the domain object unless it can be found by searching
* the inheritance path from the object's location.
*
* @param r3_domain_DomainObject $object the object to overlay
*/
function overlay(r3_domain_DomainObject $object) {
$location = $object->getLocation();
$name = $object->getName();
$found = $this->locate($location, $name);
if (is_null($found)) {
if ( $object->getTicked() == -1 ) {
$object->setTicked(0);
}
$this->insert($object);
} elseif ($object->shouldOverlay($found)) {
if ( $object->getTicked() == -1 ) {
if ( $object->getSource()->eq($object->getTranslation()) ) {
$object->setTicked(0);
} else {
$object->setTicked(1);
}
}
if ($object->getLocation()->eq($found->getLocation())) {
$this->getMapper()->delete($found);
}
$this->insert($object);
}
else {
}
}
/**
* @return string domain name
*/
abstract function getName();
/**
* @return string table name
*/
abstract function tableName();
/**
* @return string name of primary field in database table
*/
abstract function getTableKey();
/**
* @return string name of primary value field in database table
*/
abstract function getTablePrimaryValue();
/**
* @return bool true if domain table has a page component
*/
abstract function tableHasPageComponent();
/**
* @return r3_domain_domainObjectBuilder builder of domain objects
*/
abstract function objectBuilder();
/**
* @return integer count of entities in a domain
*/
function Count() {
return reg()->mapperDb()
->sql_count($this->tableName());
}
// alias - REFACTOR away
function name() {
return $this->getName();
}
// REFACTOR - remove
function toDomain() {
return $this;
}
// REFACTOR - unused (or to be used?)
function defaultGenericHexPageDistance() {
return r3_mapper_InheritanceSQL::GENERIC_HEX_DISTANCE;
}
/**
* @return array of string domain names
*/
static function names() {
return reg()->getCurrentSchema()->domainNames();
}
static function domains() {
$domains = array();
foreach (self::names() as $name) {
$domains[] = dom($name);
}
return $domains;
}
static function allDomainsEmpty() {
foreach (self::domains() as $domain) {
if ($domain->Count() > 0) {
return false;
}
return true;
}
}
static function clearAllDomains() {
foreach (self::domains() as $domain) {
$domain->clearDomain();
}
dom('template')->clearDomain();
}
protected function clearDomain() {
$this->getMapper()->clear();
}
}
?>