Location: PHPKode > projects > Rthree > r3-1.9.0/r3/Domain.php
<?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();
    }

}

?>
Return current item: Rthree