Commit fd238f57919408dbd91ae5d9d5c8fe4cddaaed7f
1 parent
93c267f7
Admin begin refactor.
Showing
8 changed files
with
257 additions
and
115 deletions
Show diff stats
backend/controllers/ArticlesController.php
... | ... | @@ -9,7 +9,6 @@ |
9 | 9 | use yii\web\NotFoundHttpException; |
10 | 10 | use yii\filters\VerbFilter; |
11 | 11 | use developeruz\db_rbac\behaviors\AccessBehavior; |
12 | - use yii\web\UploadedFile; | |
13 | 12 | |
14 | 13 | /** |
15 | 14 | * ArticlesController implements the CRUD actions for Articles model. |
... | ... | @@ -86,18 +85,12 @@ |
86 | 85 | $model_langs = $model->generateLangs(); |
87 | 86 | if($model->load(Yii::$app->request->post())) { |
88 | 87 | $model->loadLangs(\Yii::$app->request, $model_langs); |
89 | - if($model->save()) { | |
90 | - if($model->linkLangs($model_langs) && $model->saveLangs($model_langs)) { | |
91 | - return $this->redirect([ | |
92 | - 'view', | |
93 | - 'id' => $model->id, | |
94 | - ]); | |
95 | - } else { | |
96 | - return $this->redirect([ | |
97 | - 'update', | |
98 | - 'id' => $model->id, | |
99 | - ]); | |
100 | - } | |
88 | + $model->model_langs = $model_langs; | |
89 | + if($model->save() && $model->transactionStatus) { | |
90 | + return $this->redirect([ | |
91 | + 'view', | |
92 | + 'id' => $model->id, | |
93 | + ]); | |
101 | 94 | } |
102 | 95 | } |
103 | 96 | return $this->render('create', [ |
... | ... | @@ -120,13 +113,12 @@ |
120 | 113 | $model_langs = $model->generateLangs(); |
121 | 114 | if($model->load(Yii::$app->request->post())) { |
122 | 115 | $model->loadLangs(\Yii::$app->request, $model_langs); |
123 | - if($model->save()) { | |
124 | - if($model->linkLangs($model_langs) && $model->saveLangs($model_langs)) { | |
125 | - return $this->redirect([ | |
126 | - 'view', | |
127 | - 'id' => $model->id, | |
128 | - ]); | |
129 | - } | |
116 | + $model->model_langs = $model_langs; | |
117 | + if($model->save() && $model->transactionStatus) { | |
118 | + return $this->redirect([ | |
119 | + 'view', | |
120 | + 'id' => $model->id, | |
121 | + ]); | |
130 | 122 | } |
131 | 123 | } |
132 | 124 | return $this->render('update', [ |
... | ... | @@ -162,7 +154,11 @@ |
162 | 154 | */ |
163 | 155 | protected function findModel($id) |
164 | 156 | { |
165 | - if(( $model = Articles::findOne($id) ) !== NULL) { | |
157 | + if(( $model = Articles::find() | |
158 | + ->where([ 'id' => $id ]) | |
159 | + ->with('lang') | |
160 | + ->one() ) !== NULL | |
161 | + ) { | |
166 | 162 | return $model; |
167 | 163 | } else { |
168 | 164 | throw new NotFoundHttpException('The requested page does not exist.'); | ... | ... |
backend/views/articles/index.php
1 | 1 | <?php |
2 | - | |
3 | -use yii\helpers\Html; | |
4 | -use yii\grid\GridView; | |
5 | - | |
6 | -/* @var $this yii\web\View */ | |
7 | -/* @var $searchModel common\models\ArticlesSearch */ | |
8 | -/* @var $dataProvider yii\data\ActiveDataProvider */ | |
9 | - | |
10 | -$this->title = \Yii::t('app', 'Articles'); | |
11 | -$this->params['breadcrumbs'][] = $this->title; | |
2 | + | |
3 | + use yii\helpers\Html; | |
4 | + use yii\grid\GridView; | |
5 | + | |
6 | + /** | |
7 | + * @var yii\web\View $this | |
8 | + * @var common\models\ArticlesSearch $searchModel | |
9 | + * @var yii\data\ActiveDataProvider $dataProvider | |
10 | + */ | |
11 | + | |
12 | + $this->title = \Yii::t('app', 'Articles'); | |
13 | + $this->params[ 'breadcrumbs' ][] = $this->title; | |
12 | 14 | ?> |
13 | 15 | <div class="articles-index"> |
14 | 16 | <h1><?= Html::encode($this->title) ?></h1> |
15 | 17 | <p> |
16 | - <?= Html::a(\Yii::t('app', 'Create Articles'), ['create'], ['class' => 'btn btn-success']) ?> | |
18 | + <?= Html::a(\Yii::t('app', 'Create Articles'), [ 'create' ], [ 'class' => 'btn btn-success' ]) ?> | |
17 | 19 | </p> |
18 | 20 | <?= GridView::widget([ |
19 | 21 | 'dataProvider' => $dataProvider, |
20 | - 'filterModel' => $searchModel, | |
21 | - 'columns' => [ | |
22 | - ['class' => 'yii\grid\SerialColumn'], | |
22 | + 'filterModel' => $searchModel, | |
23 | + 'columns' => [ | |
23 | 24 | 'id', |
24 | - 'date', | |
25 | + [ | |
26 | + 'attribute' => 'title', | |
27 | + 'value' => 'lang.title', | |
28 | + ], | |
29 | + 'date:date', | |
25 | 30 | 'imageUrl:image', |
26 | - ['class' => 'yii\grid\ActionColumn'], | |
31 | + [ 'class' => 'yii\grid\ActionColumn' ], | |
27 | 32 | ], |
28 | 33 | ]); ?> |
29 | 34 | </div> | ... | ... |
backend/views/articles/view.php
1 | 1 | <?php |
2 | - | |
3 | -use yii\helpers\Html; | |
4 | -use yii\widgets\DetailView; | |
5 | - | |
6 | -/* @var $this yii\web\View */ | |
7 | -/* @var $model common\models\Articles */ | |
8 | - | |
9 | -$this->title = $model->id; | |
10 | -$this->params['breadcrumbs'][] = ['label' => \Yii::t('app', 'Articles'), 'url' => ['index']]; | |
11 | -$this->params['breadcrumbs'][] = $this->title; | |
2 | + | |
3 | + use yii\helpers\Html; | |
4 | + use yii\widgets\DetailView; | |
5 | + | |
6 | + /** | |
7 | + * @var yii\web\View $this | |
8 | + * @var common\models\Articles $model | |
9 | + */ | |
10 | + | |
11 | + $this->title = $model->lang->title; | |
12 | + $this->params[ 'breadcrumbs' ][] = [ | |
13 | + 'label' => \Yii::t('app', 'Articles'), | |
14 | + 'url' => [ 'index' ], | |
15 | + ]; | |
16 | + $this->params[ 'breadcrumbs' ][] = $this->title; | |
12 | 17 | ?> |
13 | 18 | <div class="articles-view"> |
14 | 19 | <h1><?= Html::encode($this->title) ?></h1> |
15 | 20 | <p> |
16 | - <?= Html::a(\Yii::t('app', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?> | |
17 | - <?= Html::a(\Yii::t('app', 'Delete'), ['delete', 'id' => $model->id], [ | |
21 | + <?= Html::a(\Yii::t('app', 'Update'), [ | |
22 | + 'update', | |
23 | + 'id' => $model->id, | |
24 | + ], [ 'class' => 'btn btn-primary' ]) ?> | |
25 | + <?= Html::a(\Yii::t('app', 'Delete'), [ | |
26 | + 'delete', | |
27 | + 'id' => $model->id, | |
28 | + ], [ | |
18 | 29 | 'class' => 'btn btn-danger', |
19 | - 'data' => [ | |
30 | + 'data' => [ | |
20 | 31 | 'confirm' => \Yii::t('app', 'Are you sure you want to delete this item?'), |
21 | - 'method' => 'post', | |
32 | + 'method' => 'post', | |
22 | 33 | ], |
23 | 34 | ]) ?> |
24 | 35 | </p> |
25 | 36 | <?= DetailView::widget([ |
26 | - 'model' => $model, | |
37 | + 'model' => $model, | |
27 | 38 | 'attributes' => [ |
28 | 39 | 'id', |
29 | - 'date', | |
40 | + 'date:date', | |
41 | + 'lang.title', | |
42 | + 'lang.body:html', | |
43 | + 'imageUrl:image', | |
30 | 44 | ], |
31 | 45 | ]) ?> |
32 | 46 | </div> | ... | ... |
backend/web/css/site.css
common/models/Articles.php
1 | 1 | <?php |
2 | 2 | |
3 | 3 | namespace common\models; |
4 | - | |
4 | + | |
5 | + use common\modules\language\behaviors\TransactionBehavior; | |
5 | 6 | use common\modules\language\behaviors\LanguageBehavior; |
6 | 7 | use common\behaviors\SaveImgBehavior; |
7 | 8 | use common\modules\comment\models\CommentModel; |
... | ... | @@ -32,6 +33,11 @@ |
32 | 33 | * @method bool linkLangs(ActiveRecord[] $model_langs) |
33 | 34 | * @method bool saveLangs(ActiveRecord[] $model_langs) |
34 | 35 | * * End language behavior * |
36 | + * * From transaction behavior * | |
37 | + * @property ArticlesLang[] $model_langs | |
38 | + * @property bool $transactionStatus | |
39 | + * @method bool getTransactionStatus() | |
40 | + * * End transaction behavior * | |
35 | 41 | */ |
36 | 42 | class Articles extends \yii\db\ActiveRecord |
37 | 43 | { |
... | ... | @@ -63,6 +69,9 @@ |
63 | 69 | 'language' => [ |
64 | 70 | 'class' => LanguageBehavior::className(), |
65 | 71 | ], |
72 | + 'transaction' => [ | |
73 | + 'class' => TransactionBehavior::className(), | |
74 | + ], | |
66 | 75 | ]; |
67 | 76 | } |
68 | 77 | ... | ... |
common/models/ArticlesSearch.php
1 | 1 | <?php |
2 | - | |
3 | -namespace common\models; | |
4 | - | |
5 | -use yii\base\Model; | |
6 | -use yii\data\ActiveDataProvider; | |
7 | - | |
8 | -/** | |
9 | - * ArticlesSearch represents the model behind the search form about `common\models\Articles`. | |
10 | - */ | |
11 | -class ArticlesSearch extends Articles | |
12 | -{ | |
13 | - /** | |
14 | - * @inheritdoc | |
15 | - */ | |
16 | - public function rules() | |
17 | - { | |
18 | - return [ | |
19 | - [['id'], 'integer'], | |
20 | - ]; | |
21 | - } | |
22 | 2 | |
23 | - public function behaviors() | |
24 | - { | |
25 | - return []; | |
26 | - } | |
3 | + namespace common\models; | |
27 | 4 | |
28 | - /** | |
29 | - * @inheritdoc | |
30 | - */ | |
31 | - public function scenarios() | |
32 | - { | |
33 | - // bypass scenarios() implementation in the parent class | |
34 | - return Model::scenarios(); | |
35 | - } | |
5 | + use yii\base\Model; | |
6 | + use yii\data\ActiveDataProvider; | |
7 | + use yii\data\Sort; | |
36 | 8 | |
37 | 9 | /** |
38 | - * Creates data provider instance with search query applied | |
39 | - * | |
40 | - * @param array $params | |
41 | - * | |
42 | - * @return ActiveDataProvider | |
10 | + * ArticlesSearch represents the model behind the search form about `common\models\Articles`. | |
43 | 11 | */ |
44 | - public function search($params) | |
12 | + class ArticlesSearch extends Articles | |
45 | 13 | { |
46 | - $query = Articles::find(); | |
47 | - | |
48 | - // add conditions that should always apply here | |
49 | - | |
50 | - $dataProvider = new ActiveDataProvider([ | |
51 | - 'query' => $query, | |
52 | - ]); | |
53 | - | |
54 | - $this->load($params); | |
55 | - | |
56 | - if (!$this->validate()) { | |
57 | - // uncomment the following line if you do not want to return any records when validation fails | |
58 | - // $query->where('0=1'); | |
14 | + | |
15 | + public $title; | |
16 | + | |
17 | + /** | |
18 | + * @inheritdoc | |
19 | + */ | |
20 | + public function rules() | |
21 | + { | |
22 | + return [ | |
23 | + [ | |
24 | + [ 'id' ], | |
25 | + 'integer', | |
26 | + ], | |
27 | + [ | |
28 | + [ 'title' ], | |
29 | + 'string', | |
30 | + ], | |
31 | + ]; | |
32 | + } | |
33 | + | |
34 | + public function behaviors() | |
35 | + { | |
36 | + return []; | |
37 | + } | |
38 | + | |
39 | + /** | |
40 | + * @inheritdoc | |
41 | + */ | |
42 | + public function scenarios() | |
43 | + { | |
44 | + // bypass scenarios() implementation in the parent class | |
45 | + return Model::scenarios(); | |
46 | + } | |
47 | + | |
48 | + /** | |
49 | + * Creates data provider instance with search query applied | |
50 | + * | |
51 | + * @param array $params | |
52 | + * | |
53 | + * @return ActiveDataProvider | |
54 | + */ | |
55 | + public function search($params) | |
56 | + { | |
57 | + $query = Articles::find() | |
58 | + ->joinWith('lang'); | |
59 | + | |
60 | + // add conditions that should always apply here | |
61 | + | |
62 | + $dataProvider = new ActiveDataProvider([ | |
63 | + 'query' => $query, | |
64 | + 'sort' => [ | |
65 | + 'attributes' => [ | |
66 | + 'id', | |
67 | + 'title' => [ | |
68 | + 'asc' => [ 'articles_lang.title' => SORT_ASC ], | |
69 | + 'desc' => [ 'articles_lang.title' => SORT_DESC ], | |
70 | + ], | |
71 | + ], | |
72 | + ], | |
73 | + ]); | |
74 | + | |
75 | + $this->load($params); | |
76 | + | |
77 | + if(!$this->validate()) { | |
78 | + // uncomment the following line if you do not want to return any records when validation fails | |
79 | + // $query->where('0=1'); | |
80 | + return $dataProvider; | |
81 | + } | |
82 | + | |
83 | + // grid filtering conditions | |
84 | + $query->andFilterWhere([ | |
85 | + 'id' => $this->id, | |
86 | + ]); | |
87 | + | |
88 | + $query->andFilterWhere([ | |
89 | + 'like', | |
90 | + 'articles_lang.title', | |
91 | + $this->title, | |
92 | + ]); | |
93 | + | |
59 | 94 | return $dataProvider; |
60 | 95 | } |
61 | - | |
62 | - // grid filtering conditions | |
63 | - $query->andFilterWhere([ | |
64 | - 'id' => $this->id, | |
65 | - ]); | |
66 | - | |
67 | - return $dataProvider; | |
68 | 96 | } |
69 | -} | ... | ... |
common/modules/language/behaviors/TransactionBehavior.php
0 → 100644
1 | +<?php | |
2 | + | |
3 | + namespace common\modules\language\behaviors; | |
4 | + | |
5 | + use yii\base\Behavior; | |
6 | + use yii\db\ActiveRecord; | |
7 | + use yii\db\Transaction; | |
8 | + | |
9 | + /** | |
10 | + * Class Save Image Behavior | |
11 | + * @property ActiveRecord $owner | |
12 | + * @package common\behaviors | |
13 | + */ | |
14 | + class TransactionBehavior extends Behavior | |
15 | + { | |
16 | + | |
17 | + /** | |
18 | + * @var Transaction $_transaction | |
19 | + */ | |
20 | + private $_transaction; | |
21 | + | |
22 | + /** | |
23 | + * @var bool $_transaction_status | |
24 | + */ | |
25 | + private $_transaction_status = false; | |
26 | + | |
27 | + /** | |
28 | + * @var ActiveRecord[] $model_langs | |
29 | + */ | |
30 | + public $model_langs = []; | |
31 | + | |
32 | + public function events() | |
33 | + { | |
34 | + return [ | |
35 | + ActiveRecord::EVENT_BEFORE_INSERT => 'beforeSave', | |
36 | + ActiveRecord::EVENT_BEFORE_UPDATE => 'beforeSave', | |
37 | + ActiveRecord::EVENT_AFTER_INSERT => 'afterSave', | |
38 | + ActiveRecord::EVENT_AFTER_UPDATE => 'afterSave', | |
39 | + ]; | |
40 | + } | |
41 | + | |
42 | + public function beforeSave($event) { | |
43 | + /** | |
44 | + * @var ActiveRecord $owner | |
45 | + */ | |
46 | + $owner = $this->owner; | |
47 | + $db = $owner::getDb(); | |
48 | + $this->_transaction = $db->beginTransaction(); | |
49 | + } | |
50 | + | |
51 | + public function afterSave($event) { | |
52 | + /** | |
53 | + * @var ActiveRecord $owner | |
54 | + */ | |
55 | + $owner = $this->owner; | |
56 | + if(!empty($this->model_langs) && $owner->getBehavior('language')) { | |
57 | + if($owner->linkLangs($this->model_langs) && $owner->saveLangs($this->model_langs)) { | |
58 | + $this->_transaction->commit(); | |
59 | + $this->_transaction_status = true; | |
60 | + } else { | |
61 | + $this->_transaction->rollBack(); | |
62 | + $this->_transaction_status = false; | |
63 | + } | |
64 | + } else { | |
65 | + $this->_transaction->commit(); | |
66 | + $this->_transaction_status = true; | |
67 | + } | |
68 | + } | |
69 | + | |
70 | + /** | |
71 | + * @return bool | |
72 | + */ | |
73 | + public function getTransactionStatus():bool { | |
74 | + return $this->_transaction_status; | |
75 | + } | |
76 | + | |
77 | + } | |
0 | 78 | \ No newline at end of file | ... | ... |
common/modules/language/readme.txt
... | ... | @@ -45,6 +45,9 @@ public function behaviors() { |
45 | 45 | 'ownerKey' => {Table}->id //optional, default to {Table}->primaryKey()[0] |
46 | 46 | 'langKey' => {TableLang}->table_id //optional, default to {Table}->tableName().'_id' |
47 | 47 | ], |
48 | + 'transaction' => [ | |
49 | + 'class' => TransactionBehavior::className(), | |
50 | + ], | |
48 | 51 | ]; |
49 | 52 | } |
50 | 53 | 3.1. PHPDoc для {Table}: |
... | ... | @@ -65,6 +68,11 @@ public function behaviors() { |
65 | 68 | * @method bool linkLangs(ActiveRecord[] $model_langs) |
66 | 69 | * @method bool saveLangs(ActiveRecord[] $model_langs) |
67 | 70 | * * End language behavior * |
71 | + * * From transaction behavior * | |
72 | + * @property {TableLang}[] $model_langs | |
73 | + * @property bool $transactionStatus | |
74 | + * @method bool getTransactionStatus() | |
75 | + * * End transaction behavior * | |
68 | 76 | 3.2. Убрать language behavior с наследуемых таблиц от {Table} ({TableSearch}...) |
69 | 77 | 4. Доступные полезные методы: |
70 | 78 | {Table}->getLangs() - получить все текущие {TableLang} для {Table} проиндексированные по language_id |
... | ... | @@ -83,6 +91,6 @@ public function behaviors() { |
83 | 91 | 6. Обрабатывать данные в контроллере. |
84 | 92 | 1. После создания/поиска {Table} создаем/находим языковые модели {Table}->generateLangs() |
85 | 93 | 2. При POST запросе загружаем данные в языковые модели {Table}->loadLangs(Request $request, {TableLangs[]} $model_langs) |
86 | - 3. Связываем модель {Table} с языковыми моделями {Table}->linkLangs({TableLang[]} $model_langs). Возвращает true при успехе. | |
87 | - 4. Сохраняе языковые модели в базу {Table}->saveLangs({TableLang[]} $model_langs). Возвращает true при успешной валидации каждого {TableLang}. | |
94 | + 3. Передаем в свойство model_langs модели {Table} массив {TableLang[]}: $model->model_langs = $model_langs | |
95 | + 4. После сохранения, если транзанкция успешна, то свойство {Table}->transactionStatus будет true, иначе возникла ошибка в какой то модели. | |
88 | 96 | 7. Получать данные на публичной части сайта через {Table}->lang. |
89 | 97 | \ No newline at end of file | ... | ... |