Select.php 6.5 KB

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