public function afterDelete(Model &$model) { $class = get_class($model); $relations = $class::getRelations(); foreach ($relations as $name => $relation) { switch ($relation['type']) { case Model::MANY_TO_MANY: $linkTable = $class::getRelationLinkName($relation); $query = new QueryBuilder(); $query->delete()->table($linkTable)->where($class::getManyToManyThisLinkColumnName() . '=:id'); $query->params([':id' => $model->getPk()]); $class::getDbConnection()->execute($query); } } return true; }
/** * Создает пустое место в дереве заданной ширины * Место создается ВНУТРИ элемента с заданным 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 string $key * @param array $options * @return mixed * @throws Exception */ public function getRelationLazy($key, $options = []) { $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: $relationClass = $relation['model']; $link = $class::getRelationLinkName($relation); $subModel = $relationClass::findByPK($this->{$link}); if (empty($subModel)) { return null; } else { return $relationClass::findByPK($this->{$link}); } break; case $class::HAS_ONE: $relationClass = $relation['model']; $link = $class::getRelationLinkName($relation); return $relationClass::findByColumn($link, $this->getPk(), $options); break; case $class::HAS_MANY: $relationClass = $relation['model']; $link = $class::getRelationLinkName($relation); return $relationClass::findAllByColumn($link, $this->getPk(), $options); break; case $class::MANY_TO_MANY: $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 QueryBuilder(); $query->select('t1.*' . $pivotColumnsSql)->from($relationClass::getTableName())->join($linkTable, 't1.' . $relationClass::PK . '=j1.' . static::getManyToManyThatLinkColumnName($relation), 'right')->where('(j1.' . static::getManyToManyThisLinkColumnName() . '=:id)' . (isset($options['where']) ? ' AND (' . $options['where'] . ')' : '')); if (isset($options['order'])) { $query->order($options['order']); } $query->params([':id' => $this->getPk()]); $result = $relationClass::getDbConnection()->query($query)->fetchAll(\PDO::FETCH_CLASS, $relationClass); if (!empty($result)) { $ret = new Collection($result); $ret->setNew(false); return $ret; } else { return new Collection(); } } }
/** * Удаление узла дерева * В данном методе удаляются все его подузлы * @param \T4\Orm\Model $model * @return bool */ public function afterDelete(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->delete()->table($tableName)->where('__lft>:lft AND __rgt<:rgt'); $query->params([':lft' => $model->__lft, ':rgt' => $model->__rgt]); $connection->execute($query); $this->removeFromTreeByLftRgt($connection, $tableName, $model->__lft, $model->__rgt); $model->__lft = 0; $model->__rgt = 0; $model->__lvl = 0; $model->__prt = 0; }