/** * @param string $key * @param array $options * @return mixed * @throws Exception */ public function getRelationLazy($key, $options = []) { /** @var \T4\Orm\Model $class */ $class = get_class($this); $relations = $class::getRelations(); if (empty($relations[$key])) { throw new Exception('No such column or relation: ' . $key . ' in model of ' . $class . ' class'); } $relation = $relations[$key]; switch ($relation['type']) { case $class::BELONGS_TO: /** @var \T4\Orm\Model $relationClass */ $relationClass = $relation['model']; $thisColumnName = $class::getRelationLinkName($relation); $thatColumnName = $class::getBelongsToThatLinkColumnName($relation); $subModel = $relationClass::findByColumn($thatColumnName, $this->{$thisColumnName}, $options); if (empty($subModel)) { return null; } else { return $subModel; } break; case $class::HAS_ONE: /** @var \T4\Orm\Model $relationClass */ $relationClass = $relation['model']; $thisColumnName = $class::getHasOneThisLinkColumnName($relation); $thatColumnName = $class::getRelationLinkName($relation); $subModel = $relationClass::findByColumn($thatColumnName, $this->{$thisColumnName}, $options); if (empty($subModel)) { return null; } else { return $subModel; } break; case $class::HAS_MANY: /** @var \T4\Orm\Model $relationClass */ $relationClass = $relation['model']; $thisColumnName = $class::getHasManyThisLinkColumnName($relation); $thatColumnName = $class::getRelationLinkName($relation); return $relationClass::findAllByColumn($thatColumnName, $this->{$thisColumnName}, $options); break; case $class::MANY_TO_MANY: /** @var \T4\Orm\Model $relationClass */ $relationClass = $relation['model']; $linkTable = $class::getRelationLinkName($relation); $pivots = $relationClass::getPivots($class, $key); if (!empty($pivots)) { $pivotColumnsSql = ', ' . implode(', ', array_map(function ($x) { return 'j1.' . $x; }, array_keys($pivots))); } else { $pivotColumnsSql = ''; } $query = new Query(); $query->select('t1.*' . $pivotColumnsSql)->from($relationClass::getTableName())->join($linkTable, 't1.' . $relationClass::PK . '=j1.' . static::getManyToManyThatLinkColumnName($relation), 'left')->where('(j1.' . static::getManyToManyThisLinkColumnName($relation) . '=:id)' . (isset($options['where']) ? ' AND (' . $options['where'] . ')' : '')); if (isset($options['order'])) { $query->order($options['order']); } $query->params([':id' => $this->getPk()]); /** @var \T4\Orm\Model $relationClass */ $result = $relationClass::getDbConnection()->query($query)->fetchAllObjects($relationClass); if (!empty($result)) { $ret = new Collection($result); $ret->setNew(false); return $ret; } else { return new Collection(); } } }
public function __call($method, $argv) { /** @var \T4\Orm\Model $model */ $model = $argv[0]; array_shift($argv); /* @var \T4\Orm\Model $class */ $class = get_class($model); $tableName = $class::getTableName(); /** @var \T4\Dbal\Connection $connection */ $connection = $class::getDbConnection(); switch ($method) { case 'refreshTreeColumns': $sql = (new Query())->select(['__lft', '__rgt', '__lvl', '__prt'])->from($tableName)->where($class::PK . '=:id')->params([':id' => $model->getPk()]); $columns = $connection->query($sql)->fetch(\PDO::FETCH_ASSOC); $model->merge($columns); return $model; case 'getTreeWidth': if ($model->isNew()) { return 1; } else { return $model->__rgt - $model->__lft; } case 'findAllParents': $query = new Query(); $query->select('*')->from($class::getTableName())->where('__lft<:lft AND __rgt>:rgt')->order('__lft')->params([':lft' => $model->__lft, ':rgt' => $model->__rgt]); return $class::findAllByQuery($query); case 'findAllChildren': $query = new Query(); $query->select('*')->from($class::getTableName())->where('__lft>:lft AND __rgt<:rgt')->order('__lft')->params([':lft' => $model->__lft, ':rgt' => $model->__rgt]); return $class::findAllByQuery($query); case 'hasChildren': $query = new Query(); $query->select('COUNT(*)')->from($class::getTableName())->where('__lft>:lft AND __rgt<:rgt')->order('__lft')->params([':lft' => $model->__lft, ':rgt' => $model->__rgt]); return 0 != $connection->query($query)->fetchScalar(); case 'findSubTree': $query = new Query(); $query->select('*')->from($class::getTableName())->where('__lft>=:lft AND __rgt<=:rgt')->order('__lft')->params([':lft' => $model->__lft, ':rgt' => $model->__rgt]); return $class::findAllByQuery($query); case 'hasPrevSibling': $query = new Query(); $query->select('COUNT(*)')->from($class::getTableName())->where('__rgt<:lft AND __prt=:prt')->params([':lft' => $model->__lft, ':prt' => $model->__prt]); return 0 != $connection->query($query)->fetchScalar(); case 'getPrevSibling': $query = new Query(); $query->select('*')->from($class::getTableName())->where('__rgt<:lft AND __prt=:prt')->order('__lft DESC')->limit(1)->params([':lft' => $model->__lft, ':prt' => $model->__prt]); return $class::findByQuery($query); case 'hasNextSibling': $query = new Query(); $query->select('COUNT(*)')->from($class::getTableName())->where('__lft>:rgt AND __prt=:prt')->params([':rgt' => $model->__rgt, ':prt' => $model->__prt]); return 0 != $connection->query($query)->fetchScalar(); case 'getNextSibling': $query = new Query(); $query->select('*')->from($class::getTableName())->where('__lft>:rgt AND __prt=:prt')->order('__lft')->limit(1)->params([':rgt' => $model->__rgt, ':prt' => $model->__prt]); return $class::findByQuery($query); case 'insertBefore': $element = $argv[0]; $this->insertModelBeforeElement($model, $element); return $model; break; case 'insertAfter': $element = $argv[0]; $this->insertModelAfterElement($model, $element); return $model; break; case 'moveToFirstPosition': $parent = $model->parent; if (empty($parent)) { $this->insertModelAsFirstRoot($model); } else { $this->insertModelAsFirstChildOf($model, $parent); } return $model; case 'moveToLastPosition': $parent = $model->parent; if (empty($parent)) { $this->insertModelAsLastRoot($model); } else { $this->insertModelAsLastChildOf($model, $parent); } return $model; } }
protected function getLastMigrationTime() { $query = new Query(); $query->select('time')->from(self::TABLE_NAME)->order(Model::PK . ' DESC')->limit(1); return $this->app->db->default->query($query)->fetchScalar() ?: 0; }
/** * @param string $class * @param string $column * @param mixed $value * @param array|\T4\Dbal\Query $options * @return int * @throws \T4\Dbal\Exception */ public function countAllByColumn($class, $column, $value, $options = []) { /** @var \T4\Orm\Model $class */ if ('mysql' != $class::getDbConnection()->getDriverName()) { throw new Exception('DB drivers mismatch'); } $query = new Query($options); $query->select('COUNT(*)')->from($this->quoteName($class::getTableName()))->where($this->quoteName($column) . '=:columnvalue' . (!empty($query->where) ? ' AND (' . $query->where . ')' : ''))->param(':columnvalue', $value); return (int) $class::getDbConnection()->query($query)->fetchScalar(); }