diff --git a/backend/config/main.php b/backend/config/main.php
index 1c68330..6e718ad 100755
--- a/backend/config/main.php
+++ b/backend/config/main.php
@@ -26,7 +26,7 @@
'alias' => 'artbox\core\seo\controllers\AliasController',
'seo' => 'artbox\core\controllers\SeoController',
'feedback' => 'artbox\core\controllers\FeedbackController',
- 'blog' => 'artbox\weblog\controllers\ArticleController',
+ 'blog' => 'backend\controllers\ArticleController',
'blog-category' => 'artbox\weblog\controllers\CategoryController',
'blog-tag' => 'artbox\weblog\controllers\TagController',
'comment' => 'artbox\webcomment\controllers\ManageController',
diff --git a/backend/controllers/ArticleController.php b/backend/controllers/ArticleController.php
new file mode 100755
index 0000000..485ca58
--- /dev/null
+++ b/backend/controllers/ArticleController.php
@@ -0,0 +1,343 @@
+ [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => [ 'POST' ],
+ ],
+ ],
+ 'access' => [
+ 'class' => AccessControl::className(),
+ 'rules' => [
+ [
+ 'actions' => [
+ 'login',
+ 'error',
+ ],
+ 'allow' => true,
+ ],
+ [
+ 'allow' => true,
+ 'roles' => [ '@' ],
+ ],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Lists all BlogArticle models.
+ *
+ * @return mixed
+ */
+ public function actionIndex()
+ {
+ $searchModel = new ArticleSearch();
+ $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
+
+ return $this->render(
+ 'index',
+ [
+ 'searchModel' => $searchModel,
+ 'dataProvider' => $dataProvider,
+ ]
+ );
+ }
+
+ /**
+ * Displays a single BlogArticle model.
+ *
+ * @param integer $id
+ *
+ * @return mixed
+ */
+ public function actionView($id)
+ {
+ return $this->render(
+ 'view',
+ [
+ 'model' => $this->findModel($id),
+ ]
+ );
+ }
+
+ /**
+ * Creates a new BlogArticle model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ *
+ * @return mixed
+ */
+ public function actionCreate()
+ {
+ $model = new Article();
+ $model->generateLangs();
+
+ if (class_exists('\artbox\catalog\models\Product')) {
+ $model->productIds = ArrayHelper::map(
+ $model->relatedProducts,
+ 'id',
+ 'lang.title'
+ );
+ }
+
+ if ($model->loadWithLangs(\Yii::$app->request) && $model->saveWithLangs()) {
+
+ $categories = Category::find()
+ ->where([ 'id' => \Yii::$app->request->post('categoryIds') ])
+ ->all();
+
+ if (class_exists('\artbox\catalog\models\Product')) {
+ /**
+ * @var \yii\db\ActiveQuery $query
+ */
+ $query = call_user_func(
+ [
+ '\artbox\catalog\models\Product',
+ 'find',
+ ]
+ );
+ /**
+ * @var \artbox\catalog\models\Product[] $products
+ */
+ $products = $query->where([ 'id' => \Yii::$app->request->post('productIds') ])
+ ->all();
+
+ $model->linkMany('relatedProducts', $products);
+ }
+
+
+ $model->linkMany('categories', $categories);
+
+ $tags = Tag::find()
+ ->where(
+ [
+ 'id' => \Yii::$app->request->post('tagIds'),
+ ]
+ )
+ ->all();
+
+ $model->linkMany('tags', $tags);
+
+ return $this->redirect(
+ [
+ 'view',
+ 'id' => $model->id,
+ ]
+ );
+ }
+
+ return $this->render(
+ 'create',
+ [
+ 'model' => $model,
+ 'modelLangs' => $model->modelLangs,
+ ]
+ );
+
+ }
+
+ /**
+ * Updates an existing BlogArticle model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ *
+ * @param integer $id
+ *
+ * @return mixed
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+ $model->generateLangs();
+
+ $model->categoryIds = ArrayHelper::map(
+ $model->categories,
+ 'id',
+ 'lang.title'
+ );
+
+ $model->tagIds = ArrayHelper::map(
+ $model->tags,
+ 'id',
+ 'lang.label'
+ );
+
+ $model->articleIds = ArrayHelper::map(
+ $model->articles,
+ 'id',
+ 'lang.title'
+ );
+
+ if (class_exists('\artbox\catalog\models\Product')) {
+ $model->productIds = ArrayHelper::map(
+ $model->relatedProducts,
+ 'id',
+ 'lang.title'
+ );
+ }
+
+ if ($model->loadWithLangs(\Yii::$app->request) && $model->saveWithLangs()) {
+ $categories = Category::find()
+ ->where([ 'id' => \Yii::$app->request->post('categoryIds') ])
+ ->all();
+
+ $model->linkMany('categories', $categories);
+
+ $tags = Tag::find()
+ ->where(
+ [
+ 'id' => \Yii::$app->request->post('tagIds'),
+ ]
+ )
+ ->all();
+
+ $model->linkMany('tags', $tags);
+
+ if (class_exists('\artbox\catalog\models\Product')) {
+ /**
+ * @var \yii\db\ActiveQuery $query
+ */
+ $query = call_user_func(
+ [
+ '\artbox\catalog\models\Product',
+ 'find',
+ ]
+ );
+ /**
+ * @var \artbox\catalog\models\Product[] $products
+ */
+ $products = $query->where([ 'id' => \Yii::$app->request->post('productIds') ])
+ ->all();
+
+ $model->linkMany('relatedProducts', $products);
+ }
+
+ return $this->redirect(
+ [
+ 'view',
+ 'id' => $model->id,
+ ]
+ );
+
+ }
+ return $this->render(
+ 'update',
+ [
+ 'model' => $model,
+ 'modelLangs' => $model->modelLangs,
+ ]
+ );
+
+ }
+
+ /**
+ * Deletes an existing BlogArticle model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ *
+ * @param integer $id
+ *
+ * @return mixed
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)
+ ->delete();
+
+ return $this->redirect([ 'index' ]);
+ }
+
+ /**
+ * Finds the BlogArticle model based on its primary key value.
+ * If the model is not found, a 404 HTTP exception will be thrown.
+ *
+ * @param integer $id
+ *
+ * @return Article the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (( $model = Article::findOne($id) ) !== null) {
+ return $model;
+ } else {
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+ }
+
+ /**
+ * @param string $q
+ * @param integer $id
+ *
+ * @return array
+ */
+ public function actionList(string $q = null, int $id = null)
+ {
+ \Yii::$app->response->format = Response::FORMAT_JSON;
+ $out = [
+ 'results' => [
+ 'id' => '',
+ 'text' => '',
+ ],
+ ];
+ if (!is_null($q)) {
+ $out[ 'results' ] = Article::find()
+ ->joinWith('lang')
+ ->select(
+ [
+ 'blog_article.id as id',
+ 'blog_article_lang.title as text',
+ ]
+ )
+ ->where(
+ [
+ 'like',
+ 'blog_article_lang.title',
+ $q,
+ ]
+ )
+ ->andFilterWhere(
+ [
+ '!=',
+ 'blog_article.id',
+ $id,
+ ]
+ )
+ ->limit(20)
+ ->asArray()
+ ->all();
+ }
+ return $out;
+ }
+ }
diff --git a/backend/views/blog-article/_form.php b/backend/views/blog-article/_form.php
new file mode 100755
index 0000000..b483239
--- /dev/null
+++ b/backend/views/blog-article/_form.php
@@ -0,0 +1,301 @@
+
+
+
+
+ [ 'enctype' => 'multipart/form-data' ],
+ ]
+ ); ?>
+
+ $modelLangs,
+ 'formView' => '@backend/views/blog-article/_form_language',
+ 'form' => $form,
+ ]
+ );
+ ?>
+
+
+
+ 'categoryIds',
+ 'options' => [
+ 'placeholder' => \Yii::t('blog', 'Search for a categories ...'),
+ 'multiple' => true,
+
+ ],
+
+ 'value' => array_keys($model->categoryIds),
+ 'data' => $model->categoryIds,
+ 'toggleAllSettings' => [
+ 'selectLabel' => false,
+ ],
+ 'pluginOptions' => [
+ 'allowClear' => true,
+ 'minimumInputLength' => 3,
+ 'language' => [
+ 'errorLoading' => new JsExpression(
+ "function () { return 'Waiting for results...'; }"
+ ),
+ ],
+ 'ajax' => [
+ 'url' => Url::to([ '/blog-category/list' ]),
+ 'dataType' => 'json',
+ 'data' => new JsExpression(
+ 'function(params) {
+ return {
+ q:params.term
+ };
+ }'
+ ),
+ ],
+ 'escapeMarkup' => new JsExpression(
+ 'function (markup) {
+ return markup;
+ }'
+ ),
+ 'templateResult' => new JsExpression(
+ 'function (brand) {
+ return brand.text;
+ }'
+ ),
+ 'templateSelection' => new JsExpression(
+ 'function (brand) {
+ return brand.text;
+ }'
+ ),
+ ],
+ ]
+ );
+ ?>
+
+
+
+
+ 'tagIds',
+ 'options' => [
+ 'placeholder' => \Yii::t('blog', 'Search for a tags ...'),
+ 'multiple' => true,
+ ],
+ 'toggleAllSettings' => [
+ 'selectLabel' => false,
+ ],
+ 'value' => array_keys($model->tagIds),
+ 'data' => $model->tagIds,
+ 'pluginOptions' => [
+ 'allowClear' => true,
+ 'minimumInputLength' => 3,
+ 'language' => [
+ 'errorLoading' => new JsExpression(
+ "function () { return 'Waiting for results...'; }"
+ ),
+ ],
+ 'ajax' => [
+ 'url' => Url::to([ '/blog-tag/list' ]),
+ 'dataType' => 'json',
+ 'data' => new JsExpression(
+ 'function(params) {
+ return {
+ q:params.term
+ };
+ }'
+ ),
+ ],
+ 'escapeMarkup' => new JsExpression(
+ 'function (markup) {
+ return markup;
+ }'
+ ),
+ 'templateResult' => new JsExpression(
+ 'function (brand) {
+ return brand.text;
+ }'
+ ),
+ 'templateSelection' => new JsExpression(
+ 'function (brand) {
+ return brand.text;
+ }'
+ ),
+ ],
+ ]
+ );
+ ?>
+
+
+
+
+ isNewRecord) {
+ $condition = '';
+ } else {
+ $condition = ', id: ' . $model->id;
+ }
+ echo Select2::widget(
+ [
+ 'name' => 'articleIds',
+ 'options' => [
+ 'placeholder' => \Yii::t('blog', 'Search for an articles ...'),
+ 'multiple' => true,
+ ],
+ 'toggleAllSettings' => [
+ 'selectLabel' => false,
+ ],
+ 'value' => array_keys($model->articleIds),
+ 'data' => $model->articleIds,
+ 'pluginOptions' => [
+ 'allowClear' => true,
+ 'minimumInputLength' => 3,
+ 'language' => [
+ 'errorLoading' => new JsExpression(
+ "function () { return 'Waiting for results...'; }"
+ ),
+ ],
+ 'ajax' => [
+ 'url' => Url::to([ '/blog-article/list' ]),
+ 'dataType' => 'json',
+ 'data' => new JsExpression(
+ 'function(params) {
+ return {
+ q:params.term' . $condition . '
+ };
+ }'
+ ),
+ ],
+ 'escapeMarkup' => new JsExpression(
+ 'function (markup) {
+ return markup;
+ }'
+ ),
+ 'templateResult' => new JsExpression(
+ 'function (brand) {
+ return brand.text;
+ }'
+ ),
+ 'templateSelection' => new JsExpression(
+ 'function (brand) {
+ return brand.text;
+ }'
+ ),
+ ],
+ ]
+ );
+ ?>
+
+
+
+
+ 'productIds',
+ 'options' => [
+ 'placeholder' => \Yii::t('blog', 'Search for products ...'),
+ 'multiple' => true,
+ ],
+ 'toggleAllSettings' => [
+ 'selectLabel' => false,
+ ],
+ 'value' => array_keys($model->productIds),
+ 'data' => $model->productIds,
+ 'pluginOptions' => [
+ 'allowClear' => true,
+ 'minimumInputLength' => 3,
+ 'language' => [
+ 'errorLoading' => new JsExpression(
+ "function () { return 'Waiting for results...'; }"
+ ),
+ ],
+ 'ajax' => [
+ 'url' => Url::to([ '/product/list' ]),
+ 'dataType' => 'json',
+ 'data' => new JsExpression(
+ 'function(params) {
+ return {
+ q:params.term
+ };
+ }'
+ ),
+ ],
+ 'escapeMarkup' => new JsExpression(
+ 'function (markup) {
+ return markup;
+ }'
+ ),
+ 'templateResult' => new JsExpression(
+ 'function (product) {
+ return product.text;
+ }'
+ ),
+ 'templateSelection' => new JsExpression(
+ 'function (product) {
+ return product.text;
+ }'
+ ),
+ ],
+ ]
+ );
+ ?>
+
+
+
+ = $form->field($model, 'sort')
+ ->textInput() ?>
+
+ = $form->field($model, 'status')
+ ->checkbox(
+ [
+ 'class' => 'flat',
+ ]
+ ) ?>
+
+ = $form->field($model, 'author_id')
+ ->textInput() ?>
+
+
+ = Html::submitButton(
+ $model->isNewRecord ? 'Create' : 'Update',
+ [ 'class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary' ]
+ ) ?>
+
+
+
+
+
diff --git a/backend/views/blog-article/_form_language.php b/backend/views/blog-article/_form_language.php
new file mode 100755
index 0000000..c0adbe3
--- /dev/null
+++ b/backend/views/blog-article/_form_language.php
@@ -0,0 +1,80 @@
+
+field($model_lang, '[' . $language->id . ']title')
+ ->textInput([ 'maxlength' => true ]);
+ echo $attributeField;
+?>
+
+= SlugifyDecorator::decorate(
+ $form->field($model_lang, '[' . $language->id . ']aliasValue'),
+ [ '/alias/slugify' ],
+ $attributeField,
+ false,
+ $language->id
+)
+ ->textInput([ 'maxlength' => true ]); ?>
+
+= $form->field($model_lang, '[' . $language->id . ']body')
+ ->widget(
+ TinyMce::className(),
+ [
+ 'options' => [ 'rows' => 30 ],
+ 'language' => 'ru',
+ 'clientOptions' => [
+ 'file_browser_callback' => new JsExpression(
+ "function(field_name, url, type, win) {
+window.open('" . Url::to(
+ [
+ 'imagemanager/manager',
+ 'view-mode' => 'iframe',
+ 'select-type' => 'tinymce',
+ ]
+ ) . "&tag_name='+field_name,'','width=800,height=540 ,toolbar=no,status=no,menubar=no,scrollbars=no,resizable=no');
+}"
+ ),
+ 'plugins' => [
+ "advlist autolink lists link charmap print preview anchor",
+ "searchreplace visualblocks code fullscreen",
+ "insertdatetime media table contextmenu paste image",
+ ],
+ 'toolbar' => "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | code",
+ 'image_advtab' => true,
+ ],
+ ]
+ ); ?>
+
+= $form->field($model_lang, '[' . $language->id . ']body_preview')
+ ->textarea(
+ [
+ 'rows' => '10',
+ ]
+ ) ?>
+= $form->field($model_lang, '[' . $language->id . ']image_id')
+ ->widget(
+ ImageManagerInputWidget::className(),
+ [
+ 'aspectRatio' => ( 16 / 9 ),
+ //set the aspect ratio
+ 'showPreview' => true,
+ //false to hide the preview
+ 'showDeletePickedImageConfirm' => false,
+ //on true show warning before detach image
+ ]
+ ); ?>
diff --git a/backend/views/blog-article/_search.php b/backend/views/blog-article/_search.php
new file mode 100755
index 0000000..75c549d
--- /dev/null
+++ b/backend/views/blog-article/_search.php
@@ -0,0 +1,44 @@
+
+
+
+
+ [ 'index' ],
+ 'method' => 'get',
+ ]
+ ); ?>
+
+ = $form->field($model, 'id') ?>
+
+ = $form->field($model, 'image') ?>
+
+ = $form->field($model, 'created_at') ?>
+
+ = $form->field($model, 'updated_at') ?>
+
+ = $form->field($model, 'deleted_at') ?>
+
+ field($model, 'sort') ?>
+
+ field($model, 'status')->checkbox() ?>
+
+ field($model, 'author_id') ?>
+
+
+ = Html::submitButton('Search', [ 'class' => 'btn btn-primary' ]) ?>
+ = Html::resetButton('Reset', [ 'class' => 'btn btn-default' ]) ?>
+
+
+
+
+
diff --git a/backend/views/blog-article/create.php b/backend/views/blog-article/create.php
new file mode 100755
index 0000000..14ff913
--- /dev/null
+++ b/backend/views/blog-article/create.php
@@ -0,0 +1,41 @@
+title = \Yii::t('blog', 'Create Blog Article');
+ $this->params[ 'breadcrumbs' ][] = [
+ 'label' => \Yii::t('blog', 'Blog Articles'),
+ 'url' => [ 'index' ],
+ ];
+ $this->params[ 'breadcrumbs' ][] = $this->title;
+?>
+
+
+ $this->title,
+ ]
+ ); ?>
+
+ = $this->render(
+ '_form',
+ [
+ 'model' => $model,
+ 'modelLangs' => $modelLangs,
+ ]
+ ) ?>
+
+
+
+
diff --git a/backend/views/blog-article/index.php b/backend/views/blog-article/index.php
new file mode 100755
index 0000000..742b6e5
--- /dev/null
+++ b/backend/views/blog-article/index.php
@@ -0,0 +1,121 @@
+title = \Yii::t('blog', 'Blog Articles');
+ $this->params[ 'breadcrumbs' ][] = $this->title;
+?>
+
+
+ $this->title,
+ ]
+ ); ?>
+
+ = Html::a(
+ \Yii::t('app', 'create_item', [ 'item' => 'Blog Article' ]),
+ [ 'create' ],
+ [ 'class' => 'btn btn-success' ]
+ ) ?>
+
+ = GridView::widget(
+ [
+ 'dataProvider' => $dataProvider,
+ 'filterModel' => $searchModel,
+ 'columns' => [
+ 'id',
+ [
+ 'attribute' => 'title',
+ 'value' => 'lang.title',
+ ],
+ [
+ 'attribute' => 'category',
+ 'label' => \Yii::t('blog', 'Categories'),
+ 'value' => function (Article $model) {
+ if (empty($model->categories)) {
+ return \Yii::$app->formatter->asText(null);
+ } else {
+ return implode(
+ ',
',
+ ArrayHelper::getColumn(
+ $model->categories,
+ function (Category $category) {
+ return $category->lang->title;
+ }
+ )
+ );
+ }
+ },
+ 'format' => 'html',
+ ],
+ [
+ 'attribute' => 'tag',
+ 'label' => \Yii::t('blog', 'Tags'),
+ 'value' => function (Article $model) {
+ if (empty($model->tags)) {
+ return \Yii::$app->formatter->asText(null);
+ } else {
+ return implode(
+ ',
',
+ ArrayHelper::getColumn(
+ $model->tags,
+ function (Tag $tag) {
+ return $tag->lang->label;
+ }
+ )
+ );
+ }
+ },
+ 'format' => 'html',
+ ],
+ [
+ 'attribute' => 'image_id',
+ 'value' => function (Article $model) {
+ if (empty($model->image_id)) {
+ return '';
+ } else {
+ return $model->image->getImg(
+ [
+ 'width' => '300px',
+ ]
+ );
+ }
+ },
+ 'format' => 'html',
+ ],
+ [
+ 'attribute' => 'status',
+ 'value' => function (Article $model) {
+ return ( !$model->status ) ? \Yii::t('blog', 'Not active') : \Yii::t('blog', 'Active');
+ },
+ 'filter' => [
+ 0 => \Yii::t('blog', 'Not active'),
+ 1 => \Yii::t('blog', 'Active'),
+ ],
+ ],
+ 'created_at:date',
+ 'updated_at:date',
+ [ 'class' => 'yii\grid\ActionColumn' ],
+ ],
+ ]
+ ); ?>
+
+
+
+
diff --git a/backend/views/blog-article/update.php b/backend/views/blog-article/update.php
new file mode 100755
index 0000000..b352f7d
--- /dev/null
+++ b/backend/views/blog-article/update.php
@@ -0,0 +1,46 @@
+title = \Yii::t('blog', 'Update Blog Article: ') . $model->lang->title;
+ $this->params[ 'breadcrumbs' ][] = [
+ 'label' => \Yii::t('blog', 'Blog Articles'),
+ 'url' => [ 'index' ],
+ ];
+ $this->params[ 'breadcrumbs' ][] = [
+ 'label' => $model->lang->title,
+ 'url' => [
+ 'view',
+ 'id' => $model->id,
+ ],
+ ];
+ $this->params[ 'breadcrumbs' ][] = \Yii::t('blog', 'Update');
+?>
+
+
+ $this->title,
+ ]
+ ); ?>
+
+ = $this->render(
+ '_form',
+ [
+ 'model' => $model,
+ 'modelLangs' => $modelLangs,
+ ]
+ ) ?>
+
+
+
+
diff --git a/backend/views/blog-article/view.php b/backend/views/blog-article/view.php
new file mode 100755
index 0000000..5813305
--- /dev/null
+++ b/backend/views/blog-article/view.php
@@ -0,0 +1,87 @@
+title = $model->lang->title;
+ $this->params[ 'breadcrumbs' ][] = [
+ 'label' => \Yii::t('blog', 'Blog Articles'),
+ 'url' => [ 'index' ],
+ ];
+ $this->params[ 'breadcrumbs' ][] = $this->title;
+?>
+
+
+ $this->title,
+ ]
+ ); ?>
+
+
+ = Html::a(
+ 'Update',
+ [
+ 'update',
+ 'id' => $model->id,
+ ],
+ [ 'class' => 'btn btn-primary' ]
+ ) ?>
+ = Html::a(
+ 'Delete',
+ [
+ 'delete',
+ 'id' => $model->id,
+ ],
+ [
+ 'class' => 'btn btn-danger',
+ 'data' => [
+ 'confirm' => 'Are you sure you want to delete this item?',
+ 'method' => 'post',
+ ],
+ ]
+ ) ?>
+
+
+ = DetailView::widget(
+ [
+ 'model' => $model,
+ 'attributes' => [
+ 'id',
+ [
+ 'attribute' => 'image_id',
+ 'value' => function (Article $model) {
+ if (empty($model->lang->image_id)) {
+ return '';
+ } else {
+ return $model->lang->image->getImg(
+ [
+ 'width' => '500px',
+ ]
+ );
+ }
+ },
+ 'format' => 'html',
+ ],
+ 'created_at:date',
+ 'updated_at:date',
+ [
+ 'attribute' => 'status',
+ 'value' => ( !$model->status ) ? \Yii::t('blog', 'Not active') : \Yii::t('blog', 'Active'),
+ ],
+ 'lang.body:html',
+ ],
+ ]
+ ) ?>
+
+
+
+
diff --git a/common/models/Article.php b/common/models/Article.php
new file mode 100755
index 0000000..239b97d
--- /dev/null
+++ b/common/models/Article.php
@@ -0,0 +1,226 @@
+ TimestampBehavior::className(),
+ ],
+ 'language' => [
+ 'class' => LanguageBehavior::className(),
+ ],
+ [
+ 'class' => ManyToManyBehavior::className(),
+ ],
+ ];
+ }
+ /**
+ * @inheritdoc
+ */
+ public function rules()
+ {
+ return [
+ [
+ [
+ 'created_at',
+ 'updated_at',
+ 'deleted_at',
+ 'sort',
+ 'author_id',
+ 'image_id',
+ ],
+ 'integer',
+ ],
+ [
+ [ 'status' ],
+ 'boolean',
+ ],
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'image' => 'Image',
+ 'created_at' => 'Created At',
+ 'updated_at' => 'Updated At',
+ 'deleted_at' => 'Deleted At',
+ 'sort' => 'Sort',
+ 'status' => 'Status',
+ 'author_id' => 'Author ID',
+ ];
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getRelatedBlogArticles()
+ {
+ return $this->hasMany(Article::className(), [ 'id' => 'related_blog_article_id' ])
+ ->viaTable('blog_article_to_article', [ 'blog_article_id' => 'id' ]);
+ }
+
+ /**
+ * @return Query
+ */
+ public function getRelatedProducts()
+ {
+ if (class_exists('\artbox\catalog\models\Product')) {
+ return $this->hasMany('\artbox\catalog\models\Product', [ 'id' => 'product_id' ])
+ ->via('articleToProduct');
+ } else {
+ return ( new Query() )->where('1 = 0');
+ }
+ }
+
+ public function getCommentsCount()
+ {
+
+ if (class_exists('\artbox\webcomment\models\CommentModel')) {
+ $comments = CommentModel::find()->where("status = 1 and entity = 'artbox\weblog\models\Article' and entity_id = ".$this->id)->count();
+ return $comments;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @return Query
+ */
+ public function getArticleToProduct()
+ {
+
+ if (class_exists('\artbox\catalog\models\Product')) {
+ return $this->hasMany(ArticleToProduct::className(), [ 'article_id' => 'id' ]);
+ } else {
+ return ( new Query() )->where('1 = 0');
+ }
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getImage()
+ {
+ return $this->hasOne(Image::className(), [ 'id' => 'image_id' ]);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getArticles()
+ {
+ return $this->hasMany(Article::className(), [ 'id' => 'blog_article_id' ])
+ ->viaTable('blog_article_to_article', [ 'related_blog_article_id' => 'id' ]);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCategories()
+ {
+ return $this->hasMany(Category::className(), [ 'id' => 'blog_category_id' ])
+ ->viaTable('blog_article_to_category', [ 'blog_article_id' => 'id' ]);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCategory()
+ {
+ return $this->hasOne(Category::className(), [ 'id' => 'blog_category_id' ])
+ ->viaTable('blog_article_to_category', [ 'blog_article_id' => 'id' ]);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getTags()
+ {
+ return $this->hasMany(Tag::className(), [ 'id' => 'blog_tag_id' ])
+ ->viaTable('blog_article_to_tag', [ 'blog_article_id' => 'id' ]);
+ }
+ }
diff --git a/common/models/ArticleLang.php b/common/models/ArticleLang.php
new file mode 100755
index 0000000..ccd8eb4
--- /dev/null
+++ b/common/models/ArticleLang.php
@@ -0,0 +1,172 @@
+ [
+ 'class' => SlugBehavior::className(),
+ 'action' => 'blog/article',
+ 'params' => [
+ 'id' => 'blog_article_id',
+ ],
+ 'fields' => [
+ 'title' => 'Article title',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function rules()
+ {
+ return [
+ [
+ [
+ 'blog_article_id',
+ 'language_id',
+ 'title',
+ ],
+ 'required',
+ ],
+ [
+ [
+ 'blog_article_id',
+ 'language_id',
+ 'image_id',
+ ],
+ 'integer',
+ ],
+ [
+ [
+ 'body',
+ 'body_preview',
+ ],
+ 'string',
+ ],
+ [
+ [
+ 'title',
+ ],
+ 'string',
+ 'max' => 255,
+ ],
+
+ [
+ [
+ 'blog_article_id',
+ 'language_id',
+ ],
+ 'unique',
+ 'targetAttribute' => [
+ 'blog_article_id',
+ 'language_id',
+ ],
+ 'message' => 'The combination of Blog Article ID and Language ID has already been taken.',
+ ],
+ [
+ [ 'blog_article_id' ],
+ 'exist',
+ 'skipOnError' => true,
+ 'targetClass' => Article::className(),
+ 'targetAttribute' => [ 'blog_article_id' => 'id' ],
+ ],
+ [
+ [ 'language_id' ],
+ 'exist',
+ 'skipOnError' => true,
+ 'targetClass' => Language::className(),
+ 'targetAttribute' => [ 'language_id' => 'id' ],
+ ],
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'blog_article_id' => 'Blog Article ID',
+ 'language_id' => 'Language ID',
+ 'title' => 'Title',
+ 'body' => 'Body',
+ 'body_preview' => 'Body Preview',
+ 'alias' => 'Alias',
+ 'meta_title' => 'Meta Title',
+ 'meta_description' => 'Meta Description',
+ 'h1' => 'H1',
+ 'seo_text' => 'Seo Text',
+ ];
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getArticle()
+ {
+ return $this->hasOne(Article::className(), [ 'id' => 'blog_article_id' ]);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getImage()
+ {
+ return $this->hasOne(Image::className(), [ 'id' => 'image_id' ]);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getLanguage()
+ {
+ return $this->hasOne(Language::className(), [ 'id' => 'language_id' ]);
+ }
+
+ /**
+ * @return \yii\db\ActiveQuery
+ */
+ public function getAlias()
+ {
+ return $this->hasOne(Alias::className(), [ 'id' => 'alias_id' ]);
+ }
+ }
diff --git a/common/models/ArticleSearch.php b/common/models/ArticleSearch.php
new file mode 100755
index 0000000..e232f10
--- /dev/null
+++ b/common/models/ArticleSearch.php
@@ -0,0 +1,154 @@
+joinWith(
+ [
+ 'lang',
+
+ ]
+ )
+ ->with(
+ [
+ 'tags.lang',
+ 'categories.lang',
+ ]
+ );
+
+ // add conditions that should always apply here
+
+ $dataProvider = new ActiveDataProvider(
+ [
+ 'query' => $query,
+ 'sort' => [
+ 'attributes' => [
+ 'id',
+ 'created_at',
+ 'updated_at',
+ 'title' => [
+ 'asc' => [ 'blog_article_lang.title' => SORT_ASC ],
+ 'desc' => [ 'blog_article_lang.title' => SORT_DESC ],
+ ],
+ ],
+ ],
+ ]
+ );
+
+ $this->load($params);
+
+ if (!$this->validate()) {
+ // uncomment the following line if you do not want to return any records when validation fails
+ // $query->where('0=1');
+ return $dataProvider;
+ }
+
+ // grid filtering conditions
+ $query->andFilterWhere(
+ [
+ 'blog_article.id' => $this->id,
+ 'blog_article.status' => $this->status,
+ 'author_id' => $this->author_id,
+ ]
+ );
+
+ $query->andFilterWhere(
+ [
+ 'ilike',
+ 'blog_article_lang.title',
+ $this->title,
+ ]
+ );
+
+ $query->andFilterWhere(
+ [
+ 'ilike',
+ 'blog_tag_lang.label',
+ $this->tag,
+ ]
+ );
+
+ $query->andFilterWhere(
+ [
+ 'ilike',
+ 'blog_category_lang.title',
+ $this->category,
+ ]
+ );
+
+ return $dataProvider;
+ }
+ }
diff --git a/console/migrations/m180306_103852_add_image_id_column_to_blog_article_lang.php b/console/migrations/m180306_103852_add_image_id_column_to_blog_article_lang.php
new file mode 100644
index 0000000..dfbed5a
--- /dev/null
+++ b/console/migrations/m180306_103852_add_image_id_column_to_blog_article_lang.php
@@ -0,0 +1,16 @@
+addColumn('blog_article_lang', 'image_id', $this->integer());
+ }
+
+ public function down()
+ {
+ $this->dropColumn('blog_article_lang', 'image_id');
+ }
+}
diff --git a/frontend/controllers/BlogController.php b/frontend/controllers/BlogController.php
index 66d89b0..7f4dca2 100644
--- a/frontend/controllers/BlogController.php
+++ b/frontend/controllers/BlogController.php
@@ -5,7 +5,7 @@
use yii\helpers\Html;
use yii\helpers\Url;
use yii\web\Controller;
- use artbox\weblog\models\Article;
+ use common\models\Article;
use yii\web\NotFoundHttpException;
use yii\db\ActiveQuery;
@@ -40,6 +40,7 @@
{
$query = Article::find()
+ ->with('lang.image')
->where(
[
'status' => true,
@@ -67,12 +68,14 @@
protected function findModel($id)
{
$model = Article::find()
- ->where(
+ ->with('lang.image')
+
+ ->where(
[
'id' => $id
]
)
- ->with("lang")
+ ->with("lang.image")
->one();
if ( $model !== NULL) {
@@ -92,7 +95,7 @@
if (!empty($req->post("title"))){
$title = Html::encode($req->post("title"));
$query = Article::find()
- ->joinWith("lang")
+ ->joinWith("lang.image")
->where(
[
'status' => true,
@@ -116,7 +119,7 @@
public function actionCategory($id) {
$query = Article::find()
- ->joinWith("categories.lang")
+ ->joinWith(["categories.lang", 'lang.image'])
->where(
[
'blog_article.status' => true,
@@ -135,7 +138,7 @@
public function actionTag($id){
$query = Article::find()
- ->joinWith("tags.lang")
+ ->joinWith(["tags.lang", 'lang.image'])
->where(
[
'blog_article.status' => true,
diff --git a/frontend/views/blog/_article_item.php b/frontend/views/blog/_article_item.php
index d6df81e..e106b6f 100644
--- a/frontend/views/blog/_article_item.php
+++ b/frontend/views/blog/_article_item.php
@@ -7,7 +7,7 @@
* @var Article $model
*/
- use artbox\weblog\models\Article;
+ use common\models\Article;
use yii\helpers\Url;
?>
@@ -62,7 +62,7 @@
]
)?>"
>
- =$model->image->getImg(
+ =$model->lang->image->getImg(
[
'class' => "img-responsive"
]
diff --git a/frontend/views/blog/view.php b/frontend/views/blog/view.php
index ae16197..da515cd 100644
--- a/frontend/views/blog/view.php
+++ b/frontend/views/blog/view.php
@@ -45,7 +45,7 @@
- = $article->image->getImg(
+ = $article->lang->image->getImg(
[
'class' => "img-responsive",
]
--
libgit2 0.21.4