diff --git a/backend/controllers/BlogController.php b/backend/controllers/BlogController.php new file mode 100644 index 0000000..5823d82 --- /dev/null +++ b/backend/controllers/BlogController.php @@ -0,0 +1,29 @@ + Article::find(), + 'pagination' => [ + 'pageSize' => 10 + ] + ]); + return $this->render('articles', ['dataProvider' => $dataProvider]); + } + +} \ No newline at end of file diff --git a/backend/views/blog/articles.php b/backend/views/blog/articles.php new file mode 100644 index 0000000..f56a765 --- /dev/null +++ b/backend/views/blog/articles.php @@ -0,0 +1,32 @@ + $dataProvider, + 'columns' => [ + 'id', + 'code', + 'create_at', + [ + 'value' => function($data) { + return $data->author0->firstname.' '.$data->author0->lastname; + }, + 'header' => Yii::t('app', 'Author') + ], + [ + 'class' => Column::className(), + 'header' => Yii::t('app', 'Name'), + 'content' => function($model, $key, $index, $column) { + return $model->getArticleLangs()->where(['lang_id' => Language::getDefaultLang()->language_id])->one()->name; + } + ], + [ + 'class' => ActionColumn::className(), + 'template' => '{update} {delete}' + ] + ] +]); \ No newline at end of file diff --git a/backend/views/layouts/left.php b/backend/views/layouts/left.php index c6b710e..9000a6a 100644 --- a/backend/views/layouts/left.php +++ b/backend/views/layouts/left.php @@ -40,6 +40,16 @@ ['label' => 'Login', 'url' => ['site/login'], 'visible' => Yii::$app->user->isGuest], ['label' => 'Пользователи', 'icon' => 'fa fa-file-code-o', 'url' => ['/user/']], [ + 'label' => Yii::t('app', 'Blog'), + 'icon' => 'fa fa-share', + 'url' => '#', + 'items' => [ + ['label' => Yii::t('app', 'Static pages'), 'icon' => 'fa fa-file-code-o', 'url' => ['blog/articles', 'category_id' => '63'],], + ['label' => Yii::t('app', 'Categories'), 'icon' => 'fa fa-dashboard', 'url' => ['blog/categories'],], + ['label' => Yii::t('app', 'Articles'), 'icon' => 'fa fa-dashboard', 'url' => ['blog/articles'],], + ], + ], + [ 'label' => 'Роли', 'icon' => 'fa fa-share', 'url' => '#', diff --git a/backend/web/js/option.js b/backend/web/js/option.js index 31a0901..5a9b0ec 100644 --- a/backend/web/js/option.js +++ b/backend/web/js/option.js @@ -1,25 +1,92 @@ +function readURL(input) { + $(input).parents('.tab-pane').find('.image_inputs_prev').remove(); + var urls = []; + if (input.files) { + $.each(input.files, function(key, value) { + var reader = new FileReader(); + reader.onload = function(e) { + $(input).parent().append(''); + } + reader.readAsDataURL(value); + }); + } + return urls; +} $(function() { - var counter = 0; - $(document).on('click', '.add_row', function() { - counter++; - var clone = $('#main_row').clone().html().replace(new RegExp("Option\\[0\\]", 'g'), "Option["+counter+"]"); - console.log(form); - $(clone).appendTo('#'+form); - $('#'+form+' button[type=submit]').parent().appendTo('#'+form); - }); - $(document).on('click', '.add_lang', function() { - var field_block = $(this).parent().parent(); - if($(this).hasClass('active')) { - $(field_block).find('.main_input').attr('required', '').show(); - $(field_block).find('.lang_inputs').hide(); - $(this).removeClass('active'); - } else { - $(field_block).find('.main_input').removeAttr('required').hide(); - $(field_block).find('.lang_inputs').show(); - $(this).addClass('active'); - } - }); - $(document).on('click', '.remove_lang', function() { - $(this).parents('.form-wrapper').remove(); - }); - }); \ No newline at end of file + var counter = 0; + $(document).on('click', '.add_row', function() { + counter++; + var clone = $('#main_row').clone().html().replace(new RegExp("Option\\[0\\]", 'g'), "Option["+counter+"]"); + console.log(form); + $(clone).appendTo('#'+form); + $('#'+form+' button[type=submit]').parent().appendTo('#'+form); + }); + $(document).on('click', '.add_lang', function() { + var field_block = $(this).parent().parent(); + if($(this).hasClass('active')) { + $(field_block).find('.main_input').attr('required', '').show(); + $(field_block).find('.lang_inputs').hide(); + $(this).removeClass('active'); + } else { + $(field_block).find('.main_input').removeAttr('required').hide(); + $(field_block).find('.lang_inputs').show(); + $(this).addClass('active'); + } + }); + $(document).on('click', '.remove_lang', function() { + $(this).parents('.form-wrapper').remove(); + }); + if($('#lang-tabs li').length > 1) { + $('#lang-tabs li').append('') + } + $(document).on('click', '#lang-dropdown li a[data-lang]', function() { + var lang = $(this).data('lang'); + var flag = $(this).find('span').first().clone(); + var el = $(this); + $.get('/blog/ajax/category-form', { lang_id: lang }, function(data) { + $('#lang-tabs li').removeClass('active'); + $('#lang-tabs').append('
  • '+$('

    ').append($(flag)).html()+'

  • '); + $('.lang-tab-content .tab-pane.active').removeClass('active'); + $('.lang-tab-content').append($(data).find('.ajax-loaded').first()); + $('body').append($(data).filter('script')); + $(el).parent().remove(); + if(!$('#lang-dropdown li').length) { + $('#dropdownLang').addClass('disabled'); + } + if($('#lang-tabs li').length > 1) { + $('#lang-tabs li').append('') + } + }); + }); + $(document).on('click', '.remove-lang', function() { + var lang = $(this).parent().data('lang'); + var flag = $(this).parent().find('span.flag').first().clone(); + $('#lang-'+lang).remove(); + $('#lang-dropdown').append('
  • '+$('

    ').append($(flag)).html()+'

  • '); + $('#dropdownLang').removeClass('disabled'); + $(this).parent().remove(); + if($('#lang-tabs li').length <= 1) { + $('#lang-tabs li').find('.remove-lang').remove(); + } + if(!$('#lang-tabs>li.active').length) { + $('#lang-tabs>li').first().find('a').tab('show'); + } + }); + $(document).on('change', '.image_inputs_field', function() { + readURL(this); + }); + $('a.remove_image').on('click', function(e) { + var el = $(this); + e.preventDefault(); + if(confirm(confirm_message)) { + $.ajax({ + type: 'post', + url: $(this).attr('href'), + data: $(this).data('params') + }).done(function() { + $(el).parents('.additional_image_container').remove(); + }); + } + return false; + }); +}); \ No newline at end of file diff --git a/common/config/bootstrap.php b/common/config/bootstrap.php index ecc13e5..2533ec2 100644 --- a/common/config/bootstrap.php +++ b/common/config/bootstrap.php @@ -3,3 +3,4 @@ Yii::setAlias('common', dirname(__DIR__)); Yii::setAlias('frontend', dirname(dirname(__DIR__)) . '/frontend'); Yii::setAlias('backend', dirname(dirname(__DIR__)) . '/backend'); Yii::setAlias('console', dirname(dirname(__DIR__)) . '/console'); +Yii::setAlias('saveImageDir', '@frontend/web/images/upload/'); diff --git a/common/config/main.php b/common/config/main.php index bc57e5e..21154a7 100644 --- a/common/config/main.php +++ b/common/config/main.php @@ -8,9 +8,6 @@ return [ 'userClass' => 'common\models\User' ] ], - 'blog' => [ - 'class' => 'common\modules\blog\Module', - ], ], 'components' => [ 'cache' => [ diff --git a/common/modules/blog/behaviors/Autocomplete.php b/common/modules/blog/behaviors/Autocomplete.php new file mode 100644 index 0000000..f326557 --- /dev/null +++ b/common/modules/blog/behaviors/Autocomplete.php @@ -0,0 +1,87 @@ + [[0 => property(свойство обьекта), ... дополнительные + * настройки]], ...[]] + * + */ + public $attributes; + + /** + * События + * + * События на которые должно срабатывать поведение. Задается ассоциативный массив, в котором ключ - событие + * связанного обьекта, а значение - метод, который вызывается при этом событии + * + * @return array [key(event) => val(method)] + * + */ + public function events() + { + return [ + ActiveRecord::EVENT_BEFORE_INSERT => 'autocomplete', + ActiveRecord::EVENT_BEFORE_UPDATE => 'autocomplete', + ]; + } + + /** + * События + * + * События на которые должно срабатывать поведение. Задается ассоциативный массив, в котором ключ - событие + * связанного обьекта, а значение - метод, который вызывается при этом событии + * Доступные автозаполнения: + * ['translit' => ['prop1', ... 'prop2']], + * где prop - свойство подлежащее транслитерации + * ['repeat' => [[string 'prop1', string 'target1', boolean 'skipFilled', int 'count', boolean 'truncate', string 'suffix'], ...[]], + * где prop - свойство для преобразования, + * target - свойство с которого взять данные, + * count - число для преобразования, + * skipFilled - пропустить непустые, + * truncate - true - обрезать по словам, false - по символам, + * suffix - суффикс, который добавить после обрезки + * + * @param mixed $event Yii обьект свойста https://github.com/yiisoft/yii2/blob/master/docs/guide-ru/concept-events.md + * + */ + public function autocomplete($event) + { + if(!empty($this->attributes['translit'])) { + foreach($this->attributes['translit'] as $translit) { + if($this->owner->hasAttribute($translit)) { + $this->owner->$translit = Tools::translit($this->owner->$translit); + } + } + } + if(!empty($this->attributes['repeat'])) { + foreach($this->attributes['repeat'] as $repeat) { + if(is_array($repeat) && $this->owner->hasAttribute($repeat[0]) && $this->owner->hasAttribute($repeat[1]) && is_int($repeat[3]) && (empty($this->owner->$repeat[0]) || $repeat[2])) { + $suffix = $repeat[5]?:''; + $truncate = $repeat[4]?'truncateWords':'truncate'; + $this->owner->$repeat[0] = StringHelper::$truncate($this->owner->$repeat[1], $repeat[3], $suffix); + } + } + } + } +} \ No newline at end of file diff --git a/common/modules/blog/controllers/AjaxController.php b/common/modules/blog/controllers/AjaxController.php index 939af21..5322aac 100644 --- a/common/modules/blog/controllers/AjaxController.php +++ b/common/modules/blog/controllers/AjaxController.php @@ -2,19 +2,81 @@ namespace common\modules\blog\controllers; use common\models\Language; +use common\modules\blog\models\ArticleCategory; use common\modules\blog\models\ArticleCategoryLang; +use common\modules\blog\models\ArticleCategoryMedia; +use common\modules\blog\models\ArticleLang; +use common\modules\blog\models\ArticleMedia; use yii\web\Controller; +use yii\web\ForbiddenHttpException; use yii\web\NotFoundHttpException; class AjaxController extends Controller { + public function beforeAction($action) + { + if(!\Yii::$app->request->getIsAjax()) { + //throw new ForbiddenHttpException('Permission denied'); + } + + if(!parent::beforeAction($action)) { + return false; + } + + return true; + } + public function actionCategoryForm($lang_id) { - $model = Language::findOne($lang_id); + $model = Language::find()->where(['>=', 'language_id', 1])->andWhere(['active' => 1, 'language_id' => $lang_id])->one(); if(!$model) { throw new NotFoundHttpException('Language not found'); } $category_lang = new ArticleCategoryLang(); - return $this->renderPartial('_category_form', ['model' => $model, 'category_lang' => $category_lang]); + return $this->renderAjax('_category_form', ['model' => $model, 'category_lang' => $category_lang]); + } + + public function actionArticleForm($lang_id) + { + $model = Language::find()->where(['>=', 'language_id', 1])->andWhere(['active' => 1, 'language_id' => $lang_id])->one(); + if(!$model) { + throw new NotFoundHttpException('Language not found'); + } + $article_lang = new ArticleLang(); + return $this->renderAjax('_article_form', ['model' => $model, 'article_lang' => $article_lang]); + } + + public function actionRemoveImage() + { + $post = \Yii::$app->request->post(); + if(!empty($post['article_media_id'])) { + $article_media = ArticleMedia::findOne($post['article_media_id']); + if($post['remove_media']) { + $media = $article_media->media->delete(); + } + if(!empty($article_media)) { + $article_media->delete(); + } + return true; + } else { + return false; + } + } + + public function actionRemoveImageCategory() + { + $post = \Yii::$app->request->post(); + if(!empty($post['category_media_id'])) { + $category_media = ArticleCategoryMedia::findOne($post['category_media_id']); + if($post['remove_media']) { + $media = $category_media->media->delete(); + } + if(!empty($category_media)) { + $category_media->delete(); + } + return true; + } else { + return false; + } } } diff --git a/common/modules/blog/controllers/ArticleController.php b/common/modules/blog/controllers/ArticleController.php index 7a230ad..445070e 100644 --- a/common/modules/blog/controllers/ArticleController.php +++ b/common/modules/blog/controllers/ArticleController.php @@ -1,12 +1,18 @@ render('create'); + $article_langs = array(); + $article = new Article(); + $images = array(); + $images['full'] = new ArticleMedia(['scenario' => ArticleMedia::SCENARIO_FULL]); + $images['preview'] = new ArticleMedia(['scenario' => ArticleMedia::SCENARIO_PREVIEW]); + $images['additional'] = new ArticleMedia(['scenario' => ArticleMedia::SCENARIO_ADDITIONAL]); + $article->loadDefaultValues(); + $langs = Language::getActiveLanguages(); + $default_lang = Language::getDefaultLang(); + $isValid = false; + if(!empty(\Yii::$app->request->post())) { + $isValid = true; + $article->load(\Yii::$app->request->post()); + $article->author = \Yii::$app->user->getId(); + $isValid = $article->validate(); + foreach($images as $index => $value) { + $images[$index]->type = $index; + if($index == 'additional') { + $images[$index]->imageFile = UploadedFile::getInstances($images[$index], "[{$index}]imageFile"); + } else { + $images[$index]->imageFile = UploadedFile::getInstance($images[$index], "[{$index}]imageFile"); + } + $isValid = $images[$index]->validate(['imageFile']) && $isValid; + } + if(empty(\Yii::$app->request->post()['ArticleLang'])) { + $article_langs[$default_lang->language_id] = new ArticleLang(); + $isValid = ArticleLang::validateMultiple($article_langs) && $isValid; + } else { + foreach(\Yii::$app->request->post()['ArticleLang'] as $index => $article_lang) { + $article_langs[$index] = new ArticleLang(); + } + ArticleLang::loadMultiple($article_langs, \Yii::$app->request->post()); + $isValid = ArticleLang::validateMultiple($article_langs) && $isValid; + } + } else { + $article_langs[$default_lang->language_id] = new ArticleLang(); + } + if($isValid) { + $article->save(false); + $article_categories = \Yii::$app->request->post('Article')['articleCategoriesArray']; + if(!empty($article_categories)) { + foreach($article_categories as $article_category) { + $articletocategory[$article_category] = new ArticleToCategory(); + $articletocategory[$article_category]->category_id = $article_category; + $articletocategory[$article_category]->link('article', $article); + } + } + $first = 1; + foreach($images as $index => $image) { + $images[$index]->upload($article->id); + } + foreach($article_langs as $article_lang) { + if($first) { + $article_lang_clone = clone $article_lang; + $article_lang_clone->lang_id = 0; + $article_lang_clone->link('article', $article); + unset($article_lang_clone); + } + $article_lang->link('article', $article); + $first = 0; + } + echo "ok"; + //$this->redirect('index'); + } else { + return $this->render('create', [ + 'article_langs' => $article_langs, + 'article' => $article, + 'langs' => $langs, + 'images' => $images + ]); + } + } + + public function actionUpdate($id) + { + $article = Article::findOne($id); + $images = $article->getArticleMedia()->indexBy('type')->all(); + if(!array_key_exists('full', $images)) { + $images['full'] = new ArticleMedia(); + } + if(!array_key_exists('preview', $images)) { + $images['preview'] = new ArticleMedia(); + } + foreach($images as $index => $image) { + $images[$index]->scenario = $index; + } + $images['additional'] = array( + 0 => new ArticleMedia(['scenario' => ArticleMedia::SCENARIO_ADDITIONAL]) + ); + $images['additional'] = array_merge($images['additional'], $article->getArticleMedia()->andWhere(['type' => 'additional'])->indexBy('id')->all()); + foreach($images['additional'] as $index => $image) { + $images['additional'][$index]->scenario = 'additional'; + } + $article_langs = $article->getArticleLangs()->where(['>=', 'lang_id', '1'])->indexBy('lang_id')->all(); + $langs = Language::getActiveLanguages(); + $default_lang = Language::getDefaultLang(); + $isValid = false; + if(!empty(\Yii::$app->request->post())) { + $isValid = true; + $article->load(\Yii::$app->request->post()); + ArticleToCategory::deleteAll(['article_id' => $article->id]); + $article_categories = \Yii::$app->request->post('Article')['articleCategoriesArray']; + if(!empty($article_categories)) { + foreach($article_categories as $article_category) { + $articletocategory[$article_category] = new ArticleToCategory(); + $articletocategory[$article_category]->category_id = $article_category; + $articletocategory[$article_category]->link('article', $article); + } + } + $isValid = $article->validate(); + foreach($images as $index => $value) { + if($index == 'additional') { + $images[$index][0]->type = $index; + $images[$index][0]->imageFile = UploadedFile::getInstances($images[$index][0], "[{$index}]imageFile"); + $isValid = $images[$index][0]->validate(['imageFile']) && $isValid; + } else { + $images[$index]->type = $index; + $images[$index]->imageFile = UploadedFile::getInstance($images[$index], "[{$index}]imageFile"); + $isValid = $images[$index]->validate(['imageFile']) && $isValid; + } + } + if(empty(\Yii::$app->request->post()['ArticleLang'])) { + $isValid = ArticleLang::validateMultiple($article_langs) && $isValid; + } else { + foreach(\Yii::$app->request->post()['ArticleLang'] as $index => $article_lang) { + if (!array_key_exists($index, $article_langs)) { + $article_langs[$index] = new ArticleLang(); + $article_langs[$index]->article_id = $article->id; + } + } + ArticleLang::loadMultiple($article_langs, \Yii::$app->request->post()); + $isValid = ArticleLang::validateMultiple($article_langs) && $isValid; + } + } + if($isValid) { + $article->save(false); + foreach($images as $index => $image) { + if($index == 'additional') { + $images[$index][0]->upload($article->id); + } else { + if(!empty($images[$index]->imageFile)) { + $images[$index]->replace($article->id, true); + } + } + } + foreach($article_langs as $article_lang) { + $article_lang->save(false); + } + echo "ok"; + //$this->redirect('index'); + } else { + return $this->render('update', [ + 'article_langs' => $article_langs, + 'article' => $article, + 'langs' => $langs, + 'images' => $images + ]); + } + } + + public function actionDelete($id) + { + $this->findModel($id)->delete(); + return $this->redirect(['index']); + } + + protected function findModel($id) + { + if (($model = Article::findOne($id)) !== null) { + return $model; + } else { + throw new NotFoundHttpException('The requested page does not exist.'); + } } } diff --git a/common/modules/blog/controllers/CategoryController.php b/common/modules/blog/controllers/CategoryController.php index 6c8d601..d4edd82 100644 --- a/common/modules/blog/controllers/CategoryController.php +++ b/common/modules/blog/controllers/CategoryController.php @@ -5,12 +5,28 @@ use common\models\Language; use common\modules\blog\models\Article; use common\modules\blog\models\ArticleCategory; use common\modules\blog\models\ArticleCategoryLang; +use common\modules\blog\models\ArticleCategoryMedia; use common\modules\blog\models\ArticleLang; use yii\data\ActiveDataProvider; +use yii\filters\VerbFilter; use yii\web\Controller; +use yii\web\NotFoundHttpException; +use yii\web\UploadedFile; class CategoryController extends Controller { + public function behaviors() + { + return [ + 'verbs' => [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['post'] + ] + ] + ]; + } + public function actionIndex() { $dataProvider = new ActiveDataProvider([ @@ -26,9 +42,23 @@ class CategoryController extends Controller { $category_langs = array(); $category = new ArticleCategory(); + $images = array(); + $images['full'] = new ArticleCategoryMedia(['scenario' => ArticleCategoryMedia::SCENARIO_FULL]); + $images['preview'] = new ArticleCategoryMedia(['scenario' => ArticleCategoryMedia::SCENARIO_PREVIEW]); + $images['additional'] = new ArticleCategoryMedia(['scenario' => ArticleCategoryMedia::SCENARIO_ADDITIONAL]); + $category->loadDefaultValues(); $langs = Language::getActiveLanguages(); $default_lang = Language::getDefaultLang(); $isValid = false; + foreach($images as $index => $value) { + $images[$index]->type = $index; + if($index == 'additional') { + $images[$index]->imageFile = UploadedFile::getInstances($images[$index], "[{$index}]imageFile"); + } else { + $images[$index]->imageFile = UploadedFile::getInstance($images[$index], "[{$index}]imageFile"); + } + $isValid = $images[$index]->validate(['imageFile']) && $isValid; + } if(!empty(\Yii::$app->request->post())) { $isValid = true; $category->load(\Yii::$app->request->post()); @@ -48,16 +78,122 @@ class CategoryController extends Controller } if($isValid) { $category->save(false); + $first = 1; + foreach($images as $index => $image) { + $images[$index]->upload($category->id); + } foreach($category_langs as $category_lang) { + if($first) { + $category_lang_clone = clone $category_lang; + $category_lang_clone->lang_id = 0; + $category_lang_clone->link('category', $category); + unset($category_lang_clone); + } $category_lang->link('category', $category); + $first = 0; } echo "ok"; + //$this->redirect('index'); } else { return $this->render('create', [ 'category_langs' => $category_langs, 'category' => $category, - 'langs' => $langs + 'langs' => $langs, + 'images' => $images ]); } } + + public function actionUpdate($id) + { + $category = ArticleCategory::findOne($id); + $images = $category->getArticleCategoryMedia()->indexBy('type')->all(); + if(!array_key_exists('full', $images)) { + $images['full'] = new ArticleCategoryMedia(); + } + if(!array_key_exists('preview', $images)) { + $images['preview'] = new ArticleCategoryMedia(); + } + foreach($images as $index => $image) { + $images[$index]->scenario = $index; + } + $images['additional'] = array( + 0 => new ArticleCategoryMedia(['scenario' => ArticleCategoryMedia::SCENARIO_ADDITIONAL]) + ); + $images['additional'] = array_merge($images['additional'], $category->getArticleCategoryMedia()->andWhere(['type' => 'additional'])->indexBy('id')->all()); + foreach($images['additional'] as $index => $image) { + $images['additional'][$index]->scenario = 'additional'; + } + $category_langs = $category->getArticleCategoryLangs()->where(['>=', 'lang_id', '1'])->indexBy('lang_id')->all(); + $langs = Language::getActiveLanguages(); + $default_lang = Language::getDefaultLang(); + $isValid = false; + if(!empty(\Yii::$app->request->post())) { + $isValid = true; + $category->load(\Yii::$app->request->post()); + $isValid = $category->validate(); + foreach($images as $index => $value) { + if($index == 'additional') { + $images[$index][0]->type = $index; + $images[$index][0]->imageFile = UploadedFile::getInstances($images[$index][0], "[{$index}]imageFile"); + $isValid = $images[$index][0]->validate(['imageFile']) && $isValid; + } else { + $images[$index]->type = $index; + $images[$index]->imageFile = UploadedFile::getInstance($images[$index], "[{$index}]imageFile"); + $isValid = $images[$index]->validate(['imageFile']) && $isValid; + } + } + if(empty(\Yii::$app->request->post()['ArticleCategoryLang'])) { + $isValid = ArticleCategoryLang::validateMultiple($category_langs) && $isValid; + } else { + foreach(\Yii::$app->request->post()['ArticleCategoryLang'] as $index => $category_lang) { + if(!array_key_exists($index, $category_langs)) { + $category_langs[$index] = new ArticleCategoryLang(); + $category_langs[$index]->category_id = $category->id; + } + } + ArticleCategoryLang::loadMultiple($category_langs, \Yii::$app->request->post()); + $isValid = ArticleCategoryLang::validateMultiple($category_langs) && $isValid; + } + } + if($isValid) { + $category->save(false); + foreach($images as $index => $image) { + if($index == 'additional') { + $images[$index][0]->upload($category->id); + } else { + if(!empty($images[$index]->imageFile)) { + $images[$index]->replace($category->id, true); + } + } + } + foreach($category_langs as $category_lang) { + $category_lang->save(false); + } + echo "ok"; + //$this->redirect('index'); + } else { + return $this->render('update', [ + 'category_langs' => $category_langs, + 'category' => $category, + 'langs' => $langs, + 'images' => $images + ]); + } + } + + public function actionDelete($id) + { + $this->findModel($id)->delete(); + return $this->redirect(['index']); + } + + protected function findModel($id) + { + if (($model = ArticleCategory::findOne($id)) !== null) { + return $model; + } else { + throw new NotFoundHttpException('The requested page does not exist.'); + } + } } diff --git a/common/modules/blog/controllers/MediaController.php b/common/modules/blog/controllers/MediaController.php new file mode 100644 index 0000000..e1d91f5 --- /dev/null +++ b/common/modules/blog/controllers/MediaController.php @@ -0,0 +1,45 @@ +request->isPost) { + $model->imageFile = UploadedFile::getInstance($model, 'imageFile'); + if($model->upload()) { + return true; + } else { + return false; + } + } + return $this->render('index', ['model' => $model]); + } + + public function actionCreate() + { + + } + + public function actionUpdate($id) + { + + } + + public function actionDelete($id) + { + $model = Media::findOne($id); + return $model->delete(); + } + + protected function findModel($id) + { + + } +} diff --git a/common/modules/blog/views/ajax/_article_form.php b/common/modules/blog/views/ajax/_article_form.php new file mode 100644 index 0000000..6d69bc6 --- /dev/null +++ b/common/modules/blog/views/ajax/_article_form.php @@ -0,0 +1,33 @@ + +
    + + $article_lang, 'attribute' => "[$model->language_id]lang_id"]))->label(false)->hiddenInput(['value' => $model->language_id]) ?> + + $article_lang, 'attribute' => "[$model->language_id]text", 'form' => $form]))->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ]]); ?> + + $article_lang, 'attribute' => "[$model->language_id]preview", 'form' => $form]))->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ]]); ?> + + $article_lang, 'attribute' => "[$model->language_id]seo_url"]))->textInput() ?> + + $article_lang, 'attribute' => "[$model->language_id]name"]))->textInput() ?> + + $article_lang, 'attribute' => "[$model->language_id]meta_title"]))->textInput() ?> + + $article_lang, 'attribute' => "[$model->language_id]meta_descr"]))->textarea() ?> + + $article_lang, 'attribute' => "[$model->language_id]meta_keywords"]))->textInput() ?> + + $article_lang, 'attribute' => "[$model->language_id]h1_tag"]))->textInput() ?> + + $article_lang, 'attribute' => "[$model->language_id]tags"]))->textInput() ?> + +
    +end(); +?> diff --git a/common/modules/blog/views/ajax/_category_form.php b/common/modules/blog/views/ajax/_category_form.php index 84f3633..bad2d83 100644 --- a/common/modules/blog/views/ajax/_category_form.php +++ b/common/modules/blog/views/ajax/_category_form.php @@ -1,28 +1,33 @@ -
    +
    - $category_lang, 'attribute' => "[$model->language_id]lang_id"]))->label(false)->hiddenInput(['value' => $model->language_id]) ?> + $category_lang, 'attribute' => "[$model->language_id]lang_id"]))->label(false)->hiddenInput(['value' => $model->language_id]) ?> - $category_lang, 'attribute' => "[$model->language_id]text"]))->textarea() ?> + $category_lang, 'attribute' => "[$model->language_id]text", 'form' => $form]))->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ]]); ?> - $category_lang, 'attribute' => "[$model->language_id]preview"]))->textarea() ?> + $category_lang, 'attribute' => "[$model->language_id]preview", 'form' => $form]))->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ]]); ?> - $category_lang, 'attribute' => "[$model->language_id]seo_url"]))->textInput() ?> + $category_lang, 'attribute' => "[$model->language_id]seo_url"]))->textInput() ?> - $category_lang, 'attribute' => "[$model->language_id]name"]))->textInput() ?> + $category_lang, 'attribute' => "[$model->language_id]name"]))->textInput() ?> - $category_lang, 'attribute' => "[$model->language_id]meta_title"]))->textInput() ?> + $category_lang, 'attribute' => "[$model->language_id]meta_title"]))->textInput() ?> - $category_lang, 'attribute' => "[$model->language_id]meta_descr"]))->textarea() ?> + $category_lang, 'attribute' => "[$model->language_id]meta_descr"]))->textarea() ?> - $category_lang, 'attribute' => "[$model->language_id]meta_keywords"]))->textInput() ?> + $category_lang, 'attribute' => "[$model->language_id]meta_keywords"]))->textInput() ?> - $category_lang, 'attribute' => "[$model->language_id]h1_tag"]))->textInput() ?> + $category_lang, 'attribute' => "[$model->language_id]h1_tag"]))->textInput() ?> - $category_lang, 'attribute' => "[$model->language_id]tags"]))->textInput() ?> + $category_lang, 'attribute' => "[$model->language_id]tags"]))->textInput() ?>
    +end(); +?> diff --git a/common/modules/blog/views/article/_form.php b/common/modules/blog/views/article/_form.php new file mode 100644 index 0000000..eb236e1 --- /dev/null +++ b/common/modules/blog/views/article/_form.php @@ -0,0 +1,149 @@ + +
    + + ['enctype' => 'multipart/form-data']]); ?> + + field($article, 'code')->hint(Yii::t('app', 'Insensitive latin non-space'))->textInput() ?> + + field($article, 'tags')->hint(Yii::t('app', 'Comma-separated'))->textInput() ?> + + field($article, 'sort')->input('number') ?> + + field($article, 'parent_id') + ->dropDownList(Article::findArticleDropdown($article->id), ['prompt' => Yii::t('app', 'Select parent')]) ?> + + field($article, 'articleCategoriesArray') + ->dropDownList(ArticleCategory::findArticleCategoryDropdown(NULL), ['multiple' => 'multiple'])->label(\Yii::t('app', 'Article Categories Array')); ?> + + field($article, 'active')->checkbox() ?> + + +
    + $image) { + ?> +
    + field(is_array($image)?$images[$index][0]:$images[$index], "[{$index}]imageFile[]")->fileInput(['multiple' => 'multiple', 'class' => 'image_inputs_field']); + if(is_array($image) && count($image) > 1) { + foreach($image as $oneindex => $oneimage) { + if($oneindex) { + ?> + + field($images[$index], "[{$index}]imageFile")->fileInput(['class' => 'image_inputs_field']); + if(!empty($image->id)) { + echo ""; + } + } + ?> +
    + +
    + +
    + + + +
    + $article_lang) { + ?> +
    + field($article_langs[$index], "[$index]lang_id")->label(false)->hiddenInput(['value' => $index]) ?> + + field($article_langs[$index], "[$index]text")->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ], ]); ?> + + field($article_langs[$index], "[$index]preview")->widget(CKEditor::className(),['editorOptions' => [ 'preset' => 'full', 'inline' => false, ], ]); ?> + + field($article_langs[$index], "[$index]seo_url")->textInput() ?> + + field($article_langs[$index], "[$index]name")->textInput() ?> + + field($article_langs[$index], "[$index]meta_title")->textInput() ?> + + field($article_langs[$index], "[$index]meta_descr")->textarea(); ?> + + field($article_langs[$index], "[$index]meta_keywords")->textInput() ?> + + field($article_langs[$index], "[$index]h1_tag")->textInput() ?> + + field($article_langs[$index], "[$index]tags")->textInput() ?> + +
    + +
    + +
    + isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $article->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> +
    + + + +
    + \ No newline at end of file diff --git a/common/modules/blog/views/article/create.php b/common/modules/blog/views/article/create.php index b3d9bbc..6cd9da6 100644 --- a/common/modules/blog/views/article/create.php +++ b/common/modules/blog/views/article/create.php @@ -1 +1,19 @@ title = Yii::t('app', 'Article create'); +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Articles'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
    + +

    title) ?>

    + + render('_form', [ + 'article_langs' => $article_langs, + 'article' => $article, + 'langs' => $langs, + 'images' => $images + ]) ?> + +
    diff --git a/common/modules/blog/views/article/index.php b/common/modules/blog/views/article/index.php index 16908ba..f56a765 100644 --- a/common/modules/blog/views/article/index.php +++ b/common/modules/blog/views/article/index.php @@ -1,7 +1,32 @@ $dataProvider, + 'columns' => [ + 'id', + 'code', + 'create_at', + [ + 'value' => function($data) { + return $data->author0->firstname.' '.$data->author0->lastname; + }, + 'header' => Yii::t('app', 'Author') + ], + [ + 'class' => Column::className(), + 'header' => Yii::t('app', 'Name'), + 'content' => function($model, $key, $index, $column) { + return $model->getArticleLangs()->where(['lang_id' => Language::getDefaultLang()->language_id])->one()->name; + } + ], + [ + 'class' => ActionColumn::className(), + 'template' => '{update} {delete}' + ] + ] ]); \ No newline at end of file diff --git a/common/modules/blog/views/article/update.php b/common/modules/blog/views/article/update.php new file mode 100644 index 0000000..4458a2b --- /dev/null +++ b/common/modules/blog/views/article/update.php @@ -0,0 +1,18 @@ +title = Yii::t('app', 'Article update'); +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Articles'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
    + +

    title) ?>

    + render('_form', [ + 'article_langs' => $article_langs, + 'article' => $article, + 'langs' => $langs, + 'images' => $images + ]) ?> + +
    diff --git a/common/modules/blog/views/category/_form.php b/common/modules/blog/views/category/_form.php index 6652828..4e1e615 100644 --- a/common/modules/blog/views/category/_form.php +++ b/common/modules/blog/views/category/_form.php @@ -2,23 +2,79 @@ use yii\bootstrap\ActiveForm; use common\modules\blog\models\ArticleCategory; use yii\bootstrap\Html; +use mihaildev\ckeditor\CKEditor; +use yii\helpers\Json; +use yii\helpers\Url; $def_lang = array_keys($langs)[0]; - +$uploaddir = \Yii::getAlias('@saveImageDir'); ?>
    - + ['enctype' => 'multipart/form-data']]); ?> field($category, 'code')->hint(Yii::t('app', 'Insensitive latin non-space'))->textInput() ?> field($category, 'tags')->hint(Yii::t('app', 'Comma-separated'))->textInput() ?> + field($category, 'sort')->input('number') ?> + field($category, 'parent_id') - ->dropDownList(ArticleCategory::findArticleCategoryDropdown(), ['prompt' => Yii::t('app', 'Select parent')]) ?> + ->dropDownList(ArticleCategory::findArticleCategoryDropdown($category->id), ['prompt' => Yii::t('app', 'Select parent')]) ?> field($category, 'active')->checkbox() ?> + +
    + $image) { + ?> +
    + field(is_array($image)?$images[$index][0]:$images[$index], "[{$index}]imageFile[]")->fileInput(['multiple' => 'multiple', 'class' => 'image_inputs_field']); + if(is_array($image) && count($image) > 1) { + foreach($image as $oneindex => $oneimage) { + if($oneindex) { + ?> + + field($images[$index], "[{$index}]imageFile")->fileInput(['class' => 'image_inputs_field']); + if(!empty($image->id)) { + echo ""; + } + } + ?> +
    + +
    + +
    +