Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Select.php
Go to the documentation of this file.
1 <?php
6 namespace Magento\Framework\DB;
7 
10 
33 class Select extends \Zend_Db_Select
34 {
38  const TYPE_CONDITION = 'TYPE_CONDITION';
39 
43  const STRAIGHT_JOIN = 'straightjoin';
44 
48  const SQL_STRAIGHT_JOIN = 'STRAIGHT_JOIN';
49 
53  private $selectRenderer;
54 
63  public function __construct(
64  \Magento\Framework\DB\Adapter\Pdo\Mysql $adapter,
65  \Magento\Framework\DB\Select\SelectRenderer $selectRenderer,
66  $parts = []
67  ) {
68  self::$_partsInit = array_merge(self::$_partsInit, $parts);
69  if (!isset(self::$_partsInit[self::STRAIGHT_JOIN])) {
70  self::$_partsInit = [self::STRAIGHT_JOIN => false] + self::$_partsInit;
71  }
72 
73  $this->selectRenderer = $selectRenderer;
74  parent::__construct($adapter);
75  }
76 
109  public function where($cond, $value = null, $type = null)
110  {
111  if ($value === null && $type === null) {
112  $value = '';
113  } elseif ($type == self::TYPE_CONDITION) {
114  $type = null;
115  }
116  if (is_array($value)) {
117  $cond = $this->getConnection()->quoteInto($cond, $value);
118  $value = null;
119  }
120  return parent::where($cond, $value, $type);
121  }
122 
130  public function resetJoinLeft()
131  {
132  foreach ($this->_parts[self::FROM] as $tableId => $tableProp) {
133  if ($tableProp['joinType'] == self::LEFT_JOIN) {
134  $useJoin = false;
135  foreach ($this->_parts[self::COLUMNS] as $columnEntry) {
136  list($correlationName, $column) = $columnEntry;
137  if ($column instanceof \Zend_Db_Expr) {
138  if ($this->_findTableInCond(
139  $tableId,
140  $column
141  ) || $this->_findTableInCond(
142  $tableProp['tableName'],
143  $column
144  )
145  ) {
146  $useJoin = true;
147  }
148  } else {
149  if ($correlationName == $tableId) {
150  $useJoin = true;
151  }
152  }
153  }
154  foreach ($this->_parts[self::WHERE] as $where) {
155  if ($this->_findTableInCond(
156  $tableId,
157  $where
158  ) || $this->_findTableInCond(
159  $tableProp['tableName'],
160  $where
161  )
162  ) {
163  $useJoin = true;
164  }
165  }
166 
167  $joinUseInCond = $useJoin;
168  $joinInTables = [];
169 
170  foreach ($this->_parts[self::FROM] as $tableCorrelationName => $table) {
171  if ($tableCorrelationName == $tableId) {
172  continue;
173  }
174  if (!empty($table['joinCondition'])) {
175  if ($this->_findTableInCond(
176  $tableId,
177  $table['joinCondition']
178  ) || $this->_findTableInCond(
179  $tableProp['tableName'],
180  $table['joinCondition']
181  )
182  ) {
183  $useJoin = true;
184  $joinInTables[] = $tableCorrelationName;
185  }
186  }
187  }
188 
189  if (!$useJoin) {
190  unset($this->_parts[self::FROM][$tableId]);
191  } else {
192  $this->_parts[self::FROM][$tableId]['useInCond'] = $joinUseInCond;
193  $this->_parts[self::FROM][$tableId]['joinInTables'] = $joinInTables;
194  }
195  }
196  }
197 
198  $this->_resetJoinLeft();
199 
200  return $this;
201  }
202 
208  protected function _resetJoinLeft()
209  {
210  foreach ($this->_parts[self::FROM] as $tableId => $tableProp) {
211  if ($tableProp['joinType'] == self::LEFT_JOIN) {
212  if ($tableProp['useInCond']) {
213  continue;
214  }
215 
216  $used = false;
217  foreach ($tableProp['joinInTables'] as $table) {
218  if (isset($this->_parts[self::FROM][$table])) {
219  $used = true;
220  break;
221  }
222  }
223 
224  if (!$used) {
225  unset($this->_parts[self::FROM][$tableId]);
226  return $this->_resetJoinLeft();
227  }
228  }
229  }
230 
231  return $this;
232  }
233 
241  protected function _findTableInCond($table, $cond)
242  {
243  $quote = $this->_adapter->getQuoteIdentifierSymbol();
244 
245  if (strpos($cond, $quote . $table . $quote . '.') !== false) {
246  return true;
247  }
248 
249  $position = 0;
250  $result = 0;
251  $needle = [];
252  while (is_integer($result)) {
253  $result = strpos($cond, $table . '.', $position);
254 
255  if (is_integer($result)) {
256  $needle[] = $result;
257  $position = $result + strlen($table) + 1;
258  }
259  }
260 
261  if (!$needle) {
262  return false;
263  }
264 
265  foreach ($needle as $position) {
266  if ($position == 0) {
267  return true;
268  }
269  if (!preg_match('#[a-z0-9_]#is', substr($cond, $position - 1, 1))) {
270  return true;
271  }
272  }
273 
274  return false;
275  }
276 
293  protected function _join($type, $name, $cond, $cols, $schema = null)
294  {
295  if ($type == self::INNER_JOIN && empty($cond)) {
297  }
298  return parent::_join($type, $name, $cond, $cols, $schema);
299  }
300 
308  public function limit($count = null, $offset = null)
309  {
310  if ($count === null) {
311  $this->reset(self::LIMIT_COUNT);
312  } else {
313  $this->_parts[self::LIMIT_COUNT] = (int)$count;
314  }
315  if ($offset === null) {
316  $this->reset(self::LIMIT_OFFSET);
317  } else {
318  $this->_parts[self::LIMIT_OFFSET] = (int)$offset;
319  }
320  return $this;
321  }
322 
329  public function crossUpdateFromSelect($table)
330  {
331  return $this->getConnection()->updateFromSelect($this, $table);
332  }
333 
342  public function insertFromSelect($tableName, $fields = [], $onDuplicate = true)
343  {
344  $mode = $onDuplicate ? AdapterInterface::INSERT_ON_DUPLICATE : false;
345  return $this->getConnection()->insertFromSelect($this, $tableName, $fields, $mode);
346  }
347 
356  {
357  return $this->getConnection()->insertFromSelect($this, $tableName, $fields, AdapterInterface::INSERT_IGNORE);
358  }
359 
366  public function deleteFromSelect($table)
367  {
368  return $this->getConnection()->deleteFromSelect($this, $table);
369  }
370 
379  public function setPart($part, $value)
380  {
381  $part = strtolower($part);
382  if (!array_key_exists($part, $this->_parts)) {
383  throw new \Zend_Db_Select_Exception("Invalid Select part '{$part}'");
384  }
385  $this->_parts[$part] = $value;
386  return $this;
387  }
388 
395  public function useStraightJoin($flag = true)
396  {
397  $this->_parts[self::STRAIGHT_JOIN] = (bool)$flag;
398  return $this;
399  }
400 
407  protected function _renderStraightjoin($sql)
408  {
409  if ($this->_adapter->supportStraightJoin() && !empty($this->_parts[self::STRAIGHT_JOIN])) {
410  $sql .= ' ' . self::SQL_STRAIGHT_JOIN;
411  }
412 
413  return $sql;
414  }
415 
426  protected function _tableCols($correlationName, $cols, $afterCorrelationName = null)
427  {
428  if (!is_array($cols)) {
429  $cols = [$cols];
430  }
431 
432  foreach ($cols as $k => $v) {
433  if ($v instanceof Select) {
434  $cols[$k] = new \Zend_Db_Expr(sprintf('(%s)', $v->assemble()));
435  }
436  }
437 
438  return parent::_tableCols($correlationName, $cols, $afterCorrelationName);
439  }
440 
447  public function orderRand($field = null)
448  {
449  $this->_adapter->orderRand($this, $field);
450  return $this;
451  }
452 
459  protected function _renderForupdate($sql)
460  {
461  if ($this->_parts[self::FOR_UPDATE]) {
462  $sql = $this->_adapter->forUpdate($sql);
463  }
464 
465  return $sql;
466  }
467 
476  public function exists($select, $joinCondition, $isExists = true)
477  {
478  if ($isExists) {
479  $exists = 'EXISTS (%s)';
480  } else {
481  $exists = 'NOT EXISTS (%s)';
482  }
483  $select->reset(self::COLUMNS)->columns([new \Zend_Db_Expr('1')])->where($joinCondition);
484 
485  $exists = sprintf($exists, $select->assemble());
486 
487  $this->where($exists);
488  return $this;
489  }
490 
496  public function getConnection()
497  {
498  return $this->_adapter;
499  }
500 
507  public function assemble()
508  {
509  return $this->selectRenderer->render($this);
510  }
511 
516  public function __sleep()
517  {
518  $properties = array_keys(get_object_vars($this));
519  $properties = array_diff(
520  $properties,
521  [
522  '_adapter',
523  'selectRenderer'
524  ]
525  );
526  return $properties;
527  }
528 
535  public function __wakeup()
536  {
538  $this->_adapter = $objectManager->get(ResourceConnection::class)->getConnection();
539  $this->selectRenderer = $objectManager->get(\Magento\Framework\DB\Select\SelectRenderer::class);
540  }
541 }
$tableName
Definition: trigger.php:13
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$objectManager
Definition: bootstrap.php:17
static $_partsInit
Definition: Select.php:126
exists($select, $joinCondition, $isExists=true)
Definition: Select.php:476
_join($type, $name, $cond, $cols, $schema=null)
Definition: Select.php:293
$count
Definition: recent.phtml:13
$quote
useStraightJoin($flag=true)
Definition: Select.php:395
$fields
Definition: details.phtml:14
orderRand($field=null)
Definition: Select.php:447
insertFromSelect($tableName, $fields=[], $onDuplicate=true)
Definition: Select.php:342
__construct(\Magento\Framework\DB\Adapter\Pdo\Mysql $adapter, \Magento\Framework\DB\Select\SelectRenderer $selectRenderer, $parts=[])
Definition: Select.php:63
const FROM
Definition: Select.php:49
$adapter
Definition: webapi_user.php:16
$type
Definition: item.phtml:13
reset($part=null)
Definition: Select.php:742
$value
Definition: gender.phtml:16
where($cond, $value=null, $type=null)
Definition: Select.php:109
if($exist=($block->getProductCollection() && $block->getProductCollection() ->getSize())) $mode
Definition: grid.phtml:15
const LIMIT_OFFSET
Definition: Select.php:56
limit($count=null, $offset=null)
Definition: Select.php:308
_findTableInCond($table, $cond)
Definition: Select.php:241
const CROSS_JOIN
Definition: Select.php:63
insertIgnoreFromSelect($tableName, $fields=[])
Definition: Select.php:355
$properties
Definition: categories.php:26
setPart($part, $value)
Definition: Select.php:379
$table
Definition: trigger.php:14
_tableCols($correlationName, $cols, $afterCorrelationName=null)
Definition: Select.php:426
const LIMIT_COUNT
Definition: Select.php:55
if(!isset($_GET['name'])) $name
Definition: log.php:14