Index: Table/Row/Abstract.php =================================================================== --- Table/Row/Abstract.php (revision 9065) +++ Table/Row/Abstract.php (working copy) @@ -480,7 +480,7 @@ $pkOld = $this->_getPrimaryKey(false); foreach ($depTables as $tableClass) { try { - @Zend_Loader::loadClass($tableClass); + $tableClass = $this->_getTable()->_loadClass($tableClass); } catch (Zend_Exception $e) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception($e->getMessage()); @@ -550,7 +550,7 @@ $pk = $this->_getPrimaryKey(); foreach ($depTables as $tableClass) { try { - @Zend_Loader::loadClass($tableClass); + $tableClass = $this->_getTable()->_loadClass($tableClass); } catch (Zend_Exception $e) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception($e->getMessage()); @@ -773,7 +773,14 @@ */ protected function _prepareReference(Zend_Db_Table_Abstract $dependentTable, Zend_Db_Table_Abstract $parentTable, $ruleKey) { - $map = $dependentTable->getReference(get_class($parentTable), $ruleKey); + if (count($parentTable->getRelationshipPath() > 0) { + foreach ($parentTable->getRelationshipPath() as $relationshipPath) { + $parentTable = str_replace('_', '', str_replace($relationshipPath, '', get_class($parentTable))); + } + } else { + $parentTable = get_class($parentTable); + } + $map = $dependentTable->getReference($parentTable, $ruleKey); if (!isset($map[Zend_Db_Table_Abstract::REF_COLUMNS])) { $parentInfo = $parentTable->info(); @@ -800,7 +807,7 @@ if (is_string($dependentTable)) { try { - @Zend_Loader::loadClass($dependentTable); + $dependentTable = $this->_getTable()->_loadClass($dependentTable); } catch (Zend_Exception $e) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception($e->getMessage()); @@ -853,7 +860,7 @@ if (is_string($parentTable)) { try { - @Zend_Loader::loadClass($parentTable); + $parentTable = $this->_getTable()->_loadClass($parentTable); } catch (Zend_Exception $e) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception($e->getMessage()); @@ -907,7 +914,7 @@ if (is_string($intersectionTable)) { try { - @Zend_Loader::loadClass($intersectionTable); + $intersectionTable = $this->_getTable()->_loadClass($intersectionTable); } catch (Zend_Exception $e) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception($e->getMessage()); @@ -925,7 +932,7 @@ if (is_string($matchTable)) { try { - @Zend_Loader::loadClass($matchTable); + $matchTable = $this->_getTable()->_loadClass($matchTable); } catch (Zend_Exception $e) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception($e->getMessage()); Index: Table/Abstract.php =================================================================== --- Table/Abstract.php (revision 9065) +++ Table/Abstract.php (working copy) @@ -202,6 +202,13 @@ protected $_dependentTables = array(); /** + * Path stack for database tables. + * + * @var array + */ + protected static $_path = array(); + + /** * Constructor. * * Supported params for $config are: @@ -271,6 +278,84 @@ } /** + * @param string $path + * @param string $classPrefix + * @return void + */ + public static final function addRelationshipPath($path, $classPrefix = '') + { + if (!empty($classPrefix) && ('_' != substr($classPrefix, -1))) { + $classPrefix .= '_'; + } + + self::_addPath($path, $classPrefix); + } + + /** + * Returns relations + * + * @return array + */ + public static final function getRelationshipPath() + { + return self::$_path; + } + + /** + * @param string $name + * @return class name + */ + public function _loadClass($name) + { + // check to see if name => class mapping exists for helper/filter + $classLoaded = '_Loaded'; + $classAccess = '_setClass'; + if (isset($this->$classLoaded[$name])) { + return $this->$classLoaded[$name]; + } + + // only look for "$Name.php" + $file = ucfirst($name) . '.php'; + + // do LIFO search for helper + foreach (self::$_path as $info) { + $dir = $info['dir']; + $prefix = $info['prefix']; + + $class = $prefix . ucfirst($name); + $class = preg_replace('/([a-z])([A-Z])/', "$1_$2", $class); + + Zend_Loader::loadClass($class); + return $class; + } + + require_once 'Zend/View/Exception.php'; + throw new Zend_View_Exception("'$name' not found in path", $this); + } + + /** + * @param string $path + * @param string $prefix + * @return void + */ + private function _addPath($path, $prefix = null) + { + foreach ((array) $path as $dir) { + // attempt to strip any possible separator and + // append the system directory separator + $dir = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $dir); + $dir = rtrim($dir, DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR) + . DIRECTORY_SEPARATOR; + $params = array('prefix' => $prefix, 'dir' => $dir); + + if (!in_array($params, self::$_path)){ + // add as array with prefix and dir keys + array_unshift(self::$_path, $params); + } + } + } + + /** * @param string $classname * @return Zend_Db_Table_Abstract Provides a fluent interface */