Commit 4d7ee43827fe30b5a8cbbbe46340b1307386445d

Authored by Alexey Boroda
1 parent b224f0ae

Changes:

-Blog categories added
-Comments to do
backend/controllers/BlogCategoryController.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\controllers;
  4 +
  5 +use Yii;
  6 +use common\models\BlogCategory;
  7 +use common\models\BlogCategorySearch;
  8 +use yii\web\Controller;
  9 +use yii\web\NotFoundHttpException;
  10 +use yii\filters\VerbFilter;
  11 +
  12 +/**
  13 + * BlogCategoryController implements the CRUD actions for BlogCategory model.
  14 + */
  15 +class BlogCategoryController extends Controller
  16 +{
  17 + /**
  18 + * @inheritdoc
  19 + */
  20 + public function behaviors()
  21 + {
  22 + return [
  23 + 'verbs' => [
  24 + 'class' => VerbFilter::className(),
  25 + 'actions' => [
  26 + 'delete' => ['POST'],
  27 + ],
  28 + ],
  29 + ];
  30 + }
  31 +
  32 + /**
  33 + * Lists all BlogCategory models.
  34 + * @return mixed
  35 + */
  36 + public function actionIndex()
  37 + {
  38 + $searchModel = new BlogCategorySearch();
  39 + $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
  40 +
  41 + return $this->render('index', [
  42 + 'searchModel' => $searchModel,
  43 + 'dataProvider' => $dataProvider,
  44 + ]);
  45 + }
  46 +
  47 + /**
  48 + * Displays a single BlogCategory model.
  49 + * @param integer $id
  50 + * @return mixed
  51 + */
  52 + public function actionView($id)
  53 + {
  54 + return $this->render('view', [
  55 + 'model' => $this->findModel($id),
  56 + ]);
  57 + }
  58 +
  59 + /**
  60 + * Creates a new BlogCategory model.
  61 + * If creation is successful, the browser will be redirected to the 'view' page.
  62 + * @return mixed
  63 + */
  64 + public function actionCreate()
  65 + {
  66 + $model = new BlogCategory();
  67 +
  68 + if ($model->load(Yii::$app->request->post()) && $model->save()) {
  69 + return $this->redirect(['view', 'id' => $model->id]);
  70 + } else {
  71 + return $this->render('create', [
  72 + 'model' => $model,
  73 + ]);
  74 + }
  75 + }
  76 +
  77 + /**
  78 + * Updates an existing BlogCategory model.
  79 + * If update is successful, the browser will be redirected to the 'view' page.
  80 + * @param integer $id
  81 + * @return mixed
  82 + */
  83 + public function actionUpdate($id)
  84 + {
  85 + $model = $this->findModel($id);
  86 +
  87 + if ($model->load(Yii::$app->request->post()) && $model->save()) {
  88 + return $this->redirect(['view', 'id' => $model->id]);
  89 + } else {
  90 + return $this->render('update', [
  91 + 'model' => $model,
  92 + ]);
  93 + }
  94 + }
  95 +
  96 + /**
  97 + * Deletes an existing BlogCategory model.
  98 + * If deletion is successful, the browser will be redirected to the 'index' page.
  99 + * @param integer $id
  100 + * @return mixed
  101 + */
  102 + public function actionDelete($id)
  103 + {
  104 + $this->findModel($id)->delete();
  105 +
  106 + return $this->redirect(['index']);
  107 + }
  108 +
  109 + /**
  110 + * Finds the BlogCategory model based on its primary key value.
  111 + * If the model is not found, a 404 HTTP exception will be thrown.
  112 + * @param integer $id
  113 + * @return BlogCategory the loaded model
  114 + * @throws NotFoundHttpException if the model cannot be found
  115 + */
  116 + protected function findModel($id)
  117 + {
  118 + if (($model = BlogCategory::findOne($id)) !== null) {
  119 + return $model;
  120 + } else {
  121 + throw new NotFoundHttpException('The requested page does not exist.');
  122 + }
  123 + }
  124 +}
... ...
backend/controllers/BlogController.php
... ... @@ -3,10 +3,12 @@
3 3 namespace backend\controllers;
4 4  
5 5 use common\models\Blog;
  6 +use common\models\BlogCategory;
6 7 use common\models\BlogSearch;
7 8 use Yii;
8 9 use common\models\Articles;
9 10 use common\models\ArticlesSearch;
  11 +use yii\helpers\VarDumper;
10 12 use yii\web\Controller;
11 13 use yii\web\NotFoundHttpException;
12 14 use yii\filters\VerbFilter;
... ... @@ -95,7 +97,17 @@ class BlogController extends Controller
95 97 if ($model->save() && $image) {
96 98 $image->saveAs(Yii::getAlias('@storage/blog/' . $image->name));
97 99 }
98   -
  100 +
  101 + if(!empty($model->categoryItems))
  102 + {
  103 + foreach($model->categoryItems as $item)
  104 + {
  105 + if($category = BlogCategory::findOne($item)) {
  106 + $model->link('categories', $category);
  107 + }
  108 + }
  109 + }
  110 +
