/** * TODO: много лишних isset, которые всегда true по определению * Сохранение полей модели без учета связей, требующих ID модели * @param Model $model * @return Model */ protected function saveColumns(Model $model) { $class = get_class($model); $columns = $class::getColumns(); $relations = $class::getRelations(); $cols = []; $sets = []; $data = []; foreach ($columns as $column => $def) { if (isset($model->{$column}) && !is_null($model->{$column})) { $cols[] = $column; $sets[$column] = ':' . $column; $data[':' . $column] = $model->{$column}; } elseif (isset($def['default'])) { $sets[$column] = ':' . $column; $data[':' . $column] = $def['default']; } } foreach ($relations as $rel => $def) { switch ($def['type']) { case $class::BELONGS_TO: $column = $class::getRelationLinkName($def); if (!in_array($column, $cols)) { if (isset($model->{$column}) && !is_null($model->{$column})) { $sets[$column] = ':' . $column; $data[':' . $column] = $model->{$column}; } elseif (isset($model->{$rel}) && $model->{$rel} instanceof Model) { $sets[$column] = ':' . $column; $data[':' . $column] = $model->{$rel}->getPk(); } } break; } } $connection = $class::getDbConnection(); if ($model->isNew()) { $sql = new QueryBuilder(); $sql->insert($class::getTableName())->values($sets); $connection->execute($sql, $data); $model->{$class::PK} = $connection->lastInsertId(); } else { $sql = new QueryBuilder(); $sql->update($class::getTableName())->values($sets)->where($class::PK . '=' . $model->getPk()); $connection->execute($sql, $data); } return $model; }
/** * Создает пустое место в дереве заданной ширины * Место создается ВНУТРИ элемента с заданным rgt как ПОСЛЕДНИЙ его потомок * @param \T4\Dbal\Connection $connection * @param string $table * @param int $rgt * @param int $width */ protected function expandTreeBeforeRgt(Connection $connection, $table, $rgt, $width) { $query = new QueryBuilder(); $query->update()->table($table)->values(['__lft' => 'CASE WHEN __lft>=:rgt THEN __lft + (:width + 1) ELSE __lft END', '__rgt' => 'CASE WHEN __rgt>=:rgt THEN __rgt + (:width + 1) ELSE __rgt END'])->where('__lft>=:rgt OR __rgt>=:rgt')->order('__lft DESC'); $query->params([':rgt' => $rgt, ':width' => $width]); $connection->execute($query); }
/** * Подготовка модели к вставке в дерево в качестве последнего корня * @param \T4\Orm\Model $model */ protected function insertModelAsLastRoot(Model &$model) { /** @var \T4\Orm\Model $class */ $class = get_class($model); $tableName = $class::getTableName(); /** @var \T4\Dbal\Connection $connection */ $connection = $class::getDbConnection(); $query = new QueryBuilder(); $query->select('MAX(__rgt)')->from($tableName); $maxRgt = (int) $connection->query($query)->fetchScalar(); if ($model->isNew()) { $model->__lft = $maxRgt + 1; $model->__rgt = $model->__lft + 1; $model->__lvl = 0; $model->__prt = 0; } else { $query = new QueryBuilder(); $query->update()->table($tableName)->values(['__lft' => '__lft + :max - :lft + 1', '__rgt' => '__rgt + :max - :lft + 1', '__lvl' => '__lvl - :lvl'])->where('__lft>=:lft AND __rgt<=:rgt'); $query->params([':max' => $maxRgt, ':lft' => $model->__lft, ':rgt' => $model->__rgt, ':lvl' => $model->__lvl]); $connection->execute($query); $this->removeFromTreeByElement($model); // TODO: calculate new __lft, __rgt! $model->refreshTreeColumns(); $model->__lvl = 0; $model->__prt = 0; } }