public function bootstrap($app) { $events = [Controller::EVENT_BEFORE_ACTION]; foreach ($events as $eventName) { Event::on(Controller::className(), $eventName, function ($event) use($app, $eventName) { Libs::mkView($app, $eventName, $event); }); } $events = [ActiveRecord::EVENT_AFTER_INSERT, ActiveRecord::EVENT_BEFORE_UPDATE, ActiveRecord::EVENT_BEFORE_DELETE]; $res0 = false; foreach ($events as $eventName) { Event::on(ActiveRecord::className(), $eventName, function ($event) use($app, $eventName) { $model = $event->sender; $res0 = Libs::mkVersion($app, $eventName, $model); }); } if ($res0) { $events = [ActiveRecord::EVENT_AFTER_UPDATE, ActiveRecord::EVENT_AFTER_DELETE]; foreach ($events as $eventName) { Event::on(ActiveRecord::className(), $eventName, function ($event) use($app, $eventName, $res0) { $res = true; $model = $event->sender; foreach ($model->attributes as $a => $v) { $m = $res0[1]; if ($eventName == ActiveRecord::EVENT_AFTER_UPDATE) { $res = $m[$a] != $v ? false : $res; } elseif ($eventName == ActiveRecord::EVENT_AFTER_DELETE) { $res = $m[$a] != null ? false : $res; } } if (!$res) { $route = Route::findOne($res0[0]); if ($route) { $route->delete(); } } }); } } }
public static function mkVersion($app, $eventName, $model, $routeString = false) { $module = $app->getModule("versioning"); $nomodels = array_merge(['amilna\\versioning\\models\\Record', 'amilna\\versioning\\models\\Version', 'amilna\\versioning\\models\\Route'], $module->nomodels); $noroutes = array_merge(['versioning/version/apply'], $module->noroutes); $onmodels = $module->onmodels; $onroutes = $module->onroutes; $modname = self::arrItemIn(get_class($model), $nomodels, $nomodels[0]); $rotname = self::arrItemIn($app->requestedRoute, $noroutes, $noroutes[0]); if (count($onmodels) > 0 || count($onroutes) > 0) { $cekmod = true; if (count($onmodels) > 0) { $onmodname = self::arrItemIn(get_class($model), $onmodels, $onmodels[0]); $cekmod = in_array($onmodname, $onmodels); } $cekrot = true; if (count($onroutes) > 0) { $onrotname = self::arrItemIn($app->requestedRoute, $onroutes, $onroutes[0]); $cekrot = in_array($onrotname, $onroutes); } if (count($onmodels) > 0 && count($onroutes) > 0) { $stat = ($cekmod || $cekrot) && (!in_array($modname, $nomodels) && !in_array($rotname, $noroutes)); } else { $stat = $cekmod && $cekrot && (!in_array($modname, $nomodels) && !in_array($rotname, $noroutes)); } if ($stat) { $modname = get_class($model); $rotname = $app->requestedRoute; } } else { $stat = !in_array($modname, $nomodels) && !in_array($rotname, $noroutes); } $res = true; if ($stat) { $version = new Version(); if ($version->itemAlias("type", $eventName, true) == 1) { $arr = $model->attributes; $atr = json_encode($arr); } elseif ($version->itemAlias("type", $eventName, true) == 0) { $atr = null; } else { $arr = self::verObj($model->oldAttributes, $model->attributes); $atr = json_encode($arr); } if ($atr != "[]") { $transaction = $app->db->beginTransaction(); try { if ($app->user->isGuest) { $param = $app->request->queryParams; if (isset($param['asusername'])) { $userClass = $module->userClass; $user = $userClass::findOne(["username" => $param['asusername']]); if ($user) { $user_id = $user->id; $app->session->set('asuserid', $user_id); $cookie = new \yii\web\Cookie(['name' => 'asuserid', 'value' => $user_id]); $cookie->expire = time() + 60 * 60 * 24 * 365; // (1 year) $app->response->cookies->add($cookie); } else { $user_id = null; } } else { if ($app->session->has('asuserid')) { $user_id = $app->session->get('asuserid'); } else { if (isset($app->request->cookies['asuserid'])) { $user_id = $app->request->cookies['asuserid']->value; } else { $user_id = null; } } } } else { $user_id = $app->user->id; } $time = date("Y-m-d H:i:s", $_SERVER["REQUEST_TIME"]); $r = !$routeString ? $rotname : $routeString; $rid = $model->getPrimaryKey(); $rid = empty($rid) || !is_int($rid) ? null : $rid; $record = Record::findOne(["model" => $modname, "record_id" => $rid]); if (!$record) { $record = new Record(); $record->model = $modname; if ($rid != null) { $record->record_id = $rid; } $record->owner_id = $user_id; } $record->viewers = implode(",", [$user_id]); $res = !$record->save() ? false : $res; $route = Route::findOne(["route" => $r, "time" => $time, "user_id" => $user_id]); if (!$route) { $route = new Route(); $route->route = $r; $route->user_id = $user_id; $route->time = $time; $res = !$route->save() ? false : $res; } $origin = Version::findOne(["record_id" => $record->id, "status" => true]); if ($version->itemAlias("type", $eventName, true) != 1) { $br = str_replace(basename($r), "", $r) . $module->defaults["create"]; if ($rid != null && !$origin) { $version0 = new Version(); $version0->record_attributes = json_encode($model->oldAttributes); $version0->isdel = 0; $version0->record_id = $record->id; $version0->route_id = $route->id; $version0->type = 1; $version0->status = false; $version0->makeRoot(); $res = !$version0->save() ? false : $res; $version->prependTo($version0); } elseif ($rid == null) { $eventName = $version->itemAlias("type", 1); $arr = $model->attributes; $atr = json_encode($arr); } } $version->record_attributes = $atr; if ($rid == null) { $origin = Version::findOne(["route_id" => $route->id, "record_id" => $record->id, "record_attributes" => $atr]); if (!$origin) { $recs = Version::findAll(["record_id" => $record->id]); foreach ($recs as $r) { $sql = ""; $key = []; foreach (json_decode($r->record_attributes) as $a => $v) { $sql .= ($sql == "" ? "" : " AND ") . $a . ($v === null ? " is null" : " = :" . $a); if ($v !== null) { $key[":" . $a] = $v; } } $rmod = $modname::find()->where($sql, $key)->one(); $rts = $r->route_ids == null ? [] : json_decode($r->route_ids); if (!$rmod) { if (($rts_key = array_search($route->id, $rts)) !== false) { unset($rts[$rts_key]); } } else { array_push($rts, $route->id); } $r->route_id = $route->id; $r->route_ids = json_encode(array_unique($rts)); $r->type = $rmod ? 1 : 0; $r->save(); if ($r->record_attributes . "" == $atr) { $version = $r; } } } else { $version = $origin; $origin = false; } $rts = $version->route_ids == null ? [] : json_decode($version->route_ids); array_push($rts, $route->id); $version->route_ids = json_encode(array_unique($rts)); } $version->isdel = 0; $version->record_id = $record->id; $version->route_id = $route->id; $version->type = $version->itemAlias("type", $eventName, true); if ($version->type == 1 && !$origin && !$version->isRoot()) { $version->makeRoot(); } else { if ($origin) { $version->prependTo($origin); $origin->status = false; } } if ($origin) { $res = !$origin->save() ? false : $res; } $res = !$version->save() ? false : $res; if ($res) { $transaction->commit(); $res = [$route->id, $model->attributes]; } else { $transaction->rollBack(); } } catch (Exception $e) { $transaction->rollBack(); $res = false; } } } return $res; }