示例#1
0
 /**
  * Return condition for select for a single model;
  * @param DbModel $model
  * @return ModelCondition
  */
 public function getConditionForModel(DbModel $model)
 {
     $mCondition = new ModelCondition(['model' => $this->model]);
     $joinString = [];
     $joinParams = [];
     foreach ($this->joins as $join) {
         if (is_array($join[0])) {
             $cJoinString = $join[3] . " `" . key($join[0]) . "` as `" . current($join[0]) . '`';
             $tName = "`" . current($join[0]) . "`";
         } else {
             $cJoinString = $join[3] . " `" . $join[0] . "`";
             $tName = $join[0];
         }
         $cJoinString .= " ON ";
         $cJoinConditions = [];
         foreach ($join[1] as $column1 => $column2) {
             // c1 -> from parent; c2 -> from table;
             if (false === strpos($column1, '.')) {
                 // is parent here
                 $joinParams[":t_" . $column1] = $model->{$column1};
                 $column1 = ":t_" . $column1;
             }
             if (false === strpos($column2, '.')) {
                 $column2 = $tName . '.' . $column2;
             }
             $cJoinConditions[] = $column1 . ' = ' . $column2;
         }
         foreach ($join[2] as $column => $value) {
             $pName = ':';
             if (false === strpos($column, '.')) {
                 $pName .= str_replace('.', '_', "{$tName}.{$column}");
                 $cJoinConditions[] = "`{$tName}`.`{$column}` = :{$pName}";
             } else {
                 $pName .= str_replace('.', '_', $column);
                 $cJoinConditions[] = "{$column} = :{$pName}";
             }
             $joinParams[$pName] = $value;
         }
         $joinString[] = $cJoinString . "(" . implode(") AND (", $cJoinConditions) . ")";
     }
     if ($this->joins) {
         $mCondition->fields = "t.*";
     }
     $mCondition->setParams($joinParams);
     $mCondition->join = implode(" ", $joinString);
     foreach ($this->conditions as $ck => $condition) {
         switch ($condition[0]) {
             case "=":
             case "!=":
                 $parentColumn = $condition[1];
                 // for now it only supports single column for this type of relations;
                 $relationColumn = $condition[2];
                 // same for relation column
                 if (false !== strpos($parentColumn, '.')) {
                     if (false === strpos($relationColumn, '.')) {
                         $relationColumn = '`t`.`' . $relationColumn . '`';
                     }
                     $mCondition->addCondition("{$parentColumn} = {$relationColumn}");
                 } else {
                     if (is_array($relationColumn)) {
                         $relationColumnListForIn = [];
                         foreach ($relationColumn as $c) {
                             $relationColumnListForIn[] = $this->_column($c, true);
                         }
                         $relationColumnListForIn = implode(', ', $relationColumnListForIn);
                     } else {
                         $relationColumnListForIn = $relationColumn;
                     }
                     $conditionParts = [];
                     $paramKey = ':' . $ck . '_';
                     if (is_array($parentColumn) && is_array($relationColumn)) {
                         $columnList = [];
                         foreach ($parentColumn as $col) {
                             $mCondition->setParam($paramKey . $col, $model->{$col});
                             $conditionParts[] = $paramKey . $col . ('!=' == $condition[0] ? 'NOT' : '') . ' IN ( ' . $relationColumnListForIn . ' )';
                             $columnList[] = $paramKey . $col . ('!=' == $condition[0] ? 'NOT' : '') . ' IN ( ' . $relationColumnListForIn . ' )';
                         }
                     } elseif (is_array($parentColumn)) {
                         $paramList = [];
                         foreach ($parentColumn as $col) {
                             $mCondition->setParam($paramKey . $col, $model->{$col});
                             $paramList[] = $paramKey . $col;
                         }
                         $conditionParts[] = $this->_column($relationColumn, true) . ('!=' == $condition[0] ? 'NOT' : '') . ' IN (' . implode(', ', $paramList) . ')';
                     } elseif (is_array($relationColumn)) {
                         $mCondition->setParam($paramKey . $parentColumn, $model->{$parentColumn});
                         $conditionParts[] = $paramKey . $parentColumn . ('!=' == $condition[0] ? 'NOT' : '') . " IN ({$relationColumnListForIn})";
                     } else {
                         if (false !== strpos($parentColumn, '.')) {
                             $mCondition->compareColumns($paramKey . $relationColumn, $parentColumn);
                         } else {
                             $mCondition->setParam($paramKey . $relationColumn, $model->{$parentColumn});
                             $conditionParts[] = $paramKey . $relationColumn;
                         }
                     }
                     if (is_string($parentColumn) && is_string($relationColumn)) {
                         $mCondition->addCondition($this->_column($relationColumn, true) . ('!=' == $condition[0] ? 'NOT' : '') . " IN (" . implode(', ', $conditionParts) . ")");
                     } else {
                         $mCondition->addCondition('(' . implode(") OR (", $conditionParts) . ')');
                     }
                 }
                 break;
             case "==":
             case "=attribute":
                 if ($condition[0] == '=attribute') {
                     // for attribute read the value
                     $parentModel = get_class($model);
                     $c = $condition[2];
                     if (false === strpos($c, '(')) {
                         $condition[2] = $parentModel::${$c};
                     } else {
                         // for method call it and get the value;
                         $c = substr($c, 0, strlen($c) - 2);
                         $condition[2] = call_user_func("{$parentModel}::{$c}");
                     }
                 }
                 $mCondition->compareColumn($condition[1], $condition[2]);
                 break;
         }
     }
     if ($this->order) {
         $mCondition->order = $this->order;
     }
     if ($this->offset) {
         $mCondition->offset = $this->offset;
     }
     if ($this->limit) {
         $mCondition->limit = $this->limit;
     }
     return $mCondition;
 }