http://phing.info/

Source Code Coverage

Designed for use with PHPUnit2, Xdebug and Phing.

Methods: 6 LOC: 244 Statements: 105

Source file Statements Methods Total coverage
Translator.php 97.1% 100.0% 97.3%
   
1
<?php
2
/**
3
 * Xyster Framework
4
 *
5
 * This source file is subject to the new BSD license that is bundled
6
 * with this package in the file LICENSE.txt.
7
 * It is also available through the world-wide-web at this URL:
8
 * http://www.opensource.org/licenses/bsd-license.php
9
 *
10
 * @category  Xyster
11
 * @package   Xyster_Orm
12
 * @copyright Copyright (c) 2007-2008 Irrational Logic (http://irrationallogic.net)
13
 * @license   http://www.opensource.org/licenses/bsd-license.php New BSD License
14
 * @version   $Id: Translator.php 220 2008-02-09 18:04:52Z doublecompile $
15
 */
16
/**
17
 * @see Xyster_Db_Translator
18
 */
19 1
require_once 'Xyster/Db/Translator.php';
20
/**
21
 * @see Xyster_Orm_Xsql
22
 */
23 1
require_once 'Xyster/Orm/Xsql.php';
24
/**
25
 * A translator for db fields that is smart about ORM
26
 *
27
 * @category  Xyster
28
 * @package   Xyster_Orm
29
 * @copyright Copyright (c) 2007-2008 Irrational Logic (http://irrationallogic.net)
30
 * @license   http://www.opensource.org/licenses/bsd-license.php New BSD License
31
 */
32
class Xyster_Orm_Mapper_Translator extends Xyster_Db_Translator
33
{
34
    /**
35
     * This is the anchor class for translations
36
     *
37
     * @var string
38
     */
39
	protected $_class;
40
41
	/**
42
	 * Associative array of prefixes to table aliases
43
	 *
44
	 * @var array
45
	 */
46
	protected $_aliases = array();
47
48
	/**
49
	 * Associative array of prefixes to table names
50
	 *
51
	 * @var array
52
	 */
53
	protected $_tables = array();
54
55
	/**
56
	 * The mapper factory
57
	 *
58
	 * @var Xyster_Orm_Mapper_Factory_Interface
59
	 */
60
	protected $_mapFactory;
61
62
	/**
63
	 * Creates a new orm sql translator
64
	 * {@inherit}
65
	 *
66
	 * @param Zend_Db_Adapter_Abstract $db
67
	 * @param string $className
68
	 */
69
	public function __construct( Zend_Db_Adapter_Abstract $db, $className, Xyster_Orm_Mapper_Factory_Interface $mapFactory )
70
	{
71 20
	    parent::__construct($db);
72
73 20
	    require_once 'Xyster/Orm/Loader.php';
74 20
	    Xyster_Orm_Loader::loadEntityClass($className);
75 20
	    $this->_class = $className;
76 20
	    $this->_mapFactory = $mapFactory;
77 20
	    $map = $mapFactory->get($className);
78 20
	    $this->aliasField(current($map->getEntityMeta()->getPrimary()));
79
	}
80
81
	/**
82
	 * Gets the main alias
83
	 *
84
	 * @return string
85
	 */
86
	public function getMain()
87
	{
88 16
		return array_key_exists('', $this->_aliases) ? $this->_aliases[''] : null;
89
	}
90
91
	/**
92
	 * Returns an alias to prefix a column in a SQL query
93
	 *
94
	 * @param string $column  The column to alias
95
	 * @throws Xyster_Orm_Mapper_Exception if $column is runtime
96
	 * @return string
97
	 */
98
	public function aliasField( $field )
99
	{
100 20
        $factory = $this->_mapFactory;
101 20
        $className = $this->_class;
102 20
        $currentMeta = $factory->getEntityMeta($className);
103
104 20
		if ( $currentMeta->isRuntime(Xyster_Data_Field::named($field)) ) {
105 4
			require_once 'Xyster/Orm/Mapper/Exception.php';
106 4
			throw new Xyster_Orm_Mapper_Exception('Runtime fields cannot be aliased for the backend');
107 0
		}
108
109 20
		$prefix = "";
110 20
		$calls = Xyster_Orm_Xsql::splitArrow($field);
111
112 20
		if ( count($calls) > 1 ) {
113 8
			$prefixes = array();
114 8
			foreach( $calls as $call ) {
115 8
			    if ( $currentMeta->isRelation($call) ) {
116 8
    				$prefixes[] = $call;
117 8
				    $className = $currentMeta->getRelation($call)->getTo();
118 8
				    $currentMeta = $factory->getEntityMeta($className);
119 8
			    }
120 8
			}
121 8
			$prefix = implode('->', $prefixes) . '->';
122 8
		}
123
124 20
		if ( !in_array($prefix, array_keys($this->_tables)) ) {
125 20
			$tableName = $factory->get($className)->getTable();
126 20
			$num = count(array_keys($this->_tables, $tableName));
127 20
			$this->_tables[$prefix] = $tableName;
128 20
			$this->_aliases[$prefix] = preg_replace('/[`\]\s]*/i', '',
129 20
				$tableName) . $num;
130 20
		}
131
132 20
		return $this->_aliases[$prefix];
133
	}
134
135
	/**
136
	 * Returns a from clause for a SQL query
137
	 *
138
	 * @return array An array of {@link Xyster_Db_Token} objects with table alias as key
139
	 */
140
	public function getFromClause()
141
	{
142 16
		$joined = array();
143 16
		$from = array();
144 16
		$factory = $this->_mapFactory;
145 16
		$db = $this->_adapter;
146
147 16
		foreach( array_keys($this->_aliases) as $prefix ) {
148 16
			if ( $prefix == '' ) {
149 16
				continue;
150 0
			}
151
152 8
			$prefixes = explode('->',$prefix);
153 8
			$container = $this->_class;
154 8
			$prefixsofar = '';
155 8
			$lastTable = $this->_tables[''];
156 8
			$lastAlias = $this->getMain();
157
158 8
			foreach( $prefixes as $v ) {
159 8
				if ( !$v ) {
160 8
					continue;
161 0
				}
162
163 8
				$prefixsofar .= $v.'->';
164 8
				$fromMap = $factory->get($container);
165 8
				$fromMeta = $fromMap->getEntityMeta();
166 8
				$relation = $fromMeta->getRelation($v);
167 8
				$class = $relation->getTo();
168 8
				$toMap = $factory->get($class);
169 8
				$alias = $this->aliasField($prefixsofar.current($toMap->getEntityMeta()->getPrimary()));
170
171 8
				$binds = array();
172 8
			    $localFrom = array();
173
174 8
				if (!in_array($prefixsofar, $joined)) {
175
176 8
                    $keyMap = array_combine($relation->getId(), $toMap->getEntityMeta()->getPrimary());
177 8
					foreach( $keyMap as $fromKey=>$toKey ) {
178 8
					    $localFrom[] = $lastAlias . '.'
179 8
							. $db->quoteIdentifier($fromMap->untranslateField($fromKey))
180 8
					        . ' = ' . $alias . '.' . $toMap->untranslateField($db->quoteIdentifier($toKey));
181 8
					}
182
183 8
					if ( $relation->getFilters() ) {
184 8
						$translator = new Xyster_Db_Translator($db);
185 8
						$translator->setRenameCallback(array($toMap, 'untranslateField'));
186 8
						$translator->setTable($alias);
187 8
						$fToken = $translator->translate($relation->getFilters());
188 8
						$localFrom[] = $fToken->getSql();
189 8
						$binds += $fToken->getBindValues();
190 8
					}
191 8
					$joined[] = $prefixsofar;
192 8
				}
193 8
				$lastAlias = $alias;
194 8
				$lastTable = $toMap->getTable();
195 8
				$container = $class;
196
197 8
				$from[ $toMap->getTable() . ' AS ' . $alias ] =
198 8
				    new Xyster_Db_Token(implode(' AND ', $localFrom), $binds);
199 8
			}
200 8
		}
201
202 16
		return $from;
203
	}
204
205
	/**
206
	 * {@inherit}
207
	 *
208
	 * @param Xyster_Data_Field $field
209
	 * @return string
210
	 */
211
	protected function _getRenamedField( Xyster_Data_Field $field )
212
	{
213 16
	    $factory = $this->_mapFactory;
214 16
		$className = $this->_class;
215
216 16
		$prefixes = Xyster_Orm_Xsql::splitArrow($field->getName());
217 16
		$meta = $factory->getEntityMeta($className);
218
219 16
		if ( count($prefixes) > 1 ) {
220 8
			foreach( $prefixes as $call ) {
221 8
				if ( $meta->isRelation($call) ) {
222 8
					$className = $meta->getRelation($call)->getTo();
223 8
		            $meta = $factory->getEntityMeta($className);
224 8
				}
225 8
			}
226 8
		}
227
228 16
		$rename = $factory->get($className)
229 16
			->untranslateField($prefixes[count($prefixes)-1]);
230
231 16
	    return $rename;
232
	}
233
234
	/**
235
	 * {@inherit}
236
	 *
237
	 * @param Xyster_Data_Field $field
238
	 * @return string
239
	 */
240
	protected function _getTableName( Xyster_Data_Field $field )
241
	{
242 16
	    return $this->aliasField($field->getName());
243
	}
244
}


Report generated at 2008-03-05T18:27:43-05:00