Commit fd238f57919408dbd91ae5d9d5c8fe4cddaaed7f

Authored by Yarik
1 parent 93c267f7

Admin begin refactor.

backend/controllers/ArticlesController.php
@@ -9,7 +9,6 @@ @@ -9,7 +9,6 @@
9 use yii\web\NotFoundHttpException; 9 use yii\web\NotFoundHttpException;
10 use yii\filters\VerbFilter; 10 use yii\filters\VerbFilter;
11 use developeruz\db_rbac\behaviors\AccessBehavior; 11 use developeruz\db_rbac\behaviors\AccessBehavior;
12 - use yii\web\UploadedFile;  
13 12
14 /** 13 /**
15 * ArticlesController implements the CRUD actions for Articles model. 14 * ArticlesController implements the CRUD actions for Articles model.
@@ -86,18 +85,12 @@ @@ -86,18 +85,12 @@
86 $model_langs = $model->generateLangs(); 85 $model_langs = $model->generateLangs();
87 if($model->load(Yii::$app->request->post())) { 86 if($model->load(Yii::$app->request->post())) {
88 $model->loadLangs(\Yii::$app->request, $model_langs); 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 return $this->render('create', [ 96 return $this->render('create', [
@@ -120,13 +113,12 @@ @@ -120,13 +113,12 @@
120 $model_langs = $model->generateLangs(); 113 $model_langs = $model->generateLangs();
121 if($model->load(Yii::$app->request->post())) { 114 if($model->load(Yii::$app->request->post())) {
122 $model->loadLangs(\Yii::$app->request, $model_langs); 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 return $this->render('update', [ 124 return $this->render('update', [
@@ -162,7 +154,11 @@ @@ -162,7 +154,11 @@
162 */ 154 */
163 protected function findModel($id) 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 return $model; 162 return $model;
167 } else { 163 } else {
168 throw new NotFoundHttpException('The requested page does not exist.'); 164 throw new NotFoundHttpException('The requested page does not exist.');
backend/views/articles/index.php
1 <?php 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 <div class="articles-index"> 15 <div class="articles-index">
14 <h1><?= Html::encode($this->title) ?></h1> 16 <h1><?= Html::encode($this->title) ?></h1>
15 <p> 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 </p> 19 </p>
18 <?= GridView::widget([ 20 <?= GridView::widget([
19 'dataProvider' => $dataProvider, 21 'dataProvider' => $dataProvider,
20 - 'filterModel' => $searchModel,  
21 - 'columns' => [  
22 - ['class' => 'yii\grid\SerialColumn'], 22 + 'filterModel' => $searchModel,
  23 + 'columns' => [
23 'id', 24 'id',
24 - 'date', 25 + [
  26 + 'attribute' => 'title',
  27 + 'value' => 'lang.title',
  28 + ],
  29 + 'date:date',
25 'imageUrl:image', 30 'imageUrl:image',
26 - ['class' => 'yii\grid\ActionColumn'], 31 + [ 'class' => 'yii\grid\ActionColumn' ],
27 ], 32 ],
28 ]); ?> 33 ]); ?>
29 </div> 34 </div>
backend/views/articles/view.php
1 <?php 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 <div class="articles-view"> 18 <div class="articles-view">
14 <h1><?= Html::encode($this->title) ?></h1> 19 <h1><?= Html::encode($this->title) ?></h1>
15 <p> 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 'class' => 'btn btn-danger', 29 'class' => 'btn btn-danger',
19 - 'data' => [ 30 + 'data' => [
20 'confirm' => \Yii::t('app', 'Are you sure you want to delete this item?'), 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 </p> 35 </p>
25 <?= DetailView::widget([ 36 <?= DetailView::widget([
26 - 'model' => $model, 37 + 'model' => $model,
27 'attributes' => [ 38 'attributes' => [
28 'id', 39 'id',
29 - 'date', 40 + 'date:date',
  41 + 'lang.title',
  42 + 'lang.body:html',
  43 + 'imageUrl:image',
30 ], 44 ],
31 ]) ?> 45 ]) ?>
32 </div> 46 </div>
backend/web/css/site.css
@@ -207,3 +207,9 @@ a.desc:after { @@ -207,3 +207,9 @@ a.desc:after {
207 text-align: center; 207 text-align: center;
208 font-size: 13px !important; 208 font-size: 13px !important;
209 } 209 }
  210 +.grid-view td img {
  211 + max-width: 250px;
  212 +}
  213 +.detail-view td img {
  214 + max-width: 100%;
  215 +}
210 \ No newline at end of file 216 \ No newline at end of file
common/models/Articles.php
1 <?php 1 <?php
2 2
3 namespace common\models; 3 namespace common\models;
4 - 4 +
  5 + use common\modules\language\behaviors\TransactionBehavior;
5 use common\modules\language\behaviors\LanguageBehavior; 6 use common\modules\language\behaviors\LanguageBehavior;
6 use common\behaviors\SaveImgBehavior; 7 use common\behaviors\SaveImgBehavior;
7 use common\modules\comment\models\CommentModel; 8 use common\modules\comment\models\CommentModel;
@@ -32,6 +33,11 @@ @@ -32,6 +33,11 @@
32 * @method bool linkLangs(ActiveRecord[] $model_langs) 33 * @method bool linkLangs(ActiveRecord[] $model_langs)
33 * @method bool saveLangs(ActiveRecord[] $model_langs) 34 * @method bool saveLangs(ActiveRecord[] $model_langs)
34 * * End language behavior * 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 class Articles extends \yii\db\ActiveRecord 42 class Articles extends \yii\db\ActiveRecord
37 { 43 {
@@ -63,6 +69,9 @@ @@ -63,6 +69,9 @@
63 'language' => [ 69 'language' => [
64 'class' => LanguageBehavior::className(), 70 'class' => LanguageBehavior::className(),
65 ], 71 ],
  72 + 'transaction' => [
  73 + 'class' => TransactionBehavior::className(),
  74 + ],
66 ]; 75 ];
67 } 76 }
68 77
common/models/ArticlesSearch.php
1 <?php 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 return $dataProvider; 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 \ No newline at end of file 78 \ No newline at end of file
common/modules/language/readme.txt
@@ -45,6 +45,9 @@ public function behaviors() { @@ -45,6 +45,9 @@ public function behaviors() {
45 'ownerKey' => {Table}->id //optional, default to {Table}->primaryKey()[0] 45 'ownerKey' => {Table}->id //optional, default to {Table}->primaryKey()[0]
46 'langKey' => {TableLang}->table_id //optional, default to {Table}->tableName().'_id' 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 3.1. PHPDoc для {Table}: 53 3.1. PHPDoc для {Table}:
@@ -65,6 +68,11 @@ public function behaviors() { @@ -65,6 +68,11 @@ public function behaviors() {
65 * @method bool linkLangs(ActiveRecord[] $model_langs) 68 * @method bool linkLangs(ActiveRecord[] $model_langs)
66 * @method bool saveLangs(ActiveRecord[] $model_langs) 69 * @method bool saveLangs(ActiveRecord[] $model_langs)
67 * * End language behavior * 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 3.2. Убрать language behavior с наследуемых таблиц от {Table} ({TableSearch}...) 76 3.2. Убрать language behavior с наследуемых таблиц от {Table} ({TableSearch}...)
69 4. Доступные полезные методы: 77 4. Доступные полезные методы:
70 {Table}->getLangs() - получить все текущие {TableLang} для {Table} проиндексированные по language_id 78 {Table}->getLangs() - получить все текущие {TableLang} для {Table} проиндексированные по language_id
@@ -83,6 +91,6 @@ public function behaviors() { @@ -83,6 +91,6 @@ public function behaviors() {
83 6. Обрабатывать данные в контроллере. 91 6. Обрабатывать данные в контроллере.
84 1. После создания/поиска {Table} создаем/находим языковые модели {Table}->generateLangs() 92 1. После создания/поиска {Table} создаем/находим языковые модели {Table}->generateLangs()
85 2. При POST запросе загружаем данные в языковые модели {Table}->loadLangs(Request $request, {TableLangs[]} $model_langs) 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 7. Получать данные на публичной части сайта через {Table}->lang. 96 7. Получать данные на публичной части сайта через {Table}->lang.
89 \ No newline at end of file 97 \ No newline at end of file