Commit fd238f57919408dbd91ae5d9d5c8fe4cddaaed7f

Authored by Yarik
1 parent 93c267f7

Admin begin refactor.

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
... ... @@ -207,3 +207,9 @@ a.desc:after {
207 207 text-align: center;
208 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 216 \ No newline at end of file
... ...
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
... ...