http://phing.info/

Source Code Coverage

Designed for use with PHPUnit2, Xdebug and Phing.

Methods: 6 LOC: 252 Statements: 107

Source file Statements Methods Total coverage
Translator.php 97.2% 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 202 2008-01-20 16:20:09Z doublecompile $
15
 */
16
/**
17
 * @see Xyster_Db_Translator
18
 */
19 1
require_once 'Xyster/Db/Translator.php';
20
/**
21
 * @see Xyster_Orm_Query_Parser
22
 */
23 1
require_once 'Xyster/Orm/Query/Parser.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
	 * The query parser
64
	 *
65
	 * @var Xyster_Orm_Query_Parser
66
	 */
67
	protected $_parser;
68
69
	/**
70
	 * Creates a new orm sql translator
71
	 * {@inherit}
72
	 *
73
	 * @param Zend_Db_Adapter_Abstract $db
74
	 * @param string $className
75
	 */
76
	public function __construct( Zend_Db_Adapter_Abstract $db, $className, Xyster_Orm_Mapper_Factory_Interface $mapFactory )
77
	{
78 5
	    parent::__construct($db);
79
80 5
	    require_once 'Xyster/Orm/Loader.php';
81 5
	    Xyster_Orm_Loader::loadEntityClass($className);
82 5
	    $this->_class = $className;
83 5
	    $this->_mapFactory = $mapFactory;
84 5
	    require_once 'Xyster/Orm/Query/Parser.php';
85 5
	    $this->_parser = new Xyster_Orm_Query_Parser($mapFactory);
86 5
	    $map = $mapFactory->get($className);
87 5
	    $this->aliasField(current($map->getEntityMeta()->getPrimary()));
88
	}
89
90
	/**
91
	 * Gets the main alias
92
	 *
93
	 * @return string
94
	 */
95
	public function getMain()
96
	{
97 4
		return array_key_exists('', $this->_aliases) ? $this->_aliases[''] : null;
98
	}
99
100
	/**
101
	 * Returns an alias to prefix a column in a SQL query
102
	 *
103
	 * @param string $column  The column to alias
104
	 * @throws Xyster_Orm_Backend_Sql_Exception if $column is runtime
105
	 * @return string
106
	 */
107
	public function aliasField( $field )
108
	{
109 5
		if ( $this->_parser->isRuntime(Xyster_Data_Field::named($field), $this->_class) ) {
110 1
			require_once 'Xyster/Orm/Mapper/Exception.php';
111 1
			throw new Xyster_Orm_Mapper_Exception('Runtime fields cannot be aliased for the backend');
112 0
		}
113
114 5
		$factory = $this->_mapFactory;
115 5
		$className = $this->_class;
116 5
		$prefix = "";
117 5
        $currentMeta = $factory->getEntityMeta($className);
118 5
		$calls = Xyster_String::smartSplit('->',$field);
119
120 5
		if ( count($calls) > 1 ) {
121 2
			$prefixes = array();
122 2
			foreach( $calls as $call ) {
123 2
			    if ( $currentMeta->isRelation($call) ) {
124 2
    				$prefixes[] = $call;
125 2
				    $className = $currentMeta->getRelation($call)->getTo();
126 2
				    $currentMeta = $factory->getEntityMeta($className);
127 2
			    }
128 2
			}
129 2
			$prefix = implode('->', $prefixes) . '->';
130 2
		}
131
132 5
		if ( !in_array($prefix, array_keys($this->_tables)) ) {
133 5
			$tableName = $factory->get($className)->getTable();
134 5
			$num = count(array_keys($this->_tables, $tableName));
135 5
			$this->_tables[$prefix] = $tableName;
136 5
			$this->_aliases[$prefix] = preg_replace('/[`\]\s]*/i', '',
137 5
				$tableName) . $num;
138 5
		}
139
140 5
		return $this->_aliases[$prefix];
141
	}
142
143
	/**
144
	 * Returns a from clause for a SQL query
145
	 *
146
	 * @return array An array of {@link Xyster_Db_Token} objects with table alias as key
147
	 */
148
	public function getFromClause()
149
	{
150 4
		$joined = array();
151 4
		$from = array();
152 4
		$factory = $this->_mapFactory;
153 4
		$db = $this->_adapter;
154
155 4
		foreach( array_keys($this->_aliases) as $prefix ) {
156 4
			if ( $prefix == '' ) {
157 4
				continue;
158 0
			}
159
160 2
			$prefixes = explode('->',$prefix);
161 2
			$container = $this->_class;
162 2
			$prefixsofar = '';
163 2
			$lastTable = $this->_tables[''];
164 2
			$lastAlias = $this->getMain();
165
166 2
			foreach( $prefixes as $v ) {
167 2
				if ( !$v ) {
168 2
					continue;
169 0
				}
170
171 2
				$prefixsofar .= $v.'->';
172 2
				$fromMap = $factory->get($container);
173 2
				$fromMeta = $fromMap->getEntityMeta();
174 2
				$relation = $fromMeta->getRelation($v);
175 2
				$class = $relation->getTo();
176 2
				$toMap = $factory->get($class);
177 2
				$alias = $this->aliasField($prefixsofar.current($toMap->getEntityMeta()->getPrimary()));
178
179 2
				$binds = array();
180 2
			    $localFrom = array();
181
182 2
				if (!in_array($prefixsofar, $joined)) {
183
184 2
                    $keyMap = array_combine($relation->getId(), $toMap->getEntityMeta()->getPrimary());
185 2
					foreach( $keyMap as $fromKey=>$toKey ) {
186 2
					    $localFrom[] = $lastAlias . '.'
187 2
							. $db->quoteIdentifier($fromMap->untranslateField($fromKey))
188 2
					        . ' = ' . $alias . '.' . $toMap->untranslateField($db->quoteIdentifier($toKey));
189 2
					}
190
191 2
					if ( $relation->getFilters() ) {
192 2
						$translator = new Xyster_Db_Translator($db);
193 2
						$translator->setRenameCallback(array($toMap, 'untranslateField'));
194 2
						$translator->setTable($alias);
195 2
						$fToken = $translator->translate($relation->getFilters());
196 2
						$localFrom[] = $fToken->getSql();
197 2
						$binds += $fToken->getBindValues();
198 2
					}
199 2
					$joined[] = $prefixsofar;
200 2
				}
201 2
				$lastAlias = $alias;
202 2
				$lastTable = $toMap->getTable();
203 2
				$container = $class;
204
205 2
				$from[ $toMap->getTable() . ' AS ' . $alias ] =
206 2
				    new Xyster_Db_Token(implode(' AND ', $localFrom), $binds);
207 2
			}
208 2
		}
209
210 4
		return $from;
211
	}
212
213
	/**
214
	 * {@inherit}
215
	 *
216
	 * @param Xyster_Data_Field $field
217
	 * @return string
218
	 */
219
	protected function _getRenamedField( Xyster_Data_Field $field )
220
	{
221 4
	    $factory = $this->_mapFactory;
222 4
		$className = $this->_class;
223
224 4
	    $prefixes = Xyster_String::smartSplit('->', $field->getName());
225 4
		$meta = $factory->getEntityMeta($className);
226
227 4
		if ( count($prefixes) > 1 ) {
228 2
			foreach( $prefixes as $call ) {
229 2
				if ( $meta->isRelation($call) ) {
230 2
					$className = $meta->getRelation($call)->getTo();
231 2
		            $meta = $factory->getEntityMeta($className);
232 2
				}
233 2
			}
234 2
		}
235
236 4
		$rename = $factory->get($className)
237 4
			->untranslateField($prefixes[count($prefixes)-1]);
238
239 4
	    return $rename;
240
	}
241
242
	/**
243
	 * {@inherit}
244
	 *
245
	 * @param Xyster_Data_Field $field
246
	 * @return string
247
	 */
248
	protected function _getTableName( Xyster_Data_Field $field )
249
	{
250 4
	    return $this->aliasField($field->getName());
251
	}
252
}


Report generated at 2008-01-20T12:13:38-05:00