diff --git a/backend/views/layouts/main-sidebar.php b/backend/views/layouts/main-sidebar.php index 15e30c7..a37cf74 100755 --- a/backend/views/layouts/main-sidebar.php +++ b/backend/views/layouts/main-sidebar.php @@ -121,6 +121,32 @@ use yii\widgets\Menu; 'options' => ['class'=>\Yii::$app->user->can('article') ? '' :'hide'], ], [ + 'label' => 'Блог', + 'template'=>' {label}', + 'options' => ['class'=>\Yii::$app->user->can('blog') ? '' :'hide'], + 'active' => preg_match('/^blog.*$/', $this->context->id) ? true : false, + 'items' => [ + [ + 'label' => 'Статьи', + 'url' => ['/blog/blog-article'], + 'options' => ['class'=>\Yii::$app->user->can('blog') ? '' :'hide'], + 'active' => preg_match('/.*blog-article.*$/', $this->context->id), + ], + [ + 'label' => 'Рубрики', + 'url' => ['/blog/blog-category'], + 'options' => ['class'=>\Yii::$app->user->can('blog') ? '' :'hide'], + 'active' => preg_match('/.*blog-category.*$/', $this->context->id), + ], + [ + 'label' => 'Тэги', + 'url' => ['/blog/blog-tag'], + 'options' => ['class'=>\Yii::$app->user->can('blog') ? '' :'hide'], + 'active' => preg_match('/.*blog-tag.*$/', $this->context->id), + ], + ] + ], + [ 'label' => 'Акции', 'template'=>' {label}', 'url' => ['/event/index'], diff --git a/common/config/main.php b/common/config/main.php index 557e83b..b539e83 100755 --- a/common/config/main.php +++ b/common/config/main.php @@ -1,5 +1,4 @@ 'ru', 'vendorPath' => dirname(dirname(__DIR__)) . '/vendor', @@ -41,7 +40,13 @@ 'resize' => [ 'width' => 360, 'height' => 360, - 'master' => null, + 'master' => NULL, + ], + ], + 'list' => [ + 'resize' => [ + 'width' => 360, + 'height' => 360, ], ], ], @@ -54,5 +59,8 @@ 'artbox-comment' => [ 'class' => 'common\modules\comment\Module', ], + 'blog' => [ + 'class' => 'common\modules\blog\Module', + ], ], ]; diff --git a/common/modules/blog/Module.php b/common/modules/blog/Module.php new file mode 100644 index 0000000..29fee28 --- /dev/null +++ b/common/modules/blog/Module.php @@ -0,0 +1,24 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => [ 'POST' ], + ], + ], + ]; + } + + /** + * Lists all BlogArticle models. + * + * @return mixed + */ + public function actionIndex() + { + $searchModel = new BlogArticleSearch(); + $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 BlogArticle(); + $model->generateLangs(); + + $categories = ArrayHelper::map( + BlogCategory::find() + ->joinWith('lang') + ->all(), + 'id', + 'lang.title' + ); + + $tags = ArrayHelper::map( + BlogTag::find() + ->joinWith('lang') + ->all(), + 'id', + 'lang.label' + ); + + if ($model->load(Yii::$app->request->post())) { + $model->loadLangs(\Yii::$app->request); + if ($model->save() && $model->transactionStatus) { + + if (!empty( \Yii::$app->request->post('BlogArticle')[ 'blogCategories' ] )) { + foreach (\Yii::$app->request->post('BlogArticle')[ 'blogCategories' ] as $item) { + if ($category = BlogCategory::findOne($item)) { + $model->link('blogCategories', $category); + } + } + } + + if (!empty( \Yii::$app->request->post('BlogArticle')[ 'blogTags' ] )) { + foreach (\Yii::$app->request->post('BlogArticle')[ 'blogTags' ] as $item) { + if ($category = BlogTag::findOne($item)) { + $model->link('blogTags', $category); + } + } + } + + if (!empty( \Yii::$app->request->post('BlogArticle')[ 'products' ] )) { + foreach (\Yii::$app->request->post('BlogArticle')[ 'products' ] as $item) { + if ($product = Product::findOne($item)) { + $model->link('products', $product); + } + } + } + + if (!empty( \Yii::$app->request->post('BlogArticle')[ 'blogArticles' ] )) { + foreach (\Yii::$app->request->post('BlogArticle')[ 'blogArticles' ] as $item) { + if ($article = Product::findOne($item)) { + $model->link('blogArticles', $article); + } + } + } + + return $this->redirect( + [ + 'view', + 'id' => $model->id, + ] + ); + } + } + return $this->render( + 'create', + [ + 'model' => $model, + 'modelLangs' => $model->modelLangs, + 'categories' => $categories, + 'tags' => $tags, + 'products' => [], + 'articles' => [], + ] + ); + + } + + /** + * 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(); + + $categories = ArrayHelper::map( + BlogCategory::find() + ->joinWith('lang') + ->all(), + 'id', + 'lang.title' + ); + + $tags = ArrayHelper::map( + BlogTag::find() + ->joinWith('lang') + ->all(), + 'id', + 'lang.label' + ); + + $products = ArrayHelper::map( + $model->getProducts() + ->joinWith('lang') + ->asArray() + ->all(), + 'id', + 'lang.title' + ); + + $articles = ArrayHelper::map( + $model->getBlogArticles() + ->joinWith('lang') + ->asArray() + ->all(), + 'id', + 'lang.title' + ); + + if ($model->load(Yii::$app->request->post())) { + $model->loadLangs(\Yii::$app->request); + if ($model->save() && $model->transactionStatus) { + + if (!empty( \Yii::$app->request->post('BlogArticle')[ 'blogCategories' ] )) { + $model->unlinkAll('blogCategories', true); + foreach (\Yii::$app->request->post('BlogArticle')[ 'blogCategories' ] as $item) { + if ($category = BlogCategory::findOne($item)) { + $model->link('blogCategories', $category); + } + } + } + + if (!empty( \Yii::$app->request->post('BlogArticle')[ 'blogTags' ] )) { + $model->unlinkAll('blogTags', true); + foreach (\Yii::$app->request->post('BlogArticle')[ 'blogTags' ] as $item) { + if ($tag = BlogTag::findOne($item)) { + $model->link('blogTags', $tag); + } + } + } + + if (!empty( \Yii::$app->request->post('BlogArticle')[ 'products' ] )) { + $model->unlinkAll('products', true); + foreach (\Yii::$app->request->post('BlogArticle')[ 'products' ] as $item) { + if ($product = Product::findOne($item)) { + $model->link('products', $product); + } + } + } + + if (!empty( \Yii::$app->request->post('BlogArticle')[ 'blogArticles' ] )) { + $model->unlinkAll('blogArticles', true); + foreach (\Yii::$app->request->post('BlogArticle')[ 'blogArticles' ] as $item) { + if ($article = BlogArticle::findOne($item)) { + $model->link('blogArticles', $article); + } + } + } + + return $this->redirect( + [ + 'view', + 'id' => $model->id, + ] + ); + } + } + return $this->render( + 'update', + [ + 'model' => $model, + 'modelLangs' => $model->modelLangs, + 'categories' => $categories, + 'tags' => $tags, + 'products' => $products, + 'articles' => $articles, + ] + ); + + } + + /** + * 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 BlogArticle the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (( $model = BlogArticle::findOne($id) ) !== NULL) { + return $model; + } else { + throw new NotFoundHttpException('The requested page does not exist.'); + } + } + + /** + * @param string $q + * @param null $id + * + * @return array + */ + public function actionProductList($q = NULL, $id = NULL) + { + \Yii::$app->response->format = Response::FORMAT_JSON; + $out = [ + 'results' => [ + 'id' => '', + 'text' => '', + ], + ]; + if (!is_null($q)) { + $out[ 'results' ] = Product::find() + ->joinWith('lang') + ->select( + [ + 'id', + 'product_lang.title as text', + ] + ) + ->where( + [ + 'like', + 'product_lang.title', + $q, + ] + ) + ->limit(20) + ->asArray() + ->all(); + } elseif ($id > 0) { + $out[ 'results' ] = [ + 'id' => $id, + 'text' => Product::find() + ->joinWith('lang') + ->where([ 'id' => $id ]) + ->one()->title, + ]; + } + return $out; + } + + /** + * @param string $q + * @param integer $id + * + * @return array + */ + public function actionArticleList($q = NULL, $id = NULL) + { + \Yii::$app->response->format = Response::FORMAT_JSON; + $out = [ + 'results' => [ + 'id' => '', + 'text' => '', + ], + ]; + if (!is_null($q)) { + $out[ 'results' ] = BlogArticle::find() + ->joinWith('lang') + ->select( + [ + 'blog_article.id as id', + 'blog_article_lang.title as text', + ] + ) + ->where( + [ + 'like', + 'blog_article_lang.title', + $q, + ] + ) + ->andWhere( + [ + '!=', + 'blog_article.id', + $id, + ] + ) + ->limit(20) + ->asArray() + ->all(); + } + return $out; + } + } diff --git a/common/modules/blog/controllers/BlogCategoryController.php b/common/modules/blog/controllers/BlogCategoryController.php new file mode 100644 index 0000000..a210985 --- /dev/null +++ b/common/modules/blog/controllers/BlogCategoryController.php @@ -0,0 +1,201 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => [ 'POST' ], + ], + ], + ]; + } + + /** + * Lists all BlogCategory models. + * + * @return mixed + */ + public function actionIndex() + { + $searchModel = new BlogCategorySearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render( + 'index', + [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ] + ); + } + + /** + * Displays a single BlogCategory model. + * + * @param integer $id + * + * @return mixed + */ + public function actionView($id) + { + return $this->render( + 'view', + [ + 'model' => $this->findModel($id), + ] + ); + } + + /** + * Creates a new BlogCategory model. + * If creation is successful, the browser will be redirected to the 'view' page. + * + * @return mixed + */ + public function actionCreate() + { + $model = new BlogCategory(); + $model->generateLangs(); + $parentCategories = ArrayHelper::map( + BlogCategory::find() + ->joinWith('lang') + ->where( + [ + 'parent_id' => 0, + ] + ) + ->all(), + 'id', + 'lang.title' + ); + + if ($model->load(Yii::$app->request->post())) { + $model->loadLangs(\Yii::$app->request); + if ($model->save() && $model->transactionStatus) { + return $this->redirect( + [ + 'view', + 'id' => $model->id, + ] + ); + } + } + return $this->render( + 'create', + [ + 'model' => $model, + 'modelLangs' => $model->modelLangs, + 'parentCategories' => $parentCategories, + ] + ); + + } + + /** + * Updates an existing BlogCategory 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(); + $parentCategories = ArrayHelper::map( + BlogCategory::find() + ->joinWith('lang') + ->where( + [ + 'parent_id' => 0, + ] + ) + ->andWhere( + [ + '!=', + BlogCategory::tableName() . '_id', + $model->id, + ] + ) + ->all(), + 'id', + 'lang.title' + ); + + if ($model->load(Yii::$app->request->post())) { + $model->loadLangs(\Yii::$app->request); + if ($model->save() && $model->transactionStatus) { + return $this->redirect( + [ + 'view', + 'id' => $model->id, + ] + ); + } + } + return $this->render( + 'update', + [ + 'model' => $model, + 'modelLangs' => $model->modelLangs, + 'parentCategories' => $parentCategories, + ] + ); + + } + + /** + * Deletes an existing BlogCategory 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 BlogCategory model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * + * @param integer $id + * + * @return BlogCategory the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (( $model = BlogCategory::findOne($id) ) !== NULL) { + return $model; + } else { + throw new NotFoundHttpException('The requested page does not exist.'); + } + } + } diff --git a/common/modules/blog/controllers/BlogTagController.php b/common/modules/blog/controllers/BlogTagController.php new file mode 100644 index 0000000..365b626 --- /dev/null +++ b/common/modules/blog/controllers/BlogTagController.php @@ -0,0 +1,169 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => [ 'POST' ], + ], + ], + ]; + } + + /** + * Lists all BlogTag models. + * + * @return mixed + */ + public function actionIndex() + { + $searchModel = new BlogTagSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render( + 'index', + [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ] + ); + } + + /** + * Displays a single BlogTag model. + * + * @param integer $id + * + * @return mixed + */ + public function actionView($id) + { + return $this->render( + 'view', + [ + 'model' => $this->findModel($id), + ] + ); + } + + /** + * Creates a new BlogTag model. + * If creation is successful, the browser will be redirected to the 'view' page. + * + * @return mixed + */ + public function actionCreate() + { + $model = new BlogTag(); + $model->generateLangs(); + + if (\Yii::$app->request->isPost) { + $model->loadLangs(\Yii::$app->request); + $model->markAttributeDirty('id'); + if ($model->save() && $model->transactionStatus) { + return $this->redirect( + [ + 'view', + 'id' => $model->id, + ] + ); + } + } + return $this->render( + 'create', + [ + 'model' => $model, + 'modelLangs' => $model->modelLangs, + ] + ); + + } + + /** + * Updates an existing BlogTag 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(); + + if (Yii::$app->request->isPost) { + $model->loadLangs(\Yii::$app->request); + $model->markAttributeDirty('id'); + if ($model->save() && $model->transactionStatus) { + return $this->redirect( + [ + 'view', + 'id' => $model->id, + ] + ); + } + } + return $this->render( + 'update', + [ + 'model' => $model, + 'modelLangs' => $model->modelLangs, + ] + ); + + } + + /** + * Deletes an existing BlogTag 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 BlogTag model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * + * @param integer $id + * + * @return BlogTag the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (( $model = BlogTag::findOne($id) ) !== NULL) { + return $model; + } else { + throw new NotFoundHttpException('The requested page does not exist.'); + } + } + } diff --git a/common/modules/blog/controllers/DefaultController.php b/common/modules/blog/controllers/DefaultController.php new file mode 100644 index 0000000..7cad6b8 --- /dev/null +++ b/common/modules/blog/controllers/DefaultController.php @@ -0,0 +1,20 @@ +render('index'); + } +} diff --git a/common/modules/blog/models/BlogArticle.php b/common/modules/blog/models/BlogArticle.php new file mode 100644 index 0000000..7f22431 --- /dev/null +++ b/common/modules/blog/models/BlogArticle.php @@ -0,0 +1,195 @@ + TimestampBehavior::className(), + ], + [ + 'class' => SaveImgBehavior::className(), + 'fields' => [ + [ + 'name' => 'image', + 'directory' => 'blog/article', + ], + ], + ], + 'language' => [ + 'class' => LanguageBehavior::className(), + ], + ]; + } + /** + * @inheritdoc + */ + public function rules() + { + return [ + [ + [ + 'created_at', + 'updated_at', + 'deleted_at', + 'sort', + 'author_id', + ], + 'integer', + ], + [ + [ 'status' ], + 'boolean', + ], + [ + [ 'image' ], + 'string', + 'max' => 255, + ], + ]; + } + + /** + * @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 getBlogArticleLangs() + { + return $this->hasMany(BlogArticleLang::className(), [ 'blog_article_id' => 'id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getLanguages() + { + return $this->hasMany(Language::className(), [ 'id' => 'language_id' ]) + ->viaTable('blog_article_lang', [ 'blog_article_id' => 'id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getRelatedBlogArticles() + { + return $this->hasMany(BlogArticle::className(), [ 'id' => 'related_blog_article_id' ]) + ->viaTable('blog_article_to_article', [ 'blog_article_id' => 'id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getBlogArticles() + { + return $this->hasMany(BlogArticle::className(), [ 'id' => 'blog_article_id' ]) + ->viaTable('blog_article_to_article', [ 'related_blog_article_id' => 'id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getBlogCategories() + { + return $this->hasMany(BlogCategory::className(), [ 'id' => 'blog_category_id' ]) + ->viaTable('blog_article_to_category', [ 'blog_article_id' => 'id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getProducts() + { + return $this->hasMany(Product::className(), [ 'id' => 'product_id' ]) + ->viaTable('blog_article_to_product', [ 'blog_article_id' => 'id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getBlogTags() + { + return $this->hasMany(BlogTag::className(), [ 'id' => 'blog_tag_id' ]) + ->viaTable('blog_article_to_tag', [ 'blog_article_id' => 'id' ]); + } + } diff --git a/common/modules/blog/models/BlogArticleLang.php b/common/modules/blog/models/BlogArticleLang.php new file mode 100644 index 0000000..3dad78e --- /dev/null +++ b/common/modules/blog/models/BlogArticleLang.php @@ -0,0 +1,151 @@ + [ + 'class' => 'common\behaviors\Slug', + ], + ]; + } + + /** + * @inheritdoc + */ + public function rules() + { + return [ + [ + [ + 'blog_article_id', + 'language_id', + ], + 'required', + ], + [ + [ + 'blog_article_id', + 'language_id', + ], + 'integer', + ], + [ + [ + 'body', + 'body_preview', + ], + 'string', + ], + [ + [ + 'title', + 'alias', + 'meta_title', + 'meta_description', + 'h1', + 'seo_text', + ], + 'string', + 'max' => 255, + ], + [ + [ 'alias' ], + 'unique', + ], + [ + [ + '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' => BlogArticle::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 getBlogArticle() + { + return $this->hasOne(BlogArticle::className(), [ 'id' => 'blog_article_id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getLanguage() + { + return $this->hasOne(Language::className(), [ 'id' => 'language_id' ]); + } + } diff --git a/common/modules/blog/models/BlogArticleSearch.php b/common/modules/blog/models/BlogArticleSearch.php new file mode 100644 index 0000000..7e9c0c2 --- /dev/null +++ b/common/modules/blog/models/BlogArticleSearch.php @@ -0,0 +1,130 @@ +joinWith('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( + [ + 'id' => $this->id, + 'status' => $this->status, + 'author_id' => $this->author_id, + ] + ); + + $query->andFilterWhere( + [ + 'like', + 'image', + $this->image, + ] + ); + + $query->andFilterWhere( + [ + 'like', + 'blog_article_lang.title', + $this->title, + ] + ); + + return $dataProvider; + } + } diff --git a/common/modules/blog/models/BlogCategory.php b/common/modules/blog/models/BlogCategory.php new file mode 100644 index 0000000..7463d49 --- /dev/null +++ b/common/modules/blog/models/BlogCategory.php @@ -0,0 +1,159 @@ + SaveImgBehavior::className(), + 'fields' => [ + [ + 'name' => 'image', + 'directory' => 'blog/category', + ], + ], + ], + 'language' => [ + 'class' => LanguageBehavior::className(), + ], + 'Slug' => [ + 'class' => 'common\behaviors\Slug', + ], + ]; + } + + /** + * @inheritdoc + */ + public function rules() + { + return [ + [ + [ + 'sort', + 'parent_id', + ], + 'integer', + ], + [ + [ 'status' ], + 'boolean', + ], + [ + [ 'image' ], + 'string', + 'max' => 255, + ], + [ + [ 'parent_id' ], + 'default', + 'value' => 0, + ], + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'sort' => 'Sort', + 'image' => 'Image', + 'parent_id' => 'Parent ID', + 'status' => 'Status', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getBlogArticles() + { + return $this->hasMany(BlogArticle::className(), [ 'id' => 'blog_article_id' ]) + ->viaTable('blog_article_to_category', [ 'blog_category_id' => 'id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getBlogCategoryLangs() + { + return $this->hasMany(BlogCategoryLang::className(), [ 'blog_category_id' => 'id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getLanguages() + { + return $this->hasMany(Language::className(), [ 'id' => 'language_id' ]) + ->viaTable('blog_category_lang', [ 'blog_category_id' => 'id' ]); + } + + public function getParent() + { + return $this->hasOne(BlogCategory::className(), [ 'id' => 'parent_id' ]); + } + } diff --git a/common/modules/blog/models/BlogCategoryLang.php b/common/modules/blog/models/BlogCategoryLang.php new file mode 100644 index 0000000..09a58b8 --- /dev/null +++ b/common/modules/blog/models/BlogCategoryLang.php @@ -0,0 +1,146 @@ + [ + 'class' => 'common\behaviors\Slug', + ], + ]; + } + + /** + * @inheritdoc + */ + public function rules() + { + return [ + [ + [ + 'blog_category_id', + 'language_id', + ], + 'required', + ], + [ + [ + 'blog_category_id', + 'language_id', + ], + 'integer', + ], + [ + [ 'description' ], + 'string', + ], + [ + [ + 'title', + 'alias', + 'meta_title', + 'meta_description', + 'h1', + 'seo_text', + ], + 'string', + 'max' => 255, + ], + [ + [ 'alias' ], + 'unique', + ], + [ + [ + 'blog_category_id', + 'language_id', + ], + 'unique', + 'targetAttribute' => [ + 'blog_category_id', + 'language_id', + ], + 'message' => 'The combination of Blog Category ID and Language ID has already been taken.', + ], + [ + [ 'blog_category_id' ], + 'exist', + 'skipOnError' => true, + 'targetClass' => BlogCategory::className(), + 'targetAttribute' => [ 'blog_category_id' => 'id' ], + ], + [ + [ 'language_id' ], + 'exist', + 'skipOnError' => true, + 'targetClass' => Language::className(), + 'targetAttribute' => [ 'language_id' => 'id' ], + ], + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'blog_category_id' => 'Blog Category ID', + 'language_id' => 'Language ID', + 'title' => 'Title', + 'alias' => 'Alias', + 'description' => 'Description', + 'meta_title' => 'Meta Title', + 'meta_description' => 'Meta Description', + 'h1' => 'H1', + 'seo_text' => 'Seo Text', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getBlogCategory() + { + return $this->hasOne(BlogCategory::className(), [ 'id' => 'blog_category_id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getLanguage() + { + return $this->hasOne(Language::className(), [ 'id' => 'language_id' ]); + } + } diff --git a/common/modules/blog/models/BlogCategorySearch.php b/common/modules/blog/models/BlogCategorySearch.php new file mode 100644 index 0000000..5fc5d92 --- /dev/null +++ b/common/modules/blog/models/BlogCategorySearch.php @@ -0,0 +1,128 @@ +joinWith('lang', 'parent.lang'); + + // add conditions that should always apply here + + $dataProvider = new ActiveDataProvider( + [ + 'query' => $query, + 'sort' => [ + 'attributes' => [ + 'title' => [ + 'asc' => [ 'blog_category_lang.title' => SORT_ASC ], + 'desc' => [ 'blog_category_lang.title' => SORT_DESC ], + ], + 'id', + ], + ], + ] + ); + + $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( + [ + 'id' => $this->id, + 'sort' => $this->sort, + 'parent_id' => $this->parent_id, + 'status' => $this->status, + ] + ); + + $query->andFilterWhere( + [ + 'like', + 'image', + $this->image, + ] + ); + + $query->andFilterWhere( + [ + 'like', + 'blog_category_lang.title', + $this->title, + ] + ); + + return $dataProvider; + } + } diff --git a/common/modules/blog/models/BlogTag.php b/common/modules/blog/models/BlogTag.php new file mode 100644 index 0000000..d65d43e --- /dev/null +++ b/common/modules/blog/models/BlogTag.php @@ -0,0 +1,109 @@ + [ + 'class' => LanguageBehavior::className(), + ], + ]; + } + + /** + * @inheritdoc + */ + public function rules() + { + return [ + [ + [ 'id' ], + 'integer', + ], + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getBlogArticles() + { + return $this->hasMany(BlogArticle::className(), [ 'id' => 'blog_article_id' ]) + ->viaTable('blog_article_to_tag', [ 'blog_tag_id' => 'id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getBlogTagLangs() + { + return $this->hasMany(BlogTagLang::className(), [ 'blog_tag_id' => 'id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getLanguages() + { + return $this->hasMany(Language::className(), [ 'id' => 'language_id' ]) + ->viaTable('blog_tag_lang', [ 'blog_tag_id' => 'id' ]); + } + } diff --git a/common/modules/blog/models/BlogTagLang.php b/common/modules/blog/models/BlogTagLang.php new file mode 100644 index 0000000..a894712 --- /dev/null +++ b/common/modules/blog/models/BlogTagLang.php @@ -0,0 +1,110 @@ + 255, + ], + [ + [ + 'blog_tag_id', + 'language_id', + ], + 'unique', + 'targetAttribute' => [ + 'blog_tag_id', + 'language_id', + ], + 'message' => 'The combination of Blog Tag ID and Language ID has already been taken.', + ], + [ + [ 'blog_tag_id' ], + 'exist', + 'skipOnError' => true, + 'targetClass' => BlogTag::className(), + 'targetAttribute' => [ 'blog_tag_id' => 'id' ], + ], + [ + [ 'language_id' ], + 'exist', + 'skipOnError' => true, + 'targetClass' => Language::className(), + 'targetAttribute' => [ 'language_id' => 'id' ], + ], + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'blog_tag_id' => 'Blog Tag ID', + 'language_id' => 'Language ID', + 'label' => 'Label', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getBlogTag() + { + return $this->hasOne(BlogTag::className(), [ 'id' => 'blog_tag_id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getLanguage() + { + return $this->hasOne(Language::className(), [ 'id' => 'language_id' ]); + } + } diff --git a/common/modules/blog/models/BlogTagSearch.php b/common/modules/blog/models/BlogTagSearch.php new file mode 100644 index 0000000..758fd70 --- /dev/null +++ b/common/modules/blog/models/BlogTagSearch.php @@ -0,0 +1,106 @@ +joinWith('lang'); + + // add conditions that should always apply here + + $dataProvider = new ActiveDataProvider( + [ + 'query' => $query, + 'sort' => [ + 'attributes' => [ + 'id', + 'label' => [ + 'asc' => [ 'blog_tag_lang.label' => SORT_ASC ], + 'desc' => [ 'blog_tag_lang.label' => 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( + [ + 'id' => $this->id, + ] + ); + + $query->andFilterWhere( + [ + 'like', + 'blog_tag_lang.label', + $this->label, + ] + ); + + return $dataProvider; + } + } diff --git a/common/modules/blog/views/blog-article/_form.php b/common/modules/blog/views/blog-article/_form.php new file mode 100644 index 0000000..d9e8b35 --- /dev/null +++ b/common/modules/blog/views/blog-article/_form.php @@ -0,0 +1,187 @@ + + +
+ + [ 'enctype' => 'multipart/form-data' ], + ] + ); ?> + + $modelLangs, + 'formView' => '@common/modules/blog/views/blog-article/_form_language', + 'form' => $form, + ] + ); + ?> + + field($model, 'blogCategories') + ->widget( + Select2::className(), + [ + 'data' => $categories, + 'theme' => Select2::THEME_BOOTSTRAP, + 'options' => [ + 'placeholder' => \Yii::t('blog', 'Select category'), + 'multiple' => true, + ], + 'pluginOptions' => [ + 'allowClear' => true, + ], + ] + ); + ?> + + field($model, 'blogTags') + ->widget( + Select2::className(), + [ + 'data' => $tags, + 'theme' => Select2::THEME_BOOTSTRAP, + 'options' => [ + 'placeholder' => \Yii::t('blog', 'Select tag'), + 'multiple' => true, + ], + 'pluginOptions' => [ + 'allowClear' => true, + ], + ] + ); + ?> + + field($model, 'image') + ->widget( + \kartik\file\FileInput::className(), + [ + 'language' => 'ru', + 'options' => [ + 'accept' => 'image/*', + 'multiple' => false, + ], + 'pluginOptions' => [ + 'allowedFileExtensions' => [ + 'jpg', + 'gif', + 'png', + ], + 'initialPreview' => !empty( $model->imageUrl ) ? \common\components\artboximage\ArtboxImageHelper::getImage( + $model->imageUrl, + 'list' + ) : '', + 'overwriteInitial' => true, + 'showRemove' => false, + 'showUpload' => false, + 'previewFileType' => 'image', + ], + ] + ); ?> + + field($model, 'products') + ->widget( + Select2::className(), + [ + 'data' => $products, + 'options' => [ + 'placeholder' => \Yii::t('blog', 'Select related products'), + 'multiple' => true, + ], + 'pluginOptions' => [ + 'allowClear' => true, + 'minimumInputLength' => 3, + 'language' => [ + 'errorLoading' => new JsExpression( + "function () { return '" . \Yii::t('blog', 'Waiting for results') . "'; }" + ), + ], + 'ajax' => [ + 'url' => yii\helpers\Url::to([ '/blog/blog-article/product-list' ]), + 'dataType' => 'json', + 'data' => new JsExpression('function(params) { return {q:params.term}; }'), + ], + 'templateResult' => new JsExpression('function(product) { return product.text; }'), + 'templateSelection' => new JsExpression('function (product) { return product.text; }'), + ], + ] + ); + ?> + + field($model, 'blogArticles') + ->widget( + Select2::className(), + [ + 'data' => $articles, + 'options' => [ + 'placeholder' => \Yii::t('blog', 'Select related articles'), + 'multiple' => true, + ], + 'pluginOptions' => [ + 'allowClear' => true, + 'minimumInputLength' => 3, + 'language' => [ + 'errorLoading' => new JsExpression( + "function () { return '" . \Yii::t('blog', 'Waiting for results') . "'; }" + ), + ], + 'ajax' => [ + 'url' => yii\helpers\Url::to([ '/blog/blog-article/article-list' ]), + 'dataType' => 'json', + 'data' => new JsExpression( + 'function(params) { return {q:params.term, id:' . $model->id . '}; }' + ), + ], + 'templateResult' => new JsExpression('function(article) { return article.text; }'), + 'templateSelection' => new JsExpression('function (article) { return article.text; }'), + ], + ] + ); + ?> + + field($model, 'sort') + ->textInput() ?> + + field($model, 'status') + ->checkbox() ?> + + field($model, 'author_id') + ->textInput() ?> + +
+ isNewRecord ? 'Create' : 'Update', + [ 'class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary' ] + ) ?> +
+ + + +
diff --git a/common/modules/blog/views/blog-article/_form_language.php b/common/modules/blog/views/blog-article/_form_language.php new file mode 100644 index 0000000..cd5583e --- /dev/null +++ b/common/modules/blog/views/blog-article/_form_language.php @@ -0,0 +1,55 @@ + +field($model_lang, '[' . $language->id . ']title') + ->textInput([ 'maxlength' => true ]); ?> + +field($model_lang, '[' . $language->id . ']alias') + ->textInput([ 'maxlength' => true ]); ?> + +field($model_lang, '[' . $language->id . ']body') + ->widget( + CKEditor::className(), + [ + 'editorOptions' => ElFinder::ckeditorOptions( + 'elfinder', + [ + 'preset' => 'full', + 'inline' => false, + 'filebrowserUploadUrl' => Yii::$app->getUrlManager() + ->createUrl('file/uploader/images-upload'), + ] + ), + ] + ) ?> + +field($model_lang, '[' . $language->id . ']body_preview') + ->textarea( + [ + 'rows' => '10', + ] + ) ?> + +field($model_lang, '[' . $language->id . ']meta_title') + ->textInput([ 'maxlength' => true ]); ?> + +field($model_lang, '[' . $language->id . ']meta_description') + ->textInput([ 'maxlength' => true ]); ?> + +field($model_lang, '[' . $language->id . ']seo_text') + ->textInput([ 'maxlength' => true ]); ?> + +field($model_lang, '[' . $language->id . ']h1') + ->textInput([ 'maxlength' => true ]); ?> diff --git a/common/modules/blog/views/blog-article/_search.php b/common/modules/blog/views/blog-article/_search.php new file mode 100644 index 0000000..dd2dc78 --- /dev/null +++ b/common/modules/blog/views/blog-article/_search.php @@ -0,0 +1,43 @@ + + +
+ + [ 'index' ], + 'method' => 'get', + ] + ); ?> + + field($model, 'id') ?> + + field($model, 'image') ?> + + field($model, 'created_at') ?> + + field($model, 'updated_at') ?> + + field($model, 'deleted_at') ?> + + field($model, 'sort') ?> + + field($model, 'status')->checkbox() ?> + + field($model, 'author_id') ?> + +
+ 'btn btn-primary' ]) ?> + 'btn btn-default' ]) ?> +
+ + + +
diff --git a/common/modules/blog/views/blog-article/create.php b/common/modules/blog/views/blog-article/create.php new file mode 100644 index 0000000..0211f70 --- /dev/null +++ b/common/modules/blog/views/blog-article/create.php @@ -0,0 +1,43 @@ +title = \Yii::t('blog', 'Create Blog Article'); + $this->params[ 'breadcrumbs' ][] = [ + 'label' => \Yii::t('blog', 'Blog Articles'), + 'url' => [ 'index' ], + ]; + $this->params[ 'breadcrumbs' ][] = $this->title; +?> +
+ +

title) ?>

+ + render( + '_form', + [ + 'model' => $model, + 'modelLangs' => $modelLangs, + 'categories' => $categories, + 'tags' => $tags, + 'products' => $products, + 'articles' => $articles, + ] + ) ?> + +
diff --git a/common/modules/blog/views/blog-article/index.php b/common/modules/blog/views/blog-article/index.php new file mode 100644 index 0000000..57564c2 --- /dev/null +++ b/common/modules/blog/views/blog-article/index.php @@ -0,0 +1,57 @@ +title = \Yii::t('blog', 'Blog Articles'); + $this->params[ 'breadcrumbs' ][] = $this->title; +?> +
+ +

title) ?>

+ render('_search', ['model' => $searchModel]); ?> + +

+ 'btn btn-success' ]) ?> +

+ $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + 'id', + [ + 'attribute' => 'title', + 'value' => 'lang.title', + ], + 'imageUrl:image', + [ + 'attribute' => 'status', + 'value' => function($model) { + /** + * @var BlogArticle $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/common/modules/blog/views/blog-article/update.php b/common/modules/blog/views/blog-article/update.php new file mode 100644 index 0000000..a7c0632 --- /dev/null +++ b/common/modules/blog/views/blog-article/update.php @@ -0,0 +1,50 @@ +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'); +?> +
+ +

title) ?>

+ + render( + '_form', + [ + 'model' => $model, + 'modelLangs' => $modelLangs, + 'categories' => $categories, + 'tags' => $tags, + 'products' => $products, + 'articles' => $articles, + ] + ) ?> + +
diff --git a/common/modules/blog/views/blog-article/view.php b/common/modules/blog/views/blog-article/view.php new file mode 100644 index 0000000..c96e500 --- /dev/null +++ b/common/modules/blog/views/blog-article/view.php @@ -0,0 +1,67 @@ +title = $model->lang->title; + $this->params[ 'breadcrumbs' ][] = [ + 'label' => \Yii::t('blog', 'Blog Articles'), + 'url' => [ 'index' ], + ]; + $this->params[ 'breadcrumbs' ][] = $this->title; +?> +
+ +

title) ?>

+ +

+ $model->id, + ], + [ 'class' => 'btn btn-primary' ] + ) ?> + $model->id, + ], + [ + 'class' => 'btn btn-danger', + 'data' => [ + 'confirm' => 'Are you sure you want to delete this item?', + 'method' => 'post', + ], + ] + ) ?> +

+ + $model, + 'attributes' => [ + 'id', + 'imageUrl:image', + 'created_at:date', + 'updated_at:date', + [ + 'attribute' => 'status', + 'value' => ( !$model->status ) ? \Yii::t('blog', 'Not active') : \Yii::t('blog', 'Active'), + ], + 'lang.alias', + 'lang.body:html', + ], + ] + ) ?> + +
diff --git a/common/modules/blog/views/blog-category/_form.php b/common/modules/blog/views/blog-category/_form.php new file mode 100644 index 0000000..b9f0a21 --- /dev/null +++ b/common/modules/blog/views/blog-category/_form.php @@ -0,0 +1,94 @@ + + +
+ + [ 'enctype' => 'multipart/form-data' ], + + ] + ); ?> + + $modelLangs, + 'formView' => '@common/modules/blog/views/blog-category/_form_language', + 'form' => $form, + ] + ); + ?> + + field($model, 'image') + ->widget( + \kartik\file\FileInput::className(), + [ + 'language' => 'ru', + 'options' => [ + 'accept' => 'image/*', + 'multiple' => false, + ], + 'pluginOptions' => [ + 'allowedFileExtensions' => [ + 'jpg', + 'gif', + 'png', + ], + 'initialPreview' => !empty( $model->imageUrl ) ? \common\components\artboximage\ArtboxImageHelper::getImage( + $model->imageUrl, + 'list' + ) : '', + 'overwriteInitial' => true, + 'showRemove' => false, + 'showUpload' => false, + 'previewFileType' => 'image', + ], + ] + ); ?> + + field($model, 'sort') + ->textInput() ?> + + field($model, 'parent_id') + ->widget( + Select2::className(), + [ + 'data' => $parentCategories, + 'options' => [ 'placeholder' => \Yii::t('blog', 'Has no parent rubric') ], + 'pluginOptions' => [ + 'allowClear' => true, + ], + ] + ); + ?> + + field($model, 'status') + ->checkbox() ?> + +
+ isNewRecord ? 'Create' : 'Update', + [ 'class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary' ] + ) ?> +
+ + + +
diff --git a/common/modules/blog/views/blog-category/_form_language.php b/common/modules/blog/views/blog-category/_form_language.php new file mode 100644 index 0000000..7da5d86 --- /dev/null +++ b/common/modules/blog/views/blog-category/_form_language.php @@ -0,0 +1,37 @@ + +field($model_lang, '[' . $language->id . ']title') + ->textInput([ 'maxlength' => true ]); ?> + +field($model_lang, '[' . $language->id . ']alias') + ->textInput([ 'maxlength' => true ]); ?> + +field($model_lang, '[' . $language->id . ']description') + ->textarea( + [ + 'rows' => '10', + ] + ) ?> + +field($model_lang, '[' . $language->id . ']meta_title') + ->textInput([ 'maxlength' => true ]); ?> + +field($model_lang, '[' . $language->id . ']meta_description') + ->textInput([ 'maxlength' => true ]); ?> + +field($model_lang, '[' . $language->id . ']seo_text') + ->textInput([ 'maxlength' => true ]); ?> + +field($model_lang, '[' . $language->id . ']h1') + ->textInput([ 'maxlength' => true ]); ?> diff --git a/common/modules/blog/views/blog-category/_search.php b/common/modules/blog/views/blog-category/_search.php new file mode 100644 index 0000000..b79d09d --- /dev/null +++ b/common/modules/blog/views/blog-category/_search.php @@ -0,0 +1,35 @@ + + + diff --git a/common/modules/blog/views/blog-category/create.php b/common/modules/blog/views/blog-category/create.php new file mode 100644 index 0000000..aa403d3 --- /dev/null +++ b/common/modules/blog/views/blog-category/create.php @@ -0,0 +1,35 @@ +title = \Yii::t('blog', 'Create Blog Category'); + $this->params[ 'breadcrumbs' ][] = [ + 'label' => \Yii::t('blog', 'Blog Categories'), + 'url' => [ 'index' ], + ]; + $this->params[ 'breadcrumbs' ][] = $this->title; +?> +
+ +

title) ?>

+ + render( + '_form', + [ + 'model' => $model, + 'modelLangs' => $modelLangs, + 'parentCategories' => $parentCategories, + ] + ) ?> + +
diff --git a/common/modules/blog/views/blog-category/index.php b/common/modules/blog/views/blog-category/index.php new file mode 100644 index 0000000..4223172 --- /dev/null +++ b/common/modules/blog/views/blog-category/index.php @@ -0,0 +1,68 @@ +title = \Yii::t('blog', 'Blog Categories'); + $this->params[ 'breadcrumbs' ][] = $this->title; +?> +
+ +

title) ?>

+ render('_search', ['model' => $searchModel]); ?> + +

+ 'btn btn-success' ]) ?> +

+ $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + 'id', + [ + 'attribute' => 'title', + 'value' => 'lang.title', + ], + 'imageUrl:image', + [ + 'label' => \Yii::t('blog', 'Parent category'), + 'value' => function($model) { + /** + * @var BlogCategory $model + */ + if (!empty( $model->parent )) { + return $model->parent->lang->title; + } else { + return false; + }; + }, + ], + [ + 'attribute' => 'status', + 'value' => function($model) { + /** + * @var BlogCategory $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'), + ], + ], + [ 'class' => 'yii\grid\ActionColumn' ], + ], + ] + ); ?> +
diff --git a/common/modules/blog/views/blog-category/update.php b/common/modules/blog/views/blog-category/update.php new file mode 100644 index 0000000..1663cc0 --- /dev/null +++ b/common/modules/blog/views/blog-category/update.php @@ -0,0 +1,42 @@ +title = \Yii::t('blog', 'Update Blog Category: ') . $model->lang->title; + $this->params[ 'breadcrumbs' ][] = [ + 'label' => \Yii::t('blog', 'Blog Categories'), + 'url' => [ 'index' ], + ]; + $this->params[ 'breadcrumbs' ][] = [ + 'label' => $model->lang->title, + 'url' => [ + 'view', + 'id' => $model->id, + ], + ]; + $this->params[ 'breadcrumbs' ][] = \Yii::t('blog', 'Update'); +?> +
+ +

title) ?>

+ + render( + '_form', + [ + 'model' => $model, + 'modelLangs' => $modelLangs, + 'parentCategories' => $parentCategories, + ] + ) ?> + +
diff --git a/common/modules/blog/views/blog-category/view.php b/common/modules/blog/views/blog-category/view.php new file mode 100644 index 0000000..fc61c9d --- /dev/null +++ b/common/modules/blog/views/blog-category/view.php @@ -0,0 +1,70 @@ +title = $model->lang->title; + $this->params[ 'breadcrumbs' ][] = [ + 'label' => \Yii::t('blog', 'Blog Categories'), + 'url' => [ 'index' ], + ]; + $this->params[ 'breadcrumbs' ][] = $this->title; +?> +
+ +

title) ?>

+ +

+ $model->id, + ], + [ 'class' => 'btn btn-primary' ] + ) ?> + $model->id, + ], + [ + 'class' => 'btn btn-danger', + 'data' => [ + 'confirm' => 'Are you sure you want to delete this item?', + 'method' => 'post', + ], + ] + ) ?> +

+ + $model, + 'attributes' => [ + 'id', + 'sort', + 'imageUrl:image', + [ + 'attribute' => 'parent_id', + 'value' => ( !empty( $model->parent ) ) ? $model->parent->lang->title : '', + ], + 'lang.alias', + 'lang.description:text', + [ + 'attribute' => 'status', + 'value' => ( $model->status ) ? \Yii::t('blog', 'Active') : \Yii::t('blog', 'Not active'), + ], + ], + ] + ) ?> + +
diff --git a/common/modules/blog/views/blog-tag/_form.php b/common/modules/blog/views/blog-tag/_form.php new file mode 100644 index 0000000..e257df5 --- /dev/null +++ b/common/modules/blog/views/blog-tag/_form.php @@ -0,0 +1,41 @@ + + +
+ + + + $modelLangs, + 'formView' => '@common/modules/blog/views/blog-tag/_form_language', + 'form' => $form, + ] + ); + ?> + +
+ isNewRecord ? 'Create' : 'Update', + [ 'class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary' ] + ) ?> +
+ + + +
diff --git a/common/modules/blog/views/blog-tag/_form_language.php b/common/modules/blog/views/blog-tag/_form_language.php new file mode 100644 index 0000000..d1fc0a1 --- /dev/null +++ b/common/modules/blog/views/blog-tag/_form_language.php @@ -0,0 +1,15 @@ + +field($model_lang, '[' . $language->id . ']label') + ->textInput([ 'maxlength' => true ]); ?> diff --git a/common/modules/blog/views/blog-tag/_search.php b/common/modules/blog/views/blog-tag/_search.php new file mode 100644 index 0000000..32b4064 --- /dev/null +++ b/common/modules/blog/views/blog-tag/_search.php @@ -0,0 +1,27 @@ + + + diff --git a/common/modules/blog/views/blog-tag/create.php b/common/modules/blog/views/blog-tag/create.php new file mode 100644 index 0000000..4c515e1 --- /dev/null +++ b/common/modules/blog/views/blog-tag/create.php @@ -0,0 +1,33 @@ +title = \Yii::t('blog', 'Create Blog Tag'); + $this->params[ 'breadcrumbs' ][] = [ + 'label' => \Yii::t('blog', 'Blog Tags'), + 'url' => [ 'index' ], + ]; + $this->params[ 'breadcrumbs' ][] = $this->title; +?> +
+ +

title) ?>

+ + render( + '_form', + [ + 'model' => $model, + 'modelLangs' => $modelLangs, + ] + ) ?> + +
diff --git a/common/modules/blog/views/blog-tag/index.php b/common/modules/blog/views/blog-tag/index.php new file mode 100644 index 0000000..408174b --- /dev/null +++ b/common/modules/blog/views/blog-tag/index.php @@ -0,0 +1,42 @@ +title = \Yii::t('blog', 'Blog Tags'); + $this->params[ 'breadcrumbs' ][] = $this->title; +?> +
+ +

title) ?>

+ render('_search', ['model' => $searchModel]); ?> + +

+ 'btn btn-success' ]) ?> +

+ $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + 'id', + [ + 'attribute' => 'label', + 'value' => 'lang.label', + ], + [ + 'class' => 'yii\grid\ActionColumn', + ], + ], + ] + ); ?> +
diff --git a/common/modules/blog/views/blog-tag/update.php b/common/modules/blog/views/blog-tag/update.php new file mode 100644 index 0000000..564a089 --- /dev/null +++ b/common/modules/blog/views/blog-tag/update.php @@ -0,0 +1,40 @@ +title = \Yii::t('blog', 'Update Blog Tag: ') . $model->lang->label; + $this->params[ 'breadcrumbs' ][] = [ + 'label' => \Yii::t('blog', 'Blog Tags'), + 'url' => [ 'index' ], + ]; + $this->params[ 'breadcrumbs' ][] = [ + 'label' => $model->lang->label, + 'url' => [ + 'view', + 'id' => $model->id, + ], + ]; + $this->params[ 'breadcrumbs' ][] = \Yii::t('blog', 'Update'); +?> +
+ +

title) ?>

+ + render( + '_form', + [ + 'model' => $model, + 'modelLangs' => $modelLangs, + ] + ) ?> + +
diff --git a/common/modules/blog/views/blog-tag/view.php b/common/modules/blog/views/blog-tag/view.php new file mode 100644 index 0000000..897be1c --- /dev/null +++ b/common/modules/blog/views/blog-tag/view.php @@ -0,0 +1,59 @@ +title = $model->lang->label; + $this->params[ 'breadcrumbs' ][] = [ + 'label' => \Yii::t('blog', 'Blog Tags'), + 'url' => [ 'index' ], + ]; + $this->params[ 'breadcrumbs' ][] = $this->title; +?> +
+ +

title) ?>

+ +

+ $model->id, + ], + [ 'class' => 'btn btn-primary' ] + ) ?> + $model->id, + ], + [ + 'class' => 'btn btn-danger', + 'data' => [ + 'confirm' => 'Are you sure you want to delete this item?', + 'method' => 'post', + ], + ] + ) ?> +

+ + $model, + 'attributes' => [ + 'id', + 'lang.label', + ], + ] + ) ?> + +
diff --git a/common/modules/blog/views/default/index.php b/common/modules/blog/views/default/index.php new file mode 100644 index 0000000..650b9c5 --- /dev/null +++ b/common/modules/blog/views/default/index.php @@ -0,0 +1,12 @@ +
+

context->action->uniqueId ?>

+

+ This is the view content for action "context->action->id ?>". + The action belongs to the controller "context) ?>" + in the "context->module->id ?>" module. +

+

+ You may customize this page by editing the following file:
+ +

+
diff --git a/common/translation/ru/blog.php b/common/translation/ru/blog.php new file mode 100644 index 0000000..936138e --- /dev/null +++ b/common/translation/ru/blog.php @@ -0,0 +1,22 @@ + 'Выберите категорию ...', + 'Select tag' => 'Выберите тэг ...', + 'Has no parent rubric' => 'Без категории', + 'Waiting for results' => 'Загрузка ...', + 'Select related products' => 'Выберите сопутствующие товары', + 'Select related articles' => 'Выберите статьи', + 'Blog Articles' => 'Статьи блога', + 'Create Blog Article' => 'Создать статью', + 'Update Blog Article: ' => 'Обновить статью: ', + 'Not active' => 'Не активна', + 'Active' => 'Активна', + 'Are you sure you want to delete this item?' => 'Вы точно хотите это удалить ?', + 'Update' => 'Обновить', + 'Blog Categories' => 'Рубрики', + 'Create Blog Category' => 'Создать рубрику', + 'Update Blog Category: ' => 'Обновить рубрику: ', + 'Blog Tags' => 'Тэги', + 'Create Blog Tag' => 'Создать тэг', + 'Update Blog Tag: ' => 'Обновить тэг: ', + ]; \ No newline at end of file diff --git a/console/migrations/blog/m161101_142334_blog_article.php b/console/migrations/blog/m161101_142334_blog_article.php new file mode 100644 index 0000000..235e2cb --- /dev/null +++ b/console/migrations/blog/m161101_142334_blog_article.php @@ -0,0 +1,31 @@ +createTable( + 'blog_article', + [ + 'id' => $this->primaryKey(), + 'image' => $this->string(255), + 'created_at' => $this->integer(), + 'updated_at' => $this->integer(), + 'deleted_at' => $this->integer(), + 'sort' => $this->integer(), + 'status' => $this->boolean(), + 'author_id' => $this->integer(), + ] + ); + } + + public function down() + { + $this->dropTable('blog_article'); + } +} diff --git a/console/migrations/blog/m161101_142752_blog_article_lang.php b/console/migrations/blog/m161101_142752_blog_article_lang.php new file mode 100644 index 0000000..2fabca7 --- /dev/null +++ b/console/migrations/blog/m161101_142752_blog_article_lang.php @@ -0,0 +1,83 @@ +createTable( + 'blog_article_lang', + [ + 'id' => $this->primaryKey(), + 'blog_article_id' => $this->integer() + ->notNull(), + 'language_id' => $this->integer() + ->notNull(), + 'title' => $this->string(255), + 'body' => $this->text(), + 'body_preview' => $this->text(), + 'alias' => $this->string(255), + 'meta_title' => $this->string(255), + 'meta_description' => $this->string(255), + 'h1' => $this->string(255), + 'seo_text' => $this->string(255), + ] + ); + + /** + * Creating indexes for unique fields (field pairs) + */ + $this->createIndex( + 'blog_article_lang_uk', + 'blog_article_lang', + [ + 'blog_article_id', + 'language_id', + ], + true + ); + + $this->createIndex( + 'blog_article_alias_uk', + 'blog_article_lang', + 'alias', + true + ); + + /** + * Add foreign keys in blog_articles and language tables + */ + $this->addForeignKey( + 'blog_article_fk', + 'blog_article_lang', + 'blog_article_id', + 'blog_article', + 'id', + 'CASCADE', + 'CASCADE' + ); + + $this->addForeignKey( + 'blog_article_lang_fk', + 'blog_article_lang', + 'language_id', + 'language', + 'id', + 'RESTRICT', + 'CASCADE' + ); + } + + public function down() + { + $this->dropForeignKey('blog_article_lang_fk', 'blog_article_lang'); + $this->dropForeignKey('blog_article_fk', 'blog_article_lang'); + $this->dropIndex('blog_article_alias_uk', 'blog_article_lang'); + $this->dropIndex('blog_article_lang_uk', 'blog_article_lang'); + $this->dropTable('blog_article_lang'); + } +} diff --git a/console/migrations/blog/m161101_143033_blog_category.php b/console/migrations/blog/m161101_143033_blog_category.php new file mode 100644 index 0000000..e2bfe5f --- /dev/null +++ b/console/migrations/blog/m161101_143033_blog_category.php @@ -0,0 +1,29 @@ +createTable( + 'blog_category', + [ + 'id' => $this->primaryKey(), + 'sort' => $this->integer(), + 'image' => $this->string(255), + 'parent_id' => $this->integer() + ->defaultValue(0), + 'status' => $this->boolean(), + ] + ); + } + + public function down() + { + $this->dropTable('blog_category'); + } +} diff --git a/console/migrations/blog/m161101_143259_blog_category_lang.php b/console/migrations/blog/m161101_143259_blog_category_lang.php new file mode 100644 index 0000000..72f2e14 --- /dev/null +++ b/console/migrations/blog/m161101_143259_blog_category_lang.php @@ -0,0 +1,82 @@ +createTable( + 'blog_category_lang', + [ + 'id' => $this->primaryKey(), + 'blog_category_id' => $this->integer() + ->notNull(), + 'language_id' => $this->integer() + ->notNull(), + 'title' => $this->string(255), + 'alias' => $this->string(255), + 'description' => $this->text(), + 'meta_title' => $this->string(255), + 'meta_description' => $this->string(255), + 'h1' => $this->string(255), + 'seo_text' => $this->string(255), + ] + ); + + /** + * Create unique indexes for language and alias + */ + $this->createIndex( + 'blog_category_lang_uk', + 'blog_category_lang', + [ + 'blog_category_id', + 'language_id', + ], + true + ); + + $this->createIndex( + 'blog_category_alias_uk', + 'blog_category_lang', + 'alias', + true + ); + + /** + * Add foreign keys for language tables + */ + $this->addForeignKey( + 'blog_category_fk', + 'blog_category_lang', + 'blog_category_id', + 'blog_category', + 'id', + 'CASCADE', + 'CASCADE' + ); + + $this->addForeignKey( + 'blog_category_lang_fk', + 'blog_category_lang', + 'language_id', + 'language', + 'id', + 'RESTRICT', + 'CASCADE' + ); + } + + public function down() + { + $this->dropForeignKey('blog_category_lang_fk', 'blog_category_lang'); + $this->dropForeignKey('blog_category_fk', 'blog_category_lang'); + $this->dropIndex('blog_category_alias_uk', 'blog_category_lang'); + $this->dropIndex('blog_category_lang_uk', 'blog_category_lang'); + $this->dropTable('blog_category_lang'); + } +} diff --git a/console/migrations/blog/m161101_143541_blog_article_to_category.php b/console/migrations/blog/m161101_143541_blog_article_to_category.php new file mode 100644 index 0000000..fd21784 --- /dev/null +++ b/console/migrations/blog/m161101_143541_blog_article_to_category.php @@ -0,0 +1,64 @@ +createTable( + 'blog_article_to_category', + [ + 'id' => $this->primaryKey(), + 'blog_article_id' => $this->integer() + ->notNull(), + 'blog_category_id' => $this->integer() + ->notNull(), + ] + ); + + /** + * Add foreign keys and indexes for junction table + */ + $this->createIndex( + 'blog_article_to_category_uk', + 'blog_article_to_category', + [ + 'blog_article_id', + 'blog_category_id', + ], + true + ); + + $this->addForeignKey( + 'blog_article_to_category_art_fk', + 'blog_article_to_category', + 'blog_article_id', + 'blog_article', + 'id', + 'CASCADE', + 'CASCADE' + ); + + $this->addForeignKey( + 'blog_article_to_category_cat_fk', + 'blog_article_to_category', + 'blog_category_id', + 'blog_category', + 'id', + 'CASCADE', + 'CASCADE' + ); + } + + public function down() + { + $this->dropForeignKey('blog_article_to_category_cat_fk', 'blog_article_to_category'); + $this->dropForeignKey('blog_article_to_category_art_fk', 'blog_article_to_category'); + $this->dropIndex('blog_article_to_category_uk', 'blog_article_to_category'); + $this->dropTable('blog_article_to_category'); + } +} diff --git a/console/migrations/blog/m161101_143734_blog_tag.php b/console/migrations/blog/m161101_143734_blog_tag.php new file mode 100644 index 0000000..292ee38 --- /dev/null +++ b/console/migrations/blog/m161101_143734_blog_tag.php @@ -0,0 +1,24 @@ +createTable( + 'blog_tag', + [ + 'id' => $this->primaryKey(), + ] + ); + } + + public function down() + { + $this->dropTable('blog_tag'); + } +} diff --git a/console/migrations/blog/m161101_143939_blog_tag_lang.php b/console/migrations/blog/m161101_143939_blog_tag_lang.php new file mode 100644 index 0000000..a98a4d5 --- /dev/null +++ b/console/migrations/blog/m161101_143939_blog_tag_lang.php @@ -0,0 +1,65 @@ +createTable( + 'blog_tag_lang', + [ + 'id' => $this->primaryKey(), + 'blog_tag_id' => $this->integer() + ->notNull(), + 'language_id' => $this->integer() + ->notNull(), + 'label' => $this->string(255), + ] + ); + + /** + * Creating indexes and foreign keys for language table + */ + $this->createIndex( + 'blog_tag_lang_uk', + 'blog_tag_lang', + [ + 'blog_tag_id', + 'language_id', + ], + true + ); + + $this->addForeignKey( + 'blog_tag_lang_fk', + 'blog_tag_lang', + 'language_id', + 'language', + 'id', + 'RESTRICT', + 'CASCADE' + ); + + $this->addForeignKey( + 'blog_tag_fk', + 'blog_tag_lang', + 'blog_tag_id', + 'blog_tag', + 'id', + 'CASCADE', + 'CASCADE' + ); + } + + public function down() + { + $this->dropForeignKey('blog_tag_fk', 'blog_tag_lang'); + $this->dropForeignKey('blog_tag_lang_fk', 'blog_tag_lang'); + $this->dropIndex('blog_tag_lang_uk', 'blog_tag_lang'); + $this->dropTable('blog_tag_lang'); + } +} diff --git a/console/migrations/blog/m161101_144140_blog_article_to_tag.php b/console/migrations/blog/m161101_144140_blog_article_to_tag.php new file mode 100644 index 0000000..aed42ad --- /dev/null +++ b/console/migrations/blog/m161101_144140_blog_article_to_tag.php @@ -0,0 +1,64 @@ +createTable( + 'blog_article_to_tag', + [ + 'id' => $this->primaryKey(), + 'blog_article_id' => $this->integer() + ->notNull(), + 'blog_tag_id' => $this->integer() + ->notNull(), + ] + ); + + /** + * Create indexes and foreign keys for junction table + */ + $this->createIndex( + 'blog_article_to_tag_uk', + 'blog_article_to_tag', + [ + 'blog_article_id', + 'blog_tag_id', + ], + true + ); + + $this->addForeignKey( + 'blog_article_to_tag_tag_fk', + 'blog_article_to_tag', + 'blog_tag_id', + 'blog_tag', + 'id', + 'CASCADE', + 'CASCADE' + ); + + $this->addForeignKey( + 'blog_article_to_tag_art_fk', + 'blog_article_to_tag', + 'blog_article_id', + 'blog_article', + 'id', + 'CASCADE', + 'CASCADE' + ); + } + + public function down() + { + $this->dropForeignKey('blog_article_to_tag_art_fk', 'blog_article_to_tag'); + $this->dropForeignKey('blog_article_to_tag_tag_fk', 'blog_article_to_tag'); + $this->dropIndex('blog_article_to_tag_uk', 'blog_article_to_tag'); + $this->dropTable('blog_article_to_tag'); + } +} diff --git a/console/migrations/blog/m161101_144312_blog_article_to_article.php b/console/migrations/blog/m161101_144312_blog_article_to_article.php new file mode 100644 index 0000000..a4f42b4 --- /dev/null +++ b/console/migrations/blog/m161101_144312_blog_article_to_article.php @@ -0,0 +1,61 @@ +createTable( + 'blog_article_to_article', + [ + 'id' => $this->primaryKey(), + 'blog_article_id' => $this->integer() + ->notNull(), + 'related_blog_article_id' => $this->integer() + ->notNull(), + ] + ); + + $this->createIndex( + 'blog_article_to_article_uk', + 'blog_article_to_article', + [ + 'blog_article_id', + 'related_blog_article_id', + ], + true + ); + + $this->addForeignKey( + 'blog_article_to_article_art_fk', + 'blog_article_to_article', + 'blog_article_id', + 'blog_article', + 'id', + 'CASCADE', + 'CASCADE' + ); + + $this->addForeignKey( + 'blog_article_to_article_rel_fk', + 'blog_article_to_article', + 'related_blog_article_id', + 'blog_article', + 'id', + 'CASCADE', + 'CASCADE' + ); + } + + public function down() + { + $this->dropForeignKey('blog_article_to_article_rel_fk', 'blog_article_to_article'); + $this->dropForeignKey('blog_article_to_article_art_fk', 'blog_article_to_article'); + $this->dropIndex('blog_article_to_article_uk', 'blog_article_to_article'); + $this->dropTable('blog_article_to_article'); + } +} diff --git a/console/migrations/blog/m161101_144434_blog_article_to_product.php b/console/migrations/blog/m161101_144434_blog_article_to_product.php new file mode 100644 index 0000000..a47bc41 --- /dev/null +++ b/console/migrations/blog/m161101_144434_blog_article_to_product.php @@ -0,0 +1,61 @@ +createTable( + 'blog_article_to_product', + [ + 'id' => $this->primaryKey(), + 'blog_article_id' => $this->integer() + ->notNull(), + 'product_id' => $this->integer() + ->notNull(), + ] + ); + + $this->createIndex( + 'blog_article_to_product_uk', + 'blog_article_to_product', + [ + 'blog_article_id', + 'product_id', + ], + true + ); + + $this->addForeignKey( + 'blog_article_to_product_art_fk', + 'blog_article_to_product', + 'blog_article_id', + 'blog_article', + 'id', + 'CASCADE', + 'CASCADE' + ); + + $this->addForeignKey( + 'blog_article_to_product_prod_fk', + 'blog_article_to_product', + 'product_id', + 'product', + 'id', + 'CASCADE', + 'CASCADE' + ); + } + + public function down() + { + $this->dropForeignKey('blog_article_to_product_prod_fk', 'blog_article_to_product'); + $this->dropForeignKey('blog_article_to_product_art_fk', 'blog_article_to_product'); + $this->dropIndex('blog_article_to_product_uk', 'blog_article_to_product'); + $this->dropTable('blog_article_to_product'); + } +} diff --git a/storage/.htaccess b/storage/.htaccess index 0a379a4..277e2f6 100755 --- a/storage/.htaccess +++ b/storage/.htaccess @@ -3,4 +3,4 @@ RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d -RewriteRule . index.php + -- libgit2 0.21.4