99 111 return $this->redirect(['blog/index']);
100 112 } else {
101 113 return $this->render('create', [
... ... @@ -113,6 +125,8 @@ class BlogController extends Controller
113 125 public function actionUpdate($id)
114 126 {
115 127 $model = $this->findModel($id);
  128 + $model->categoryItems = $model->getCategories()->indexBy('id')
  129 + ->column();
116 130  
117 131 if ($model->load(Yii::$app->request->post())) {
118 132  
... ... @@ -128,7 +142,17 @@ class BlogController extends Controller
128 142 if ($model->save() && $image) {
129 143 $image->saveAs(Yii::getAlias('@storage/blog/' . $image->name));
130 144 }
131   -
  145 + $model->unlinkAll('categories', true);
  146 + if(!empty($model->categoryItems))
  147 + {
  148 + foreach($model->categoryItems as $item)
  149 + {
  150 + if($category = BlogCategory::findOne($item)) {
  151 + $model->link('categories', $category);
  152 + }
  153 + }
  154 + }
  155 +
132 156 return $this->redirect(['view', 'id' => $model->id]);
133 157 } else {
134 158 return $this->render('update', [
... ...
backend/views/blog-category/_form.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\models\BlogCategory */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="blog-category-form">
  12 +
  13 + <?php $form = ActiveForm::begin(); ?>
  14 +
  15 + <?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
  16 +
  17 + <div class="form-group">
  18 + <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  19 + </div>
  20 +
  21 + <?php ActiveForm::end(); ?>
  22 +
  23 +</div>
... ...
backend/views/blog-category/_search.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\models\BlogCategorySearch */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="blog-category-search">
  12 +
  13 + <?php $form = ActiveForm::begin([
  14 + 'action' => ['index'],
  15 + 'method' => 'get',
  16 + ]); ?>
  17 +
  18 + <?= $form->field($model, 'id') ?>
  19 +
  20 + <?= $form->field($model, 'name') ?>
  21 +
  22 + <div class="form-group">
  23 + <?= Html::submitButton(Yii::t('app', 'Search'), ['class' => 'btn btn-primary']) ?>
  24 + <?= Html::resetButton(Yii::t('app', 'Reset'), ['class' => 'btn btn-default']) ?>
  25 + </div>
  26 +
  27 + <?php ActiveForm::end(); ?>
  28 +
  29 +</div>
... ...
backend/views/blog-category/create.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\models\BlogCategory */
  8 +
  9 +$this->title = Yii::t('app', 'Create Blog Category');
  10 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Blog Categories'), 'url' => ['index']];
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="blog-category-create">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 +
  17 + <?= $this->render('_form', [
  18 + 'model' => $model,
  19 + ]) ?>
  20 +
  21 +</div>
... ...
backend/views/blog-category/index.php 0 → 100644
  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\BlogCategorySearch */
  8 +/* @var $dataProvider yii\data\ActiveDataProvider */
  9 +
  10 +$this->title = Yii::t('app', 'Blog Categories');
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="blog-category-index">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 + <?php // echo $this->render('_search', ['model' => $searchModel]); ?>
  17 +
  18 + <p>
  19 + <?= Html::a(Yii::t('app', 'Create Blog Category'), ['create'], ['class' => 'btn btn-success']) ?>
  20 + </p>
  21 + <?= GridView::widget([
  22 + 'dataProvider' => $dataProvider,
  23 + 'filterModel' => $searchModel,
  24 + 'columns' => [
  25 + ['class' => 'yii\grid\SerialColumn'],
  26 +
  27 + 'id',
  28 + 'name',
  29 +
  30 + ['class' => 'yii\grid\ActionColumn'],
  31 + ],
  32 + ]); ?>
  33 +</div>
... ...
backend/views/blog-category/update.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +
  5 +/* @var $this yii\web\View */
  6 +/* @var $model common\models\BlogCategory */
  7 +
  8 +$this->title = Yii::t('app', 'Update {modelClass}: ', [
  9 + 'modelClass' => 'Blog Category',
  10 +]) . $model->name;
  11 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Blog Categories'), 'url' => ['index']];
  12 +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]];
  13 +$this->params['breadcrumbs'][] = Yii::t('app', 'Update');
  14 +?>
  15 +<div class="blog-category-update">
  16 +
  17 + <h1><?= Html::encode($this->title) ?></h1>
  18 +
  19 + <?= $this->render('_form', [
  20 + 'model' => $model,
  21 + ]) ?>
  22 +
  23 +</div>
... ...
backend/views/blog-category/view.php 0 → 100644
  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\BlogCategory */
  8 +
  9 +$this->title = $model->name;
  10 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Blog Categories'), 'url' => ['index']];
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="blog-category-view">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 +
  17 + <p>
  18 + <?= Html::a(Yii::t('app', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
  19 + <?= Html::a(Yii::t('app', 'Delete'), ['delete', 'id' => $model->id], [
  20 + 'class' => 'btn btn-danger',
  21 + 'data' => [
  22 + 'confirm' => Yii::t('app', 'Are you sure you want to delete this item?'),
  23 + 'method' => 'post',
  24 + ],
  25 + ]) ?>
  26 + </p>
  27 +
  28 + <?= DetailView::widget([
  29 + 'model' => $model,
  30 + 'attributes' => [
  31 + 'id',
  32 + 'name',
  33 + ],
  34 + ]) ?>
  35 +
  36 +</div>
... ...
backend/views/blog/_form.php
1 1 <?php
2   -
3   -use yii\helpers\Html;
4   -use yii\widgets\ActiveForm;
5   -use mihaildev\ckeditor\CKEditor;
6   -use mihaildev\elfinder\ElFinder;
7   -use yii\jui\DatePicker;
8   -/* @var $this yii\web\View */
9   -/* @var $model common\models\Blog */
10   -/* @var $form yii\widgets\ActiveForm */
  2 +
  3 + use yii\helpers\Html;
  4 + use yii\widgets\ActiveForm;
  5 + use mihaildev\ckeditor\CKEditor;
  6 + use mihaildev\elfinder\ElFinder;
  7 + use yii\jui\DatePicker;
  8 + use kartik\select2\Select2;
  9 +
  10 + /* @var $this yii\web\View */
  11 + /* @var $model common\models\Blog */
  12 + /* @var $form yii\widgets\ActiveForm */
11 13 ?>
12 14  
13 15 <div class="articles-form">
14   -
  16 +
15 17 <?php $form = ActiveForm::begin([
16 18 'enableClientValidation' => false,
17   - 'options' => ['enctype' => 'multipart/form-data']
  19 + 'options' => [ 'enctype' => 'multipart/form-data' ],
18 20 ]); ?>
19   -
20   -
  21 +
  22 +
21 23 <?= $form->field($model, 'date')
22   - ->widget(DatePicker::className(), [
23   - 'dateFormat' => 'dd-MM-yyyy',
24   - ]) ?>
25   -
  24 + ->widget(DatePicker::className(), [
  25 + 'dateFormat' => 'dd-MM-yyyy',
  26 + ]) ?>
  27 +
26 28 <?= $form->field($model, 'date_end')
27   - ->widget(DatePicker::className(), [
28   - 'dateFormat' => 'dd-MM-yyyy',
29   - ]) ?>
30   -
31   - <?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
32   -
33   - <?= $form->field($model, 'body')->widget(CKEditor::className(),
34   - [
35   - 'editorOptions' => ElFinder::ckeditorOptions('elfinder',[
36   - 'preset' => 'full', //разработанны стандартные настройки basic, standard, full данную возможность не обязательно использовать
37   - 'inline' => false, //по умолчанию false]),
38   - 'filebrowserUploadUrl'=>Yii::$app->getUrlManager()->createUrl('file/uploader/images-upload')
39   - ]
40   - )
41   - ]) ?>
42   -
43   - <?= $form->field($model, 'body_preview')->widget(CKEditor::className(),
44   - [
45   - 'editorOptions' => ElFinder::ckeditorOptions('elfinder',[
46   - 'preset' => 'full', //разработанны стандартные настройки basic, standard, full данную возможность не обязательно использовать
47   - 'inline' => false, //по умолчанию false]),
48   - 'filebrowserUploadUrl'=>Yii::$app->getUrlManager()->createUrl('file/uploader/images-upload')
49   - ]
50   - )
51   - ]) ?>
52   -
53   - <?= $form->field($model, 'imageUpload')->widget(\kartik\file\FileInput::classname(), [
54   - 'language' => 'ru',
55   - 'options' => [
56   - 'accept' => 'image/*',
57   - 'multiple' => false,
58   - ],
59   - 'pluginOptions' => [
60   - 'allowedFileExtensions' => ['jpg', 'gif', 'png'],
61   - 'initialPreview' => !empty($model->imageUrl) ? \common\components\artboximage\ArtboxImageHelper::getImage($model->imageUrl, 'list') : '',
62   - 'overwriteInitial' => true,
63   - 'showRemove' => false,
64   - 'showUpload' => false,
65   - 'previewFileType' => 'image',
66   - ],
67   - ]); ?>
68   -
69   - <?= $form->field($model, 'translit')->textInput(['maxlength' => true]) ?>
70   -
71   - <?= $form->field($model, 'meta_title')->textInput(['maxlength' => true]) ?>
72   -
73   - <?= $form->field($model, 'meta_keywords')->textInput(['maxlength' => true]) ?>
74   -
75   - <?= $form->field($model, 'meta_description')->textInput(['maxlength' => true]) ?>
76   -
77   - <?= $form->field($model, 'seo_text')->textarea(['rows' => 6]) ?>
78   -
79   - <?= $form->field($model, 'h1')->textInput(['maxlength' => true]) ?>
80   -
  29 + ->widget(DatePicker::className(), [
  30 + 'dateFormat' => 'dd-MM-yyyy',
  31 + ]) ?>
  32 +
  33 + <?= $form->field($model, 'title')
  34 + ->textInput([ 'maxlength' => true ]) ?>
  35 +
  36 + <?= $form->field($model, 'body')
  37 + ->widget(CKEditor::className(), [
  38 + 'editorOptions' => ElFinder::ckeditorOptions('elfinder', [
  39 + 'preset' => 'full',
  40 + //разработанны стандартные настройки basic, standard, full данную возможность не обязательно использовать
  41 + 'inline' => false,
  42 + //по умолчанию false]),
  43 + 'filebrowserUploadUrl' => Yii::$app->getUrlManager()
  44 + ->createUrl('file/uploader/images-upload'),
  45 + ]),
  46 + ]) ?>
  47 +
  48 + <?= $form->field($model, 'body_preview')
  49 + ->widget(CKEditor::className(), [
  50 + 'editorOptions' => ElFinder::ckeditorOptions('elfinder', [
  51 + 'preset' => 'full',
  52 + //разработанны стандартные настройки basic, standard, full данную возможность не обязательно использовать
  53 + 'inline' => false,
  54 + //по умолчанию false]),
  55 + 'filebrowserUploadUrl' => Yii::$app->getUrlManager()
  56 + ->createUrl('file/uploader/images-upload'),
  57 + ]),
  58 + ]) ?>
  59 +
  60 + <?= $form->field($model, 'imageUpload')
  61 + ->widget(\kartik\file\FileInput::classname(), [
  62 + 'language' => 'ru',
  63 + 'options' => [
  64 + 'accept' => 'image/*',
  65 + 'multiple' => false,
  66 + ],
  67 + 'pluginOptions' => [
  68 + 'allowedFileExtensions' => [
  69 + 'jpg',
  70 + 'gif',
  71 + 'png',
  72 + ],
  73 + 'initialPreview' => !empty( $model->imageUrl ) ? \common\components\artboximage\ArtboxImageHelper::getImage($model->imageUrl, 'list') : '',
  74 + 'overwriteInitial' => true,
  75 + 'showRemove' => false,
  76 + 'showUpload' => false,
  77 + 'previewFileType' => 'image',
  78 + ],
  79 + ]); ?>
  80 +
  81 + <?php
  82 + echo $form->field($model, 'categoryItems')
  83 + ->widget(Select2::className(), [
  84 + 'data' => $model->getCategoryItemsAsArray(),
  85 + 'language' => 'ru',
  86 + 'options' => [
  87 + 'placeholder' => 'Выберите категории ...',
  88 + 'multiple' => true,
  89 + ],
  90 + 'pluginOptions' => [
  91 + 'allowClear' => true,
  92 + ],
  93 + ]);
  94 + ?>
  95 +
  96 + <?= $form->field($model, 'translit')
  97 + ->textInput([ 'maxlength' => true ]) ?>
  98 +
  99 + <?= $form->field($model, 'meta_title')
  100 + ->textInput([ 'maxlength' => true ]) ?>
  101 +
  102 + <?= $form->field($model, 'meta_keywords')
  103 + ->textInput([ 'maxlength' => true ]) ?>
  104 +
  105 + <?= $form->field($model, 'meta_description')
  106 + ->textInput([ 'maxlength' => true ]) ?>
  107 +
  108 + <?= $form->field($model, 'seo_text')
  109 + ->textarea([ 'rows' => 6 ]) ?>
  110 +
  111 + <?= $form->field($model, 'h1')
  112 + ->textInput([ 'maxlength' => true ]) ?>
  113 +
81 114 <div class="form-group">
82   - <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  115 + <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', [ 'class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary' ]) ?>
83 116 </div>
84   -
  117 +
85 118 <?php ActiveForm::end(); ?>
86 119  
87 120 </div>
... ...
common/behaviors/ManyToManyBehavior.php 0 → 100644
  1 +<?php
  2 +namespace voskobovich\behaviors;
  3 +use Yii;
  4 +use yii\base\Behavior;
  5 +use yii\db\ActiveQuery;
  6 +use yii\db\ActiveRecord;
  7 +use yii\base\ErrorException;
  8 +use yii\db\Exception;
  9 +use yii\helpers\ArrayHelper;
  10 +/**
  11 + * Class ManyToManyBehavior
  12 + * @package voskobovich\behaviors
  13 + *
  14 + * See README.md for examples
  15 + */
  16 +class ManyToManyBehavior extends Behavior
  17 +{
  18 + /**
  19 + * Stores a list of relations, affected by the behavior. Configurable property.
  20 + * @var array
  21 + */
  22 + public $relations = [];
  23 + /**
  24 + * Stores values of relation attributes. All entries in this array are considered
  25 + * dirty (changed) attributes and will be saved in saveRelations().
  26 + * @var array
  27 + */
  28 + private $_values = [];
  29 + /**
  30 + * Used to store fields that this behavior creates. Each field refers to a relation
  31 + * and has optional getters and setters.
  32 + * @var array
  33 + */
  34 + private $_fields = [];
  35 + /**
  36 + * Events list
  37 + * @return array
  38 + */
  39 + public function events()
  40 + {
  41 + return [
  42 + ActiveRecord::EVENT_AFTER_INSERT => 'saveRelations',
  43 + ActiveRecord::EVENT_AFTER_UPDATE => 'saveRelations',
  44 + ];
  45 + }
  46 + /**
  47 + * Invokes init of parent class and assigns proper values to internal _fields variable
  48 + */
  49 + public function init()
  50 + {
  51 + parent::init();
  52 + //configure _fields
  53 + foreach ($this->relations as $attributeName => $params) {
  54 + //add primary field
  55 + $this->_fields[$attributeName] = [
  56 + 'attribute' => $attributeName,
  57 + ];
  58 + if (isset($params['get'])) {
  59 + $this->_fields[$attributeName]['get'] = $params['get'];
  60 + }
  61 + if (isset($params['set'])) {
  62 + $this->_fields[$attributeName]['set'] = $params['set'];
  63 + }
  64 + // Add secondary fields
  65 + if (isset($params['fields'])) {
  66 + foreach ($params['fields'] as $fieldName => $adjustments) {
  67 + $fullFieldName = $attributeName.'_'.$fieldName;
  68 + if (isset($this->_fields[$fullFieldName])) {
  69 + throw new ErrorException("Ambiguous field name definition: {$fullFieldName}");
  70 + }
  71 + $this->_fields[$fullFieldName] = [
  72 + 'attribute' => $attributeName,
  73 + ];
  74 + if (isset($adjustments['get'])) {
  75 + $this->_fields[$fullFieldName]['get'] = $adjustments['get'];
  76 + }
  77 + if (isset($adjustments['set'])) {
  78 + $this->_fields[$fullFieldName]['set'] = $adjustments['set'];
  79 + }
  80 + }
  81 + }
  82 + }
  83 + }
  84 + /**
  85 + * Save all dirty (changed) relation values ($this->_values) to the database
  86 + * @throws ErrorException
  87 + * @throws Exception
  88 + */
  89 + public function saveRelations()
  90 + {
  91 + /** @var ActiveRecord $primaryModel */
  92 + $primaryModel = $this->owner;
  93 + if (is_array($primaryModelPk = $primaryModel->getPrimaryKey())) {
  94 + throw new ErrorException('This behavior does not support composite primary keys');
  95 + }
  96 + foreach ($this->relations as $attributeName => $params) {
  97 + $relationName = $this->getRelationName($attributeName);
  98 + $relation = $primaryModel->getRelation($relationName);
  99 + if (!$this->hasNewValue($attributeName)) {
  100 + continue;
  101 + }
  102 + if (!empty($relation->via) && $relation->multiple) {
  103 + // Many-to-many
  104 + $this->saveManyToManyRelation($relation, $attributeName);
  105 + } elseif (!empty($relation->link) && $relation->multiple) {
  106 + // One-to-many on the many side
  107 + $this->saveOneToManyRelation($relation, $attributeName);
  108 + } else {
  109 + throw new ErrorException('Relationship type not supported.');
  110 + }
  111 + }
  112 + }
  113 + /**
  114 + * @param ActiveQuery $relation
  115 + * @param string $attributeName
  116 + * @throws Exception
  117 + */
  118 + private function saveManyToManyRelation($relation, $attributeName)
  119 + {
  120 + /** @var ActiveRecord $primaryModel */
  121 + $primaryModel = $this->owner;
  122 + $primaryModelPk = $primaryModel->getPrimaryKey();
  123 + $bindingKeys = $this->getNewValue($attributeName);
  124 + // Assuming junction column is visible from the primary model connection
  125 + if (is_array($relation->via)) {
  126 + // via()
  127 + $via = $relation->via[1];
  128 + /** @var ActiveRecord $junctionModelClass */
  129 + $junctionModelClass = $via->modelClass;
  130 + $junctionTable = $junctionModelClass::tableName();
  131 + list($junctionColumn) = array_keys($via->link);
  132 + } else {
  133 + // viaTable()
  134 + list($junctionTable) = array_values($relation->via->from);
  135 + list($junctionColumn) = array_keys($relation->via->link);
  136 + }
  137 + list($relatedColumn) = array_values($relation->link);
  138 + $connection = $primaryModel::getDb();
  139 + $transaction = $connection->beginTransaction();
  140 + try {
  141 + // Remove old relations
  142 + $connection->createCommand()
  143 + ->delete($junctionTable, ArrayHelper::merge(
  144 + [$junctionColumn => $primaryModelPk],
  145 + $this->getCustomDeleteCondition($attributeName)
  146 + ))
  147 + ->execute();
  148 + // Write new relations
  149 + if (!empty($bindingKeys)) {
  150 + $junctionRows = [];
  151 + $viaTableParams = $this->getViaTableParams($attributeName);
  152 + foreach ($bindingKeys as $relatedPk) {
  153 + $row = [$primaryModelPk, $relatedPk];
  154 + // Calculate additional viaTable values
  155 + foreach (array_keys($viaTableParams) as $viaTableColumn) {
  156 + $row[] = $this->getViaTableValue($attributeName, $viaTableColumn, $relatedPk);
  157 + }
  158 + array_push($junctionRows, $row);
  159 + }
  160 + $cols = [$junctionColumn, $relatedColumn];
  161 + // Additional viaTable columns
  162 + foreach (array_keys($viaTableParams) as $viaTableColumn) {
  163 + $cols[] = $viaTableColumn;
  164 + }
  165 + $connection->createCommand()
  166 + ->batchInsert($junctionTable, $cols, $junctionRows)
  167 + ->execute();
  168 + }
  169 + $transaction->commit();
  170 + } catch (Exception $ex) {
  171 + $transaction->rollback();
  172 + throw $ex;
  173 + }
  174 + }
  175 + /**
  176 + * @param ActiveQuery $relation
  177 + * @param string $attributeName
  178 + * @throws Exception
  179 + */
  180 + private function saveOneToManyRelation($relation, $attributeName)
  181 + {
  182 + /** @var ActiveRecord $primaryModel */
  183 + $primaryModel = $this->owner;
  184 + $primaryModelPk = $primaryModel->getPrimaryKey();
  185 + $bindingKeys = $this->getNewValue($attributeName);
  186 + // HasMany, primary model HAS MANY foreign models, must update foreign model table
  187 + /** @var ActiveRecord $foreignModel */
  188 + $foreignModel = new $relation->modelClass();
  189 + $manyTable = $foreignModel->tableName();
  190 + list($manyTableFkColumn) = array_keys($relation->link);
  191 + $manyTableFkValue = $primaryModelPk;
  192 + list($manyTablePkColumn) = ($foreignModel->primaryKey());
  193 + $connection = $foreignModel::getDb();
  194 + $transaction = $connection->beginTransaction();
  195 + $defaultValue = $this->getDefaultValue($attributeName);
  196 + try {
  197 + // Remove old relations
  198 + $connection->createCommand()
  199 + ->update(
  200 + $manyTable,
  201 + [$manyTableFkColumn => $defaultValue],
  202 + [$manyTableFkColumn => $manyTableFkValue])
  203 + ->execute();
  204 + // Write new relations
  205 + if (!empty($bindingKeys)) {
  206 + $connection->createCommand()
  207 + ->update(
  208 + $manyTable,
  209 + [$manyTableFkColumn => $manyTableFkValue],
  210 + ['in', $manyTablePkColumn, $bindingKeys])
  211 + ->execute();
  212 + }
  213 + $transaction->commit();
  214 + } catch (Exception $ex) {
  215 + $transaction->rollback();
  216 + throw $ex;
  217 + }
  218 + }
  219 + /**
  220 + * Call user function
  221 + * @param $function
  222 + * @param $value
  223 + * @return mixed
  224 + * @throws ErrorException
  225 + */
  226 + private function callUserFunction($function, $value)
  227 + {
  228 + if (!is_array($function) && !$function instanceof \Closure) {
  229 + throw new ErrorException('This value is not a function');
  230 + }
  231 + return call_user_func($function, $value);
  232 + }
  233 + /**
  234 + * Check if an attribute is dirty and must be saved (its new value exists)
  235 + * @param string $attributeName
  236 + * @return null
  237 + */
  238 + private function hasNewValue($attributeName)
  239 + {
  240 + return isset($this->_values[$attributeName]);
  241 + }
  242 + /**
  243 + * Get value of a dirty attribute by name
  244 + * @param string $attributeName
  245 + * @return null
  246 + */
  247 + private function getNewValue($attributeName)
  248 + {
  249 + return $this->_values[$attributeName];
  250 + }
  251 + /**
  252 + * Get default value for an attribute (used for 1-N relations)
  253 + * @param string $attributeName
  254 + * @return mixed
  255 + */
  256 + private function getDefaultValue($attributeName)
  257 + {
  258 + $relationParams = $this->getRelationParams($attributeName);
  259 + if (!isset($relationParams['default'])) {
  260 + return null;
  261 + }
  262 + if ($relationParams['default'] instanceof \Closure) {
  263 + $closure = $relationParams['default'];
  264 + $relationName = $this->getRelationName($attributeName);
  265 + return call_user_func($closure, $this->owner, $relationName, $attributeName);
  266 + }
  267 + return $relationParams['default'];
  268 + }
  269 + /**
  270 + * Calculate additional value of viaTable
  271 + * @param string $attributeName
  272 + * @param string $viaTableAttribute
  273 + * @param integer $relatedPk
  274 + * @return mixed
  275 + */
  276 + private function getViaTableValue($attributeName, $viaTableAttribute, $relatedPk)
  277 + {
  278 + $viaTableParams = $this->getViaTableParams($attributeName);
  279 + if (!isset($viaTableParams[$viaTableAttribute])) {
  280 + return null;
  281 + }
  282 + if ($viaTableParams[$viaTableAttribute] instanceof \Closure) {
  283 + $closure = $viaTableParams[$viaTableAttribute];
  284 + $relationName = $this->getRelationName($attributeName);
  285 + return call_user_func($closure, $this->owner, $relationName, $attributeName, $relatedPk);
  286 + }
  287 + return $viaTableParams[$viaTableAttribute];
  288 + }
  289 + /**
  290 + * Get additional parameters of viaTable
  291 + * @param string $attributeName
  292 + * @return array
  293 + */
  294 + private function getViaTableParams($attributeName)
  295 + {
  296 + $params = $this->getRelationParams($attributeName);
  297 + return isset($params['viaTableValues'])
  298 + ? $params['viaTableValues']
  299 + : [];
  300 + }
  301 + /**
  302 + * Get custom condition used to delete old records.
  303 + * @param string $attributeName
  304 + * @return array
  305 + */
  306 + private function getCustomDeleteCondition($attributeName)
  307 + {
  308 + $params = $this->getRelationParams($attributeName);
  309 + return isset($params['customDeleteCondition'])
  310 + ? $params['customDeleteCondition']
  311 + : [];
  312 + }
  313 + /**
  314 + * Get parameters of a field
  315 + * @param string $fieldName
  316 + * @return mixed
  317 + * @throws ErrorException
  318 + */
  319 + private function getFieldParams($fieldName)
  320 + {
  321 + if (empty($this->_fields[$fieldName])) {
  322 + throw new ErrorException('Parameter "' . $fieldName . '" does not exist');
  323 + }
  324 + return $this->_fields[$fieldName];
  325 + }
  326 + /**
  327 + * Get parameters of a relation
  328 + * @param string $attributeName
  329 + * @return mixed
  330 + * @throws ErrorException
  331 + */
  332 + private function getRelationParams($attributeName)
  333 + {
  334 + if (empty($this->relations[$attributeName])) {
  335 + throw new ErrorException('Parameter "' . $attributeName . '" does not exist.');
  336 + }
  337 + return $this->relations[$attributeName];
  338 + }
  339 + /**
  340 + * Get name of a relation
  341 + * @param string $attributeName
  342 + * @return null
  343 + */
  344 + private function getRelationName($attributeName)
  345 + {
  346 + $params = $this->getRelationParams($attributeName);
  347 + if (is_string($params)) {
  348 + return $params;
  349 + }
  350 + if (is_array($params) && !empty($params[0])) {
  351 + return $params[0];
  352 + }
  353 + return null;
  354 + }
  355 + /**
  356 + * @inheritdoc
  357 + */
  358 + public function canGetProperty($name, $checkVars = true)
  359 + {
  360 + return array_key_exists($name, $this->_fields) ?
  361 + true : parent::canGetProperty($name, $checkVars);
  362 + }
  363 + /**
  364 + * @inheritdoc
  365 + */
  366 + public function canSetProperty($name, $checkVars = true)
  367 + {
  368 + return array_key_exists($name, $this->_fields) ?
  369 + true : parent::canSetProperty($name, $checkVars = true);
  370 + }
  371 + /**
  372 + * @inheritdoc
  373 + */
  374 + public function __get($name)
  375 + {
  376 + $fieldParams = $this->getFieldParams($name);
  377 + $attributeName = $fieldParams['attribute'];
  378 + $relationName = $this->getRelationName($attributeName);
  379 + if ($this->hasNewValue($attributeName)) {
  380 + $value = $this->getNewValue($attributeName);
  381 + } else {
  382 + /** @var ActiveRecord $owner */
  383 + $owner = $this->owner;
  384 + $relation = $owner->getRelation($relationName);
  385 + /** @var ActiveRecord $foreignModel */
  386 + $foreignModel = new $relation->modelClass();
  387 + $value = $relation->select($foreignModel->getPrimaryKey())->column();
  388 + }
  389 + if (empty($fieldParams['get'])) {
  390 + return $value;
  391 + }
  392 + return $this->callUserFunction($fieldParams['get'], $value);
  393 + }
  394 + /**
  395 + * @inheritdoc
  396 + */
  397 + public function __set($name, $value)
  398 + {
  399 + $fieldParams = $this->getFieldParams($name);
  400 + $attributeName = $fieldParams['attribute'];
  401 + if (!empty($fieldParams['set'])) {
  402 + $this->_values[$attributeName] = $this->callUserFunction($fieldParams['set'], $value);
  403 + } else {
  404 + $this->_values[$attributeName] = $value;
  405 + }
  406 + }
  407 +}
0 408 \ No newline at end of file
... ...
common/models/Blog.php
1 1 <?php
2   -
3   -namespace common\models;
4   -
5   -use common\behaviors\SaveImgBehavior;
6   -use common\modules\comment\models\CommentModel;
7   -use Yii;
8   -
9   -/**
10   - * This is the model class for table "blog".
11   - *
12   - * @property integer $id
13   - * @property integer $date
14   - * @property string $title
15   - * @property string $body
16   - * @property string $image
17   - * @property string $translit
18   - * @property string $meta_title
19   - * @property string $meta_keywords
20   - * @property string $meta_description
21   - * @property string $seo_text
22   - * @property string $h1
23   - * @property string $body_preview
24   - * @property integer $date_end
25   - */
26   -class Blog extends \yii\db\ActiveRecord
27   -{
28   - public $imageUpload;
29   -
  2 +
  3 + namespace common\models;
  4 +
  5 + use common\behaviors\SaveImgBehavior;
  6 + use Yii;
  7 + use yii\db\ActiveQuery;
  8 + use yii\db\ActiveRecord;
  9 + use common\models\BlogCategory;
  10 +
30 11 /**
31   - * @inheritdoc
  12 + * This is the model class for table "blog".
  13 + * @property integer $id
  14 + * @property integer $date
  15 + * @property string $title
  16 + * @property string $body
  17 + * @property string $image
  18 + * @property string $translit
  19 + * @property string $meta_title
  20 + * @property string $meta_keywords
  21 + * @property string $meta_description
  22 + * @property string $seo_text
  23 + * @property string $h1
  24 + * @property string $body_preview
  25 + * @property integer $date_end
  26 + * @property array $categories
  27 + * @property array $categoryItems
32 28 */
33   - public static function tableName()
  29 + class Blog extends ActiveRecord
34 30 {
35   - return 'blog';
  31 + private $_categoryItems;
  32 +
  33 + public $imageUpload;
  34 +
  35 + /**
  36 + * @inheritdoc
  37 + */
  38 + public static function tableName()
  39 + {
  40 + return 'blog';
  41 + }
  42 +
  43 + /**
  44 + * @inheritdoc
  45 + */
  46 + public function behaviors()
  47 + {
  48 + return [
  49 + 'slug' => [
  50 + 'class' => 'common\behaviors\Slug',
  51 + 'in_attribute' => 'title',
  52 + 'out_attribute' => 'translit',
  53 + 'translit' => true,
  54 + ],
  55 + [
  56 + 'class' => SaveImgBehavior::className(),
  57 + ],
  58 + ];
  59 + }
  60 +
  61 + /**
  62 + * @inheritdoc
  63 + */
  64 + public function rules()
  65 + {
  66 + return [
  67 + [
  68 + [ 'date' ],
  69 + 'default',
  70 + 'value' => function() {
  71 + return time();
  72 + },
  73 + ],
  74 + [
  75 + [
  76 + 'date',
  77 + 'date_end',
  78 + ],
  79 + 'safe',
  80 + ],
  81 + [
  82 + [
  83 + 'title',
  84 + 'body',
  85 + ],
  86 + 'required',
  87 + ],
  88 + [
  89 + [
  90 + 'body',
  91 + 'body_preview',
  92 + 'seo_text',
  93 + ],
  94 + 'string',
  95 + ],
  96 + [
  97 + [
  98 + 'title',
  99 + 'image',
  100 + 'translit',
  101 + 'meta_title',
  102 + 'meta_keywords',
  103 + 'meta_description',
  104 + 'h1',
  105 + ],
  106 + 'string',
  107 + 'max' => 255,
  108 + ],
  109 + [
  110 + [ 'imageUpload' ],
  111 + 'safe',
  112 + ],
  113 + [
  114 + [ 'imageUpload' ],
  115 + 'file',
  116 + 'extensions' => 'jpg, gif, png',
  117 + ],
  118 + [
  119 + [
  120 + 'date',
  121 + 'date_end',
  122 + ],
  123 + 'filter',
  124 + 'filter' => function($value) {
  125 + return strtotime($value) ? : time();
  126 + },
  127 + ],
  128 + [
  129 + [
  130 + 'categoryItems',
  131 + ],
  132 + 'safe',
  133 + ],
  134 + ];
  135 + }
  136 +
  137 + /**
  138 + * @inheritdoc
  139 + */
  140 + public function attributeLabels()
  141 + {
  142 + return [
  143 + 'id' => 'ID',
  144 + 'date' => 'Date',
  145 + 'date_end' => 'Date end',
  146 + 'title' => 'Title',
  147 + 'body' => 'Body',
  148 + 'body_preview' => 'Body preview',
  149 + 'image' => 'Image',
  150 + 'imageUrl' => Yii::t('app', 'Image'),
  151 + 'translit' => 'Translit',
  152 + 'meta_title' => 'Meta Title',
  153 + 'meta_keywords' => 'Meta Keywords',
  154 + 'meta_description' => 'Meta Description',
  155 + 'seo_text' => 'Seo Text',
  156 + 'h1' => 'H1',
  157 + ];
  158 + }
  159 +
  160 + public function getImageFile()
  161 + {
  162 + return empty( $this->image ) ? NULL : Yii::getAlias('@imagesDir/blog/' . $this->image);
  163 + }
  164 +
  165 + public function getImageUrl()
  166 + {
  167 + return empty( $this->image ) ? NULL : Yii::getAlias('@imagesUrl/blog/' . $this->image);
  168 + }
  169 +
  170 + /**
  171 + * @return ActiveQuery
  172 + */
  173 + public function getCategories()
  174 + {
  175 + return $this->hasMany(BlogCategory::className(), [ 'id' => 'category_id' ])
  176 + ->viaTable('blog_to_category', [ 'blog_id' => 'id' ]);
  177 + }
  178 +
  179 + public function getCategoryItemsAsArray()
  180 + {
  181 + return BlogCategory::find()
  182 + ->select('name')
  183 + ->indexBy('id')
  184 + ->asArray()
  185 + ->column();
  186 + }
  187 +
  188 + public function getCategoryItems()
  189 + {
  190 + return $this->_categoryItems;
  191 + }
  192 +
  193 + public function setCategoryItems($items)
  194 + {
  195 + $this->_categoryItems = $items;
  196 + }
36 197 }
37   -
38   - /**
39   - * @inheritdoc
40   - */
41   - public function behaviors()
42   - {
43   - return [
44   - 'slug' => [
45   - 'class' => 'common\behaviors\Slug',
46   - 'in_attribute' => 'title',
47   - 'out_attribute' => 'translit',
48   - 'translit' => true
49   - ],
50   - [
51   - 'class' => SaveImgBehavior::className(),
52   - ],
53   - ];
54   - }
55   -
56   - /**
57   - * @inheritdoc
58   - */
59   - public function rules()
60   - {
61   - return [
62   - [['date'], 'default', 'value' => function() {
63   - return time();
64   - }],
65   - [['date', 'date_end'], 'safe'],
66   - [['title', 'body'], 'required'],
67   - [['body', 'body_preview', 'seo_text'], 'string'],
68   - [['title', 'image', 'translit', 'meta_title', 'meta_keywords', 'meta_description', 'h1'], 'string', 'max' => 255],
69   - [['imageUpload'], 'safe'],
70   - [['imageUpload'], 'file', 'extensions' => 'jpg, gif, png'],
71   - [['date', 'date_end'], 'filter', 'filter' => function($value) {
72   - return strtotime($value)?:time();
73   - }],
74   - ];
75   - }
76   -
77   - /**
78   - * @inheritdoc
79   - */
80   - public function attributeLabels()
81   - {
82   - return [
83   - 'id' => 'ID',
84   - 'date' => 'Date',
85   - 'date_end' => 'Date end',
86   - 'title' => 'Title',
87   - 'body' => 'Body',
88   - 'body_preview' => 'Body preview',
89   - 'image' => 'Image',
90   - 'imageUrl' => Yii::t('app', 'Image'),
91   - 'translit' => 'Translit',
92   - 'meta_title' => 'Meta Title',
93   - 'meta_keywords' => 'Meta Keywords',
94   - 'meta_description' => 'Meta Description',
95   - 'seo_text' => 'Seo Text',
96   - 'h1' => 'H1',
97   - ];
98   - }
99   -
100   - public function getImageFile() {
101   - return empty($this->image) ? null : Yii::getAlias('@imagesDir/blog/'. $this->image);
102   - }
103   -
104   - public function getImageUrl()
105   - {
106   - return empty($this->image) ? null : Yii::getAlias('@imagesUrl/blog/' . $this->image);
107   - }
108   -}
... ...
common/models/BlogCategory.php 0 → 100644
  1 +<?php
  2 + namespace common\models;
  3 +
  4 + use yii\db\ActiveRecord;
  5 + use common\models\Blog;
  6 +
  7 + /**
  8 + * Class BlogCategory
  9 + * @package common\models
  10 + * @property Blog[] $blogs
  11 + */
  12 + class BlogCategory extends ActiveRecord
  13 + {
  14 +
  15 + /**
  16 + * @inheritdoc
  17 + * @return array
  18 + */
  19 + public function rules()
  20 + {
  21 + return [
  22 + [
  23 + [ 'name' ],
  24 + 'string',
  25 + ],
  26 + ];
  27 + }
  28 +
  29 + public static function tableName()
  30 + {
  31 + return 'blog_category';
  32 + }
  33 +
  34 + public function getBlogs()
  35 + {
  36 + return $this->hasMany(Blog::className(), [ 'id' => 'blog_id' ])
  37 + ->viaTable('blog_to_category', [ 'category_id' => 'id' ]);
  38 + }
  39 + }
... ...
common/models/BlogCategorySearch.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use Yii;
  6 +use yii\base\Model;
  7 +use yii\data\ActiveDataProvider;
  8 +use common\models\BlogCategory;
  9 +
  10 +/**
  11 + * BlogCategorySearch represents the model behind the search form about `common\models\BlogCategory`.
  12 + */
  13 +class BlogCategorySearch extends BlogCategory
  14 +{
  15 + /**
  16 + * @inheritdoc
  17 + */
  18 + public function rules()
  19 + {
  20 + return [
  21 + [['id'], 'integer'],
  22 + [['name'], 'safe'],
  23 + ];
  24 + }
  25 +
  26 + /**
  27 + * @inheritdoc
  28 + */
  29 + public function scenarios()
  30 + {
  31 + // bypass scenarios() implementation in the parent class
  32 + return Model::scenarios();
  33 + }
  34 +
  35 + /**
  36 + * Creates data provider instance with search query applied
  37 + *
  38 + * @param array $params
  39 + *
  40 + * @return ActiveDataProvider
  41 + */
  42 + public function search($params)
  43 + {
  44 + $query = BlogCategory::find();
  45 +
  46 + // add conditions that should always apply here
  47 +
  48 + $dataProvider = new ActiveDataProvider([
  49 + 'query' => $query,
  50 + ]);
  51 +
  52 + $this->load($params);
  53 +
  54 + if (!$this->validate()) {
  55 + // uncomment the following line if you do not want to return any records when validation fails
  56 + // $query->where('0=1');
  57 + return $dataProvider;
  58 + }
  59 +
  60 + // grid filtering conditions
  61 + $query->andFilterWhere([
  62 + 'id' => $this->id,
  63 + ]);
  64 +
  65 + $query->andFilterWhere(['like', 'name', $this->name]);
  66 +
  67 + return $dataProvider;
  68 + }
  69 +}
... ...
common/models/BlogToCategory.php 0 → 100644
  1 +<?php
  2 + namespace common\models;
  3 +
  4 + use yii\db\ActiveRecord;
  5 +
  6 + class BlogToCategory extends ActiveRecord
  7 + {
  8 +
  9 + public static function tableName()
  10 + {
  11 + return 'blog_to_category';
  12 + }
  13 + }
... ...
common/modules/product/views/manage/_form.php
... ... @@ -37,7 +37,7 @@
37 37 'prompt' => Yii::t('product', 'Select brand')
38 38 ]
39 39 ) ?>
40   -
  40 +
41 41 <?= $form->field($model, 'categories')->widget(Select2::className(), [
42 42 'data' => ArtboxTreeHelper::treeMap(ProductHelper::getCategories(), 'category_id', 'name'),
43 43 'language' => 'ru',
... ...
console/migrations/m160930_082338_add_categories_to_blog.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\db\Migration;
  4 +
  5 +class m160930_082338_add_categories_to_blog extends Migration
  6 +{
  7 + public function up()
  8 + {
  9 + $this->createTable('blog_category', [
  10 + 'id' => $this->primaryKey(),
  11 + 'name' => $this->string(),
  12 + ]);
  13 +
  14 + $this->createTable('blog_to_category', [
  15 + 'blog_id' => $this->integer(),
  16 + 'category_id' => $this->integer(),
  17 + ]);
  18 +
  19 + $this->createIndex('blog_to_category_key', 'blog_to_category', [
  20 + 'blog_id',
  21 + 'category_id',
  22 + ], true);
  23 +
  24 + $this->addForeignKey('blog_fk', 'blog_to_category', 'blog_id', 'blog', 'id', 'CASCADE', 'CASCADE');
  25 + $this->addForeignKey('blog_category_fk', 'blog_to_category', 'category_id', 'blog_category', 'id', 'CASCADE', 'CASCADE');
  26 +
  27 + }
  28 +
  29 + public function down()
  30 + {
  31 + $this->dropForeignKey('blog_category_fk', 'blog_to_category');
  32 + $this->dropForeignKey('blog_fk', 'blog_to_category');
  33 +
  34 + $this->dropIndex('blog_to_category_key', 'blog_to_category');
  35 +
  36 + $this->dropTable('blog_to_category');
  37 + $this->dropTable('blog_category');
  38 + }
  39 +}
... ...
frontend/controllers/BlogController.php
... ... @@ -3,7 +3,9 @@
3 3 namespace frontend\controllers;
4 4  
5 5 use common\models\Blog;
  6 + use common\models\BlogCategory;
6 7 use yii\data\ActiveDataProvider;
  8 + use yii\helpers\VarDumper;
7 9 use yii\web\Controller;
8 10 use yii\web\NotFoundHttpException;
9 11  
... ... @@ -45,11 +47,38 @@
45 47 public function actionView($id)
46 48 {
47 49 $model = $this->findModel($id);
  50 + $categories = $model->categories;
48 51 return $this->render('view', [
49 52 'model' => $model,
50 53 ]);
51 54 }
52 55  
  56 + public function actionCategory($id)
  57 + {
  58 + $model = BlogCategory::find()
  59 + ->where([
  60 + 'id' => $id,
  61 + ])
  62 + ->one();
  63 + $query = $model->getBlogs();
  64 + $dataProvider = new ActiveDataProvider([
  65 + 'query' => $query,
  66 + 'pagination' => [
  67 + 'pageSize' => 4
  68 + ,
  69 + ],
  70 + 'sort' => [
  71 + 'defaultOrder' => [
  72 + 'date' => SORT_DESC,
  73 + ]
  74 + ],
  75 + ]);
  76 + return $this->render('category', [
  77 + 'model' => $model,
  78 + 'dataProvider' => $dataProvider,
  79 + ]);
  80 + }
  81 +
53 82 private function findModel($id) {
54 83 $model = Blog::findOne($id);
55 84 if(!empty($model)) {
... ...
frontend/views/blog/category.php 0 → 100755
  1 +<?php
  2 +
  3 +use common\modules\product\models\Category;
  4 +use yii\data\ActiveDataProvider;
  5 +use yii\web\View;
  6 +use yii\widgets\ListView;
  7 +
  8 +/**
  9 + * @var Category $category
  10 + * @var ActiveDataProvider $dataProvider
  11 + * @var View $this
  12 + */
  13 +$this->title = "Блог";
  14 +$this->params[ 'breadcrumbs' ][] = $this->title;
  15 +
  16 +?>
  17 +
  18 +<div class="col-md-12">
  19 + <?php
  20 +
  21 + echo ListView::widget([
  22 + 'dataProvider' => $dataProvider,
  23 + 'options' => [
  24 + 'tag' => false,
  25 + ],
  26 + 'pager' => [
  27 + 'prevPageCssClass' => 'left_pg',
  28 + 'nextPageCssClass' => 'right_pg',
  29 + 'activePageCssClass' => 'active',
  30 + 'disabledPageCssClass' => '',
  31 + 'firstPageLabel' => false,
  32 + ],
  33 + 'itemView' => '_blog_item',
  34 + 'layout' => '{items}{pager}',
  35 + ]);
  36 +
  37 + ?>
  38 +</div>
... ...
frontend/views/blog/index.php
... ... @@ -36,12 +36,4 @@ $this-&gt;params[ &#39;breadcrumbs&#39; ][] = $this-&gt;title;
36 36 ]);
37 37  
38 38 ?>
39   -
40   -<!-- <ul class="pages">-->
41   -<!-- <li><a href="#" class="left_pg"></a></li>-->
42   -<!-- <li><a href="#" class="active">1</a></li>-->
43   -<!-- <li><a href="#">2</a></li>-->
44   -<!-- <li><a href="#">3</a></li>-->
45   -<!-- <li><a href="#" class="right_pg"></a></li>-->
46   -<!-- </ul>-->
47 39 </div>
... ...
frontend/views/comments/_form.php 0 → 100755
  1 +<?php
  2 + use common\modules\comment\models\CommentModel;
  3 + use common\modules\comment\models\RatingModel;
  4 + use yii\base\Model;
  5 + use yii\helpers\Html;
  6 + use yii\helpers\Url;
  7 + use yii\web\View;
  8 + use yii\widgets\ActiveForm;
  9 +
  10 + /**
  11 + * @var CommentModel $comment_model
  12 + * @var array $form_params
  13 + * @var Model $model
  14 + * @var string $formId
  15 + * @var View $this
  16 + * @var RatingModel|NULL $rating_model
  17 + */
  18 + $form = ActiveForm::begin([
  19 + 'id' => $formId,
  20 + 'action' => Url::to([
  21 + 'artbox-comment/default/create',
  22 + 'entity' => $comment_model->encryptedEntity,
  23 + ]),
  24 + ]);
  25 +?>
  26 + <div class="form-comm-wr">
  27 + <?php
  28 + echo $form->field($comment_model, 'username', [ 'options' => [ 'class' => 'form-group input_bl' ] ])
  29 + ->textInput();
  30 + echo $form->field($comment_model, 'email', [ 'options' => [ 'class' => 'form-group input_bl' ] ])
  31 + ->textInput();
  32 +
  33 + echo $form->field($comment_model, 'text', [ 'options' => [ 'class' => 'form-group input_bl area_bl' ] ])
  34 + ->textarea();
  35 + echo Html::tag('div', Html::submitButton(Yii::t('artbox-comment', 'Submit')), [ 'class' => 'input_bl submit_btn' ]);
  36 + ?>
  37 + </div>
  38 +<?php
  39 + ActiveForm::end();
  40 +?>
0 41 \ No newline at end of file
... ...
frontend/views/comments/_item.php 0 → 100755
  1 +<?php
  2 + use common\modules\comment\models\CommentModel;
  3 + use yii\helpers\Html;
  4 + use yii\helpers\Url;
  5 + use yii\widgets\ListView;
  6 +
  7 + /**
  8 + * @var CommentModel $model
  9 + * @var mixed $key
  10 + * @var int $index
  11 + * @var ListView $widget
  12 + */
  13 +?>
  14 +<div class="comments-wr">
  15 + <div class="artbox_item_info">
  16 + <div class="user-ico">
  17 + <?php
  18 + echo Html::img('/img/user-noimage.png');
  19 + ?>
  20 + </div>
  21 + <div class="user_data" itemprop="datePublished">
  22 + <?php
  23 + echo date('d.m.Y', $model->date_add);
  24 + ?>
  25 + </div>
  26 + <div class="user_name" itemprop="author">
  27 + <?php
  28 + if(!empty( $model->user )) {
  29 + echo $model->user->username;
  30 + } else {
  31 + echo $model->username . ' (' . Yii::t('artbox-comment', 'Guest') . ')';
  32 + }
  33 + ?>
  34 + </div>
  35 + <?php
  36 + if(!empty( $model->rating )) {
  37 + ?>
  38 + <div class="user_rating" itemprop="reviewRating" itemscope itemtype="http://schema.org/Rating">
  39 + <span itemprop="worstRating" style="display: none">1</span>
  40 + <span itemprop="ratingValue" style="display: none"><?php echo $model->rating->value; ?></span>
  41 + <span itemprop="bestRating" style="display: none">5</span>
  42 + <div class="rateit" data-rateit-value="<?php echo $model->rating->value; ?>" data-rateit-ispreset="true" data-rateit-readonly="true"></div>
  43 + </div>
  44 + <?php
  45 + }
  46 + ?>
  47 + <div class="user_txt" itemprop="description">
  48 + <?php
  49 + echo $model->text;
  50 + ?>
  51 + </div>
  52 + </div>
  53 + <div class="artbox_item_tools comment-panel">
  54 + <?php
  55 + if(!\Yii::$app->user->isGuest) {
  56 + ?>
  57 + <a href="" class="btn-comm-answer" data-action="reply">Ответить</a>
  58 + <?php
  59 + }
  60 + if(!\Yii::$app->user->isGuest && \Yii::$app->user->id == $model->user_id) {
  61 + ?>
  62 + <a href="" class="btn-comm-delete" data-action="delete" data-url="<?php echo Url::to([
  63 + 'artbox-comment/default/delete',
  64 + 'id' => $model->artbox_comment_id,
  65 + ]); ?>">Удалить</a>
  66 + <?php
  67 + }
  68 + // Like / dislike to be done
  69 + /*
  70 + ?>
  71 + <a href="" class="btn-comm-like" data-action="like" data-url="<?php echo Url::to([
  72 + 'artbox-comment/default/like',
  73 + 'id' => $model->artbox_comment_id,
  74 + ]); ?>">Like</a>
  75 + <a href="" class="btn-comm-dislike" data-action="dislike" data-url="<?php echo Url::to([
  76 + 'artbox-comment/default/dislike',
  77 + 'id' => $model->artbox_comment_id,
  78 + ]); ?>">Dislike</a>
  79 + <?php
  80 + */
  81 + ?>
  82 + <div class="artbox_item_reply"></div>
  83 + </div>
  84 +</div>
  85 +<div class="artbox_children_container">
  86 + <?php
  87 + if(!empty( $model->children )) {
  88 + foreach($model->children as $index => $child) {
  89 + ?>
  90 + <div class="artbox_child_container comment-answer">
  91 + <div class="artbox_child_info">
  92 + <div class="user-ico">
  93 + <?php
  94 + echo Html::img('/img/user-noimage.png');
  95 + ?>
  96 + </div>
  97 + <div class="user_data">
  98 + <?php
  99 + echo date('d.m.Y', $child->date_add);
  100 + ?>
  101 + </div>
  102 + <div class="user_name">
  103 + <?php
  104 + if(!empty( $child->user )) {
  105 + echo $child->user->username;
  106 + } else {
  107 + echo $child->username . ' (' . Yii::t('artbox-comment', 'Guest') . ')';
  108 + }
  109 + ?>
  110 + </div>
  111 + <div class="user_txt">
  112 + <?php
  113 + echo $child->text;
  114 + ?>
  115 + </div>
  116 + </div>
  117 + <div class="artbox_child_tools comment-panel">
  118 + <?php
  119 + if(!\Yii::$app->user->isGuest) {
  120 + ?>
  121 + <a href="" class="btn-comm-answer" data-action="reply">Ответить</a>
  122 + <?php
  123 + }
  124 + if(!\Yii::$app->user->isGuest && \Yii::$app->user->id == $child->user_id) {
  125 + ?>
  126 + <a href="" class="btn-comm-delete" data-action="delete" data-url="<?php echo Url::to([
  127 + 'artbox-comment/default/delete',
  128 + 'id' => $child->artbox_comment_id,
  129 + ]); ?>">Удалить</a>
  130 + <?php
  131 + }
  132 + /* Like /dislike to be done
  133 + ?>
  134 + <a href="" class="btn-comm-like" data-action="like" data-url="<?php echo Url::to([
  135 + 'artbox-comment/default/like',
  136 + 'id' => $child->artbox_comment_id,
  137 + ]); ?>">Like</a>
  138 + <a href="" class="btn-comm-dislike" data-action="dislike" data-url="<?php echo Url::to([
  139 + 'artbox-comment/default/dislike',
  140 + 'id' => $child->artbox_comment_id,
  141 + ]); ?>">Dislike</a>
  142 + <?php
  143 + */
  144 + ?>
  145 + <div class="artbox_child_reply"></div>
  146 + </div>
  147 + </div>
  148 + <?php
  149 + }
  150 + }
  151 + ?>
  152 +</div>
  153 +
... ...
frontend/views/comments/_list.php 0 → 100755
  1 +<?php
  2 + use common\modules\comment\models\CommentModel;
  3 + use yii\base\Model;
  4 + use yii\data\ActiveDataProvider;
  5 + use yii\helpers\Html;
  6 + use yii\web\View;
  7 + use yii\widgets\ListView;
  8 + use yii\widgets\Pjax;
  9 +
  10 + /**
  11 + * @var CommentModel $comment_model
  12 + * @var array $list_params
  13 + * @var array $item_options
  14 + * @var string $item_view
  15 + * @var Model $model
  16 + * @var ActiveDataProvider $comments
  17 + * @var View $this
  18 + */
  19 + Pjax::begin();
  20 + if(($success = \Yii::$app->session->getFlash('artbox_comment_success')) != null) {
  21 + echo Html::tag('p', $success);
  22 + }
  23 + echo ListView::widget([
  24 + 'dataProvider' => $comments,
  25 + 'itemOptions' => $item_options,
  26 + 'itemView' => $item_view,
  27 + 'summary' => '',
  28 + ]);
  29 + Pjax::end();
  30 +
0 31 \ No newline at end of file
... ...
frontend/views/comments/index.php
1 1 <?php
2   -/**
3   - * @var Comments $comments
4   - */
5   -use common\models\Comments;
6   -use common\modules\comment\widgets\CommentWidget;
  2 + /**
  3 + * @var Comments $comments
  4 + */
  5 + use common\models\Comments;
  6 + use common\modules\comment\widgets\CommentWidget;
7 7  
8 8 ?>
9 9  
10   -
  10 +<!-- =========================================================== -->
11 11 <?php
12   -$comments = new Comments([
13   - 'id' => 1,
14   -]);
15   -echo CommentWidget::widget([
16   - 'model' => $comments,
17   - 'entityIdAttribute' => 'id'
18   -]);
19   -?>
20 12 \ No newline at end of file
  13 + $comments = new Comments([
  14 + 'id' => 1,
  15 + ]);
  16 + echo CommentWidget::widget([
  17 + 'model' => $comments,
  18 + 'entityIdAttribute' => 'id',
  19 + 'layout' => '{list}{form}',
  20 + 'formView' => '@frontend/views/comments/_form',
  21 + 'listView' => '@frontend/views/comments/_list',
  22 + 'itemView' => '@frontend/views/comments/_item',
  23 + ]);
  24 +?>
  25 +<!-- =========================================================== -->
  26 +<div class="otzivi_block">
  27 + <div class="title9">Отзывы</div>
  28 + <div class="start_otzivi">
  29 + <div class="title">Уважаемые клиенты и партнеры,</div>
  30 + <div>мы с благодарностью принимаем ваши пожелания и замечания относительно проведенных мероприятий и качества обслуживания в шоу-руме "Baccara Home"</div>
  31 + </div>
  32 + <div class="comments_block">
  33 +
  34 + <div class="artbox_item_container" itemprop="review" itemscope="itemscope" itemtype="http://schema.org/Review" data-key="1">
  35 + <div class="comments-wr">
  36 + <div class="artbox_item_info">
  37 + <div class="user_data" itemprop="datePublished">Сентябрь 10, 2016</div>
  38 + <div class="user_name" itemprop="author">Светлана</div>
  39 + <div class="user_txt" itemprop="description">Заказали на всю квартиру обои. Все хорошо, но был задержан один вид обоев к установленному сроку. Приятно, что это компенсировали доставкой. В целом мы остались довольны.</div>
  40 + </div>
  41 + <div class="artbox_item_tools comment-panel">
  42 + <div class="artbox_item_reply"></div>
  43 + </div>
  44 + </div>
  45 + <div class="artbox_children_container">
  46 + </div>
  47 + </div>
  48 +
  49 + </div>
  50 + <div class="otz_buttons">
  51 + <a href="#" class="btn_otz more1">Больше отзывов</a>
  52 + <a href="#" class="btn_otz write">Написать отзыв</a>
  53 + </div>
  54 + <div class="add_comment">
  55 + <div class="title">Мы обязательно рассмотрим все отзывы!</div>
  56 + <div class="close_comm"></div>
  57 + <div id="artbox-comment" class="artbox_comment_container comments-start">
  58 + <div class='comments-border'></div>
  59 + <div class="artbox_form_container">
  60 + <form id="artbox-comment-form" action="/artbox-comment/default/create?entity=%F5%40k%3E%A3%E2O%84gdp%3C%01%09%C9%BD54209f45051223919c32fe61aca45881a14133a988ba1fe383633a051f60ae8b%8D%AB%D4%ED%B7%EB.%18%FE%C1D%9D%DCo%CE%CD%DF%ED%08%1C%13%7B%C6%AEK%2B%28z%E22%C3%AB%88%C6%3A%D2%DD1%BCg%18%D6%ED%CDF%B6%D2%AA%1A%B3%92%08%E1d0%CD%B8%B6%8D%05%EFF%B6%21%05%C9%7C%93%E5%CE%94%D1%F9%F1%2BL%3C%8BJ%CC" method="post">
  61 + <input type="hidden" name="_frontendCSRF" value="TWl1TjU0X1gkMRR6DUYeMX9cGAtlTQgMKjonLARYBR8CATI8V1krbg==">
  62 + <div class="form-comm-wr">
  63 + <div class="form-group input_bl area_bl field-commentmodel-text required">
  64 + <textarea id="commentmodel-text" class="form-control" name="CommentModel[text]" placeholder="Комментарий" rows="8"></textarea>
  65 +
  66 + <div class="help-block"></div>
  67 + </div>
  68 + <div class="form-group input_bl field-commentmodel-username required">
  69 + <input type="text" id="commentmodel-username" class="form-control" name="CommentModel[username]" placeholder="Имя / Компания">
  70 +
  71 + <div class="help-block"></div>
  72 + </div>
  73 + <div class="form-group input_bl field-commentmodel-email required">
  74 + <input type="text" id="commentmodel-email" class="form-control" name="CommentModel[email]" placeholder="E-mail">
  75 +
  76 + <div class="help-block"></div>
  77 + </div>
  78 + <div class="input_bl submit_btn">
  79 + <button type="submit">Отправить</button>
  80 + </div>
  81 + </div>
  82 + </form>
  83 + </div>
  84 + <div id="artbox-comment-list" class="artbox_list_container">
  85 + <div id="w1" data-pjax-container="" data-pjax-push-state data-pjax-timeout="1000">
  86 + <div id="w2" class="list-view">
  87 + </div>
  88 + </div>
  89 + </div>
  90 + </div>
  91 + </div>
  92 +</div>
  93 +
... ...
frontend/web/css/style.css 100755 → 100644
... ... @@ -202,45 +202,6 @@ footer .socbuts ul li{
202 202 footer .socbuts a:hover{
203 203 opacity:0.6;
204 204 }
205   -.pagination{
206   - display: flex;
207   - justify-content: center;
208   - margin: 56px 0px;
209   -}
210   -.pagination, .pagination a, .pagination span{
211   - font-family: Arial, sans-serif!important;
212   - font-weight: bold;
213   - color:#9b9999!important;
214   - font-size: 12px;
215   - background-position: center;
216   - background-repeat: no-repeat;
217   -}
218   -.pagination li a, .pagination li span{
219   - padding: 1px 8.5px;
220   -}
221   -
222   -.pagination .active a{
223   - background-color: initial!important;
224   - border-color: #d2d2d2!important;
225   - color:#000!important;
226   -}
227   -.pagination .left_pg span, .pagination .right_pg span, .pagination .left_pg a, .pagination .right_pg a{
228   - background-color: #d2d2d2;
229   - padding: 1px 9.5px;
230   -}
231   -.pagination .left_pg a, .pagination .left_pg span{
232   - background-image: url(../images/left_ar.png);
233   - font-size:0px;
234   - width: 28px;
235   - height: 21px;
236   -}
237   -.pagination .right_pg a, .pagination .right_pg span{
238   - background-image: url(../images/right_ar.png);
239   - font-size:0px;
240   - width: 28px;
241   - height: 21px;
242   -}
243   -
244 205 .main-box1{
245 206 min-height:300px;
246 207 text-align: center;
... ... @@ -754,14 +715,11 @@ footer .socbuts a:hover{
754 715 }
755 716 .post_1.contract img{max-height:222px;}
756 717 .blocks{text-align: center;letter-spacing: normal;text-transform: uppercase;margin-top: 36px;margin-left: 9px;}
757   -.blocks .title{
758   -
759   - padding: 17px 0px 9px 0px;
760   -}
761   -.blocks .title a{
  718 +.blocks a .title{
762 719 font-size: 14px;
763 720 font-family: 'Lato-Medium';
764 721 font-weight: bold;
  722 + padding: 17px 0px 9px 0px;
765 723 }
766 724 .blocks a:hover{color:black!important;}
767 725 .b1{padding-bottom: 44px;}
... ... @@ -1028,18 +986,18 @@ footer .socbuts a:hover{
1028 986 }
1029 987 .spoiler .control-label{display: none;}
1030 988 .spoiler input[type=checkbox], input[type=radio] {
1031   - /*margin: 1px 0 0;*/
1032   - /*opacity: 0;*/
1033   - /*margin-right: 7px;*/
  989 + margin: 1px 0 0;
  990 + opacity: 0;
  991 + margin-right: 7px;
1034 992 }
1035 993 .spoiler label {
1036   - display: inline;
  994 + display: inline-block;
1037 995 max-width: 100%;
1038 996 font-weight: 700;
1039 997 width: 100%;
1040 998 letter-spacing: 0.4px;
1041 999 margin-bottom: 0px;
1042   - /*background: url('../images/knopka.png');*/
  1000 + background: url('../images/knopka.png');
1043 1001 background-position: left 5px;
1044 1002 background-repeat: no-repeat;
1045 1003 }
... ... @@ -1125,9 +1083,47 @@ footer .socbuts a:hover{
1125 1083 line-height: 18px;
1126 1084 margin-bottom: 28px;
1127 1085 }
  1086 +.pagination{
  1087 + text-align: center;
  1088 + list-style: none;
  1089 + display: flex;
  1090 + justify-content: center;
  1091 + margin: 56px 0px;
  1092 +}
1128 1093 a.active{
1129 1094 cursor: default;
1130 1095 }
  1096 +.pagination li a{
  1097 + width: 21px;
  1098 + height: 21px;
  1099 + display: flex;
  1100 + text-align: center;
  1101 + font-family: 'Arial Bold', Arial, sans-serif;
  1102 + font-weight: bold;
  1103 + line-height: 2px;
  1104 + justify-content: center;
  1105 + align-items: center;
  1106 + border: 1px solid #d2d2d2;
  1107 + margin-right: -1px;
  1108 + color: #9b9999;
  1109 + font-size: 12px;
  1110 +}
  1111 +.pagination .left_pg{
  1112 + background-image: url('../images/left_ar.png');
  1113 +}
  1114 +.pagination .right_pg{
  1115 + background-image: url('../images/right_ar.png');
  1116 +}
  1117 +.pagination .left_pg, .pagination .right_pg{
  1118 + background-color: #d2d2d2;
  1119 + padding: 0px 14px;
  1120 + background-repeat: no-repeat;
  1121 + background-position: center center;
  1122 +}
  1123 +.pagination .left_pg, .pagination .right_pg:hover{
  1124 + border:1px solid rgba(0,0,0,0);
  1125 +}
  1126 +.pagination li a.active, .pagination li a.active:hover{color:black;}
1131 1127 .more_colls{
1132 1128 background-color: #decfc8;
1133 1129 text-transform: uppercase;
... ... @@ -1513,7 +1509,7 @@ p.right{text-align: right;}
1513 1509 }
1514 1510 .collection .head img{
1515 1511 max-width:960px;
1516   - /*width:100%;*/
  1512 + width:100%;
1517 1513 }
1518 1514 .cols{max-width: 960px;margin: 40px auto 25px;}
1519 1515 .cols a{
... ... @@ -1604,7 +1600,58 @@ p.right{text-align: right;}
1604 1600 margin: 0px;
1605 1601 }
1606 1602 .dropd_menu div:first-child .title:after{display: none;}
  1603 +.pagination li a {
  1604 + width: 21px!important;
  1605 + height: 21px!important;
  1606 + display: flex!important;
  1607 + text-align: center!important;
  1608 + font-family: 'Arial Bold', Arial, sans-serif!important;
  1609 + font-weight: bold!important;
  1610 + line-height: 2px!important;
  1611 + justify-content: center!important;
  1612 + align-items: center!important;
  1613 + border: 1px solid #d2d2d2!important;
  1614 + margin-right: -1px!important;
  1615 + color: #9b9999!important;
  1616 + font-size: 12px!important;
  1617 + background-position: center;
  1618 + background-repeat: no-repeat;
  1619 +}
1607 1620  
  1621 +.pagination span{
  1622 + width: 28px;
  1623 + height: 21px!important;
  1624 + display: flex!important;
  1625 + text-align: center!important;
  1626 + font-family: 'Arial Bold', Arial, sans-serif!important;
  1627 + font-weight: bold!important;
  1628 + line-height: 2px!important;
  1629 + justify-content: center!important;
  1630 + align-items: center!important;
  1631 + border: 1px solid #d2d2d2!important;
  1632 + margin-right: -1px!important;
  1633 + color: #9b9999!important;
  1634 + font-size: 12px!important;
  1635 + background-color: #d2d2d2;
  1636 + text-indent: -999px;
  1637 + background-position: center;
  1638 + background-repeat: no-repeat;
  1639 +}
  1640 +.pagination .prev a, .pagination .prev span{
  1641 + background-image: url(../images/left_ar.png);
  1642 + width: 30px!important;
  1643 + text-indent: 100px;
  1644 + overflow: hidden;
  1645 + background-color: #d2d2d2;
  1646 +}
  1647 +.pagination .next a, .pagination .next span{
  1648 + background-image: url('../images/right_ar.png');
  1649 + width: 30px!important;
  1650 + text-indent: 100px;
  1651 + overflow: hidden;
  1652 + background-color: #d2d2d2;
  1653 +}
  1654 +.pagination .active a{color:#000!important;background-color:white!important;}
1608 1655  
1609 1656 .action{max-width:260px;margin-bottom: 10px;}
1610 1657 .action img{width:100%; max-width:227px;}
... ... @@ -1649,7 +1696,25 @@ p.right{text-align: right;}
1649 1696 font-weight: 600;
1650 1697 }
1651 1698 .act_d{margin-top:66px;}
1652   -.act_d p{color:#878686;font-family: 'Lato-Light';font-weight: 600;font-size:15px;letter-spacing: 0.4px;}
  1699 +.act_d p{
  1700 + color: #878686;
  1701 + font-family: 'Lato-Light';
  1702 + font-weight: 600;
  1703 + font-size: 15px;
  1704 + letter-spacing: 0.4px;
  1705 + height: 24px;
  1706 + overflow: hidden;
  1707 + transition:0.2s;
  1708 +}
  1709 +.act_d p.opened{
  1710 + height: initial;
  1711 +}
  1712 +
  1713 +.left_pg, .right_pg{
  1714 + max-height: 21px;
  1715 + width: 28px;
  1716 + overflow: hidden;
  1717 +}
1653 1718  
1654 1719 /**/
1655 1720 .dropd_menu:before {
... ... @@ -1746,4 +1811,162 @@ p.right{text-align: right;}
1746 1811 @media (max-width: 379px) {
1747 1812 .main-box1 img{width:100%;}
1748 1813 .blog_link img{width: 100%;}
  1814 +}
  1815 +
  1816 +
  1817 +/* OTZIVI */
  1818 +.form-comm-wr .input_bl, .form-comm-wr .help-block{
  1819 + margin: 0;
  1820 + padding: 0;
  1821 +}
  1822 +.artbox_item_info .user_data, .artbox_item_info .user_name{
  1823 + color: #7e7e82;
  1824 + font-size:14px;
  1825 + display: inline-block;
  1826 +}
  1827 +.artbox_item_info .user_name:before{
  1828 + content:'/ ';
  1829 +}
  1830 +.artbox_item_info .user_txt{
  1831 + color: #343333;
  1832 + font-size: 15px;
  1833 + font-family: 'Lato-Light';
  1834 + font-weight: 600;
  1835 + padding-top: 11px;
  1836 + line-height: 20px;
  1837 +}
  1838 +.otzivi_block{
  1839 + width:100%;
  1840 + max-width: 865px;
  1841 + float: none;
  1842 + margin: 0 auto;
  1843 + padding-bottom: 140px;
  1844 +}
  1845 +.artbox_item_info{
  1846 + border-top: 1px solid #d9d9d9;
  1847 + padding-top: 18px;
  1848 + padding-bottom: 27px;
  1849 +}
  1850 +.comments_block{
  1851 + border-bottom: 1px solid #d9d9d9;
  1852 +}
  1853 +.title9{
  1854 + color: #847e7e;
  1855 + font-size: 24px;
  1856 + text-transform: uppercase;
  1857 + font-family: 'Lato-Light';
  1858 + font-weight: 600;
  1859 + margin-top: 10px;
  1860 + margin-bottom: 11px;
  1861 +}
  1862 +.start_otzivi{
  1863 + text-align: center;
  1864 + text-transform: uppercase;
  1865 + color: #000000;
  1866 + font-size: 15px;
  1867 + line-height: 26px;
  1868 + font-family: 'Lato-Light';
  1869 + font-weight: 600;
  1870 + margin-bottom: 15px;
  1871 + max-width: 640px;
  1872 + margin-left: auto;
  1873 + margin-right: auto;
  1874 +}
  1875 +.start_otzivi .title{
  1876 + font-size:18px;
  1877 +}
  1878 +.form-comm-wr input, .form-comm-wr textarea{
  1879 + text-transform: uppercase;
  1880 + font-size: 11px;
  1881 + font-weight: 900;
  1882 + border-radius: 0px;
  1883 + margin-top:-1px;
  1884 + outline: none;
  1885 + resize: none;
  1886 + padding:14px;
  1887 + letter-spacing: 0.5px;
  1888 + box-shadow: none!important;
  1889 + border: 1px solid rgb(204, 204, 204)!important;
  1890 +}
  1891 +.input_bl.submit_btn{
  1892 + text-align:center;
  1893 + padding: 15px 0px;
  1894 +}
  1895 +.input_bl.submit_btn button{
  1896 + border: 1px solid #9e9e9e;
  1897 + background-color: #fff;
  1898 + outline: none;
  1899 + text-transform: uppercase;
  1900 + font-size: 11px;
  1901 + font-weight: 600;
  1902 + color: #9e9e9e;
  1903 + letter-spacing: 1px;
  1904 + padding: 5px 17px;
  1905 + transition:0.1s;
  1906 +}
  1907 +.input_bl.submit_btn button:hover{
  1908 + background-color:#9e9e9e;
  1909 + color:#fff;
  1910 +}
  1911 +.add_comment{
  1912 + display: none;
  1913 + margin-top: 40px!important;
  1914 +}
  1915 +.add_comment, .add_comment .artbox_comment_container.comments-start{
  1916 + position: relative;
  1917 + max-width: 705px;
  1918 + margin: 0 auto;
  1919 +}
  1920 +.otz_buttons{
  1921 + text-align: center;
  1922 + text-transform: uppercase;
  1923 + font-size: 11px;
  1924 + font-weight: 600;
  1925 + letter-spacing: 1px;
  1926 + margin: 44px 0px;
  1927 +}
  1928 +.otz_buttons a{
  1929 + background-color:#e4e4e4;
  1930 + padding: 11px;
  1931 + padding-bottom: 10px;
  1932 + margin: 10px;
  1933 + background-image: url(../images/arrow_down_bold.png);
  1934 + background-repeat: no-repeat;
  1935 + background-position-y: center;
  1936 +}
  1937 +.otz_buttons .btn_otz.more1{
  1938 + padding-right: 15px;
  1939 + padding-left: 38px;
  1940 + background-position-x: 17px;
  1941 +}
  1942 +.otz_buttons .btn_otz.write{
  1943 + padding-right: 42px;
  1944 + padding-left: 16px;
  1945 + background-position-x: calc(100% - 16px);
  1946 +}
  1947 +.otz_buttons a:hover{
  1948 + background-color:#ebdbd4!important;
  1949 + color:#000;
  1950 +}
  1951 +.add_comment .title{
  1952 + text-align: center;
  1953 + text-transform: uppercase;
  1954 + font-size: 15px;
  1955 + color: #000000;
  1956 + font-family: 'Lato-Light';
  1957 + font-weight: 600;
  1958 + padding: 14px;
  1959 +}
  1960 +.close_comm{
  1961 + position: absolute;
  1962 + top: 16px;
  1963 + right: 0;
  1964 + width: 27px;
  1965 + height: 27px;
  1966 + background-image:url('../images/close.png');
  1967 + transition:0.1s;
  1968 + cursor: pointer;
  1969 +}
  1970 +.close_comm:hover{
  1971 + background-image:url('../images/close_hover.png');
1749 1972 }
1750 1973 \ No newline at end of file
... ...