1: <?php
2:
3: /**
4: * Zend Framework
5: *
6: * LICENSE
7: *
8: * This source file is subject to the new BSD license that is bundled
9: * with this package in the file LICENSE.txt.
10: * It is also available through the world-wide-web at this URL:
11: * http://framework.zend.com/license/new-bsd
12: * If you did not receive a copy of the license and are unable to
13: * obtain it through the world-wide-web, please send an email
14: * to license@zend.com so we can send you a copy immediately.
15: *
16: * @category Zend
17: * @package Zend_Db
18: * @subpackage Select
19: * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
20: * @license http://framework.zend.com/license/new-bsd New BSD License
21: * @version $Id: Select.php 20096 2010-01-06 02:05:09Z bkarwin $
22: */
23:
24:
25: /**
26: * @see Zend_Db_Select
27: */
28: require_once 'Zend/Db/Select.php';
29:
30:
31: /**
32: * @see Zend_Db_Table_Abstract
33: */
34: require_once 'Zend/Db/Table/Abstract.php';
35:
36:
37: /**
38: * Class for SQL SELECT query manipulation for the Zend_Db_Table component.
39: *
40: * @category Zend
41: * @package Zend_Db
42: * @subpackage Table
43: * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
44: * @license http://framework.zend.com/license/new-bsd New BSD License
45: */
46: class Zend_Db_Table_Select extends Zend_Db_Select
47: {
48: /**
49: * Table schema for parent Zend_Db_Table.
50: *
51: * @var array
52: */
53: protected $_info;
54:
55: /**
56: * Table integrity override.
57: *
58: * @var array
59: */
60: protected $_integrityCheck = true;
61:
62: /**
63: * Table instance that created this select object
64: *
65: * @var Zend_Db_Table_Abstract
66: */
67: protected $_table;
68:
69: /**
70: * Class constructor
71: *
72: * @param Zend_Db_Table_Abstract $adapter
73: */
74: public function __construct(Zend_Db_Table_Abstract $table)
75: {
76: parent::__construct($table->getAdapter());
77:
78: $this->setTable($table);
79: }
80:
81: /**
82: * Return the table that created this select object
83: *
84: * @return Zend_Db_Table_Abstract
85: */
86: public function getTable()
87: {
88: return $this->_table;
89: }
90:
91: /**
92: * Sets the primary table name and retrieves the table schema.
93: *
94: * @param Zend_Db_Table_Abstract $adapter
95: * @return Zend_Db_Select This Zend_Db_Select object.
96: */
97: public function setTable(Zend_Db_Table_Abstract $table)
98: {
99: $this->_adapter = $table->getAdapter();
100: $this->_info = $table->info();
101: $this->_table = $table;
102:
103: return $this;
104: }
105:
106: /**
107: * Sets the integrity check flag.
108: *
109: * Setting this flag to false skips the checks for table joins, allowing
110: * 'hybrid' table rows to be created.
111: *
112: * @param Zend_Db_Table_Abstract $adapter
113: * @return Zend_Db_Select This Zend_Db_Select object.
114: */
115: public function setIntegrityCheck($flag = true)
116: {
117: $this->_integrityCheck = $flag;
118: return $this;
119: }
120:
121: /**
122: * Tests query to determine if expressions or aliases columns exist.
123: *
124: * @return boolean
125: */
126: public function isReadOnly()
127: {
128: $readOnly = false;
129: $fields = $this->getPart(Zend_Db_Table_Select::COLUMNS);
130: $cols = $this->_info[Zend_Db_Table_Abstract::COLS];
131:
132: if (!count($fields)) {
133: return $readOnly;
134: }
135:
136: foreach ($fields as $columnEntry) {
137: $column = $columnEntry[1];
138: $alias = $columnEntry[2];
139:
140: if ($alias !== null) {
141: $column = $alias;
142: }
143:
144: switch (true) {
145: case ($column == self::SQL_WILDCARD):
146: break;
147:
148: case ($column instanceof Zend_Db_Expr):
149: case (!in_array($column, $cols)):
150: $readOnly = true;
151: break 2;
152: }
153: }
154:
155: return $readOnly;
156: }
157:
158: /**
159: * Adds a FROM table and optional columns to the query.
160: *
161: * The table name can be expressed
162: *
163: * @param array|string|Zend_Db_Expr|Zend_Db_Table_Abstract $name The table name or an
164: associative array relating
165: table name to correlation
166: name.
167: * @param array|string|Zend_Db_Expr $cols The columns to select from this table.
168: * @param string $schema The schema name to specify, if any.
169: * @return Zend_Db_Table_Select This Zend_Db_Table_Select object.
170: */
171: public function from($name, $cols = self::SQL_WILDCARD, $schema = null)
172: {
173: if ($name instanceof Zend_Db_Table_Abstract) {
174: $info = $name->info();
175: $name = $info[Zend_Db_Table_Abstract::NAME];
176: if (isset($info[Zend_Db_Table_Abstract::SCHEMA])) {
177: $schema = $info[Zend_Db_Table_Abstract::SCHEMA];
178: }
179: }
180:
181: return $this->joinInner($name, null, $cols, $schema);
182: }
183:
184: /**
185: * Performs a validation on the select query before passing back to the parent class.
186: * Ensures that only columns from the primary Zend_Db_Table are returned in the result.
187: *
188: * @return string|null This object as a SELECT string (or null if a string cannot be produced)
189: */
190: public function assemble()
191: {
192: $fields = $this->getPart(Zend_Db_Table_Select::COLUMNS);
193: $primary = $this->_info[Zend_Db_Table_Abstract::NAME];
194: $schema = $this->_info[Zend_Db_Table_Abstract::SCHEMA];
195:
196:
197: if (count($this->_parts[self::UNION]) == 0) {
198:
199: // If no fields are specified we assume all fields from primary table
200: if (!count($fields)) {
201: $this->from($primary, self::SQL_WILDCARD, $schema);
202: $fields = $this->getPart(Zend_Db_Table_Select::COLUMNS);
203: }
204:
205: $from = $this->getPart(Zend_Db_Table_Select::FROM);
206:
207: if ($this->_integrityCheck !== false) {
208: foreach ($fields as $columnEntry) {
209: list($table, $column) = $columnEntry;
210:
211: // Check each column to ensure it only references the primary table
212: if ($column) {
213: if (!isset($from[$table]) || $from[$table]['tableName'] != $primary) {
214: require_once 'Zend/Db/Table/Select/Exception.php';
215: throw new Zend_Db_Table_Select_Exception('Select query cannot join with another table');
216: }
217: }
218: }
219: }
220: }
221:
222: return parent::assemble();
223: }
224: }