http://phing.info/

Source Code Coverage

Designed for use with PHPUnit2, Xdebug and Phing.

Methods: 6 LOC: 257 Statements: 107

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


Report generated at 2007-10-08T19:32:23-05:00