public function init() { parent::init(); $view = $this->getView(); $module = Yii::$app->getModule("versioning"); $user_id = Yii::$app->user->id; $groups = \amilna\versioning\components\Libs::userGroups($user_id); $groups = [1]; $bundle = NotificationAsset::register($view); $this->bundle = $bundle; $searchModel = new VersionSearch(); $dataProvider = $searchModel->search([]); $query = $dataProvider->query; $query->andWhere([Version::tableName() . ".status" => true])->andWhere(Record::tableName() . ".record_id is not null"); if (count($this->models) > 0) { $query->andWhere([Record::tableName() . ".model" => $this->models])->andWhere(Record::tableName() . ".filter_viewers = false"); } if ($user_id > 0) { $query->andWhere("concat(','," . Record::tableName() . ".viewers,',') not like '%," . $user_id . ",%'")->andWhere(Record::tableName() . ".filter_viewers = false OR (" . Record::tableName() . ".filter_viewers = true AND (" . Record::tableName() . ".owner_id = :uid OR " . Record::tableName() . ".group_id in (" . implode(",", $groups) . ")) )", [":uid" => $user_id]); } else { $query->limit(10); } $query->orderBy(Route::tableName() . ".time DESC," . Version::tableName() . ".id DESC"); $script = "\t\t\n\t\t" . PHP_EOL; $view->registerJs($script); echo $this->render($this->viewPath, ['searchModel' => $searchModel, 'dataProvider' => $dataProvider, 'module' => $module, 'widget' => $this]); }
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; }
/** * @return \yii\db\ActiveQuery */ public function getRoute() { return $this->hasOne(Route::className(), ['id' => 'route_id']); }
/** * Creates data provider instance with search query applied * * @param array $params * * @return ActiveDataProvider */ public function search($params) { $query = $this->find(); $query->joinWith(['record', 'route', 'route.user']); $dataProvider = new ActiveDataProvider(['query' => $query]); $userClass = Yii::$app->getModule('versioning')->userClass; /* uncomment to sort by relations table on respective column */ $dataProvider->sort->attributes['recordModel'] = ['asc' => ['concat(' . Record::tableName() . '.model,' . Record::tableName() . '.id)' => SORT_ASC], 'desc' => ['concat(' . Record::tableName() . '.model,' . Record::tableName() . '.id)' => SORT_DESC]]; $dataProvider->sort->attributes['time'] = ['asc' => ['' . Route::tableName() . '.time' => SORT_ASC], 'desc' => ['' . Route::tableName() . '.time' => SORT_DESC]]; $dataProvider->sort->attributes['routeUser'] = ['asc' => [$userClass::tableName() . '.username' => SORT_ASC], 'desc' => [$userClass::tableName() . '.username' => SORT_DESC]]; if (!($this->load($params) && $this->validate())) { return $dataProvider; } $query->andFilterWhere(['status' => $this->status]); $params = self::queryNumber([['id', $this->tableName()], ['route_id'], ['record_id'], ['type'], ['isdel']]); foreach ($params as $p) { $query->andFilterWhere($p); } $params = self::queryString([['record_attributes']]); foreach ($params as $p) { $query->andFilterWhere($p); } $params = self::queryTime([['time', Route::tableName()]]); foreach ($params as $p) { $query->andFilterWhere($p); } $query->andFilterWhere(["like", "lower(concat(" . Record::tableName() . ".model,' '," . Record::tableName() . ".record_id))", strtolower($this->recordModel)]); $query->andFilterWhere(['like', 'lower(' . $userClass::tableName() . '.username)', strtolower($this->routeUser)]); /* example to use search all in field1,field2,field3 or field4 */ //print_r(self::mkArrQuery([["OR","lower(field1) like '%".strtolower($this->recordModel)."%'"],["OR","lower(field2) like '%".strtolower($this->recordModel)."%'"]])); //die(); /* if ($this->term) { $query->andFilterWhere(["OR","lower(field1) like '%".strtolower($this->term)."%'", ["OR","lower(field2) like '%".strtolower($this->term)."%'", ["OR","lower(field3) like '%".strtolower($this->term)."%'", "lower(field4) like '%".strtolower($this->term)."%'" ] ] ]); } */ return $dataProvider; }