namespace app\controllers;
+use Throwable;
use Yii;
use yii_app\records\MatrixType;
use yii\data\ActiveDataProvider;
public function actionToggleActive()
{
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
- $id = Yii::$app->request->post('id');
- $active = Yii::$app->request->post('active');
+ $id = (int) Yii::$app->request->post('id');
+ $active = (int) Yii::$app->request->post('active');
$model = $this->findModel($id);
if (!$model) {
return ['success' => false, 'message' => 'Не найдено'];
}
- $model->active = (int)$active;
- if ($model->save(false)) {
+ $db = Yii::$app->db;
+ $transaction = $db->beginTransaction();
+
+ try {
+ $model->active = $active;
+ if (!$model->save(false)) {
+ throw new \RuntimeException('Не удалось сохранить узел');
+ }
+
+ if ($active === 0 && empty($model->parent_id)) {
+ $this->deactivateChildren($model);
+ }
+
+ $transaction->commit();
return ['success' => true];
+
+ } catch (Throwable $e) {
+ $transaction->rollBack();
+ Yii::error($e->getMessage(), 'matrix-type.toggle-active');
+ return ['success' => false, 'message' => 'Ошибка при сохранении'];
+ }
+ }
+
+ protected function deactivateChildren(MatrixType $parent): void
+ {
+ $children = MatrixType::find()
+ ->where(['parent_id' => $parent->id])
+ ->all();
+
+ foreach ($children as $child) {
+ if ($child->active != 0) {
+ $child->active = 0;
+ if(!$child->save()) {
+ Yii::error("Ошибка сохранения " . json_encode($child->getErrors(), JSON_UNESCAPED_UNICODE));
+ }
+ }
+ $this->deactivateChildren($child);
}
- return ['success' => false, 'message' => 'Не удалось сохранить'];
}
+
/**
* Deletes an existing MatrixType model.
* If deletion is successful, the browser will be redirected to the 'index' page.
$model->delete();
}
+ public function actionSoftDelete($id)
+ {
+ $model = $this->findModel($id);
+ if (!$model) {
+ return $this->redirect(['index']);
+ }
+
+ $db = Yii::$app->db;
+ $transaction = $db->beginTransaction();
+
+ try {
+ $now = date('Y-m-d H:i:s');
+ $uid = Yii::$app->user->id ?? null;
+
+ $this->markDeleted($model, $uid, $now);
+
+ if (empty($model->parent_id)) {
+ $this->markDeletedChildren($model, $uid, $now);
+ }
+
+ $transaction->commit();
+ return $this->redirect(['index']);
+ } catch (\Throwable $e) {
+ $transaction->rollBack();
+ Yii::error($e->getMessage(), 'matrix-type.soft-delete');
+ return $this->redirect(['index']);
+ }
+ }
+
+ protected function markDeleted(MatrixType $matrixType, $uid, $now): void
+ {
+ if (!empty($matrixType->deleted_at)) return;
+
+ $result = $matrixType->updateAttributes([
+ 'deleted_by' => $uid,
+ 'deleted_at' => $now,
+ 'active' => 0,
+ ]);
+ if ($result === false) {
+ Yii::error("Ошибка сохранения " . json_encode($matrixType->getErrors(), JSON_UNESCAPED_UNICODE));
+ throw new \RuntimeException("Не удалось пометить удалённым ID={$matrixType->id}");
+ }
+ }
+
+ protected function markDeletedChildren(MatrixType $parent, $uid, $now): void
+ {
+ $children = MatrixType::find()
+ ->where(['parent_id' => $parent->id])
+ ->all();
+
+ foreach ($children as $child) {
+ $this->markDeleted($child, $uid, $now);
+ $this->markDeletedChildren($child, $uid, $now);
+ }
+ }
+
+
/**
* Finds the MatrixType model based on its primary key value.
* @param int $id
*/
protected function findModel($id)
{
- if (($model = MatrixType::findOne($id)) !== null) {
+ if (($model = MatrixType::find()->where(['id' => $id])->andWhere(['deleted_at' => null])->one()) !== null) {
return $model;
}
$this->tinyInteger()->notNull()->defaultValue(1)->comment('активность')
);
}
+ if (!$this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('deleted_by')) {
+ $this->addColumn(
+ self::TABLE_NAME,
+ 'deleted_by',
+ $this->integer()->null()->comment('Кем удалено - id пользователя')
+ );
+ }
+ if (!$this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('deleted_at')) {
+ $this->addColumn(
+ self::TABLE_NAME,
+ 'deleted_at',
+ $this->timestamp()->defaultValue(null)->comment('дата удаления')
+ );
+ }
}
/**
if ($this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('active')) {
$this->dropColumn(self::TABLE_NAME, 'active');
}
+ if ($this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('deleted_by')) {
+ $this->dropColumn(self::TABLE_NAME, 'deleted_by');
+ }
+ if ($this->db->schema->getTableSchema(self::TABLE_NAME, true)->getColumn('deleted_at')) {
+ $this->dropColumn(self::TABLE_NAME, 'deleted_at');
+ }
}
/*