diff --git a/assets/css/main.css b/assets/css/main.css index 75d163d..00ffaf9 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -70,33 +70,33 @@ .i18ncontent-table-wrapper td.i18n-language-translations .label { margin-right: 5px; } -.togglebutton { +.i18ncontent-table-wrapper .togglebutton { vertical-align: middle; } -.togglebutton, -.togglebutton label, -.togglebutton input, -.togglebutton .toggle { +.i18ncontent-table-wrapper .togglebutton, +.i18ncontent-table-wrapper .togglebutton label, +.i18ncontent-table-wrapper .togglebutton input, +.i18ncontent-table-wrapper .togglebutton .toggle { user-select: none; } -.togglebutton label { +.i18ncontent-table-wrapper .togglebutton label { cursor: pointer; color: rgba(0, 0, 0, 0.26); } -.togglebutton label:focus { +.i18ncontent-table-wrapper .togglebutton label:focus { outline: 0; } -.togglebutton label input[type=checkbox] { +.i18ncontent-table-wrapper .togglebutton label input[type=checkbox] { opacity: 0; width: 0; height: 0; display: none; } -.togglebutton label .toggle { +.i18ncontent-table-wrapper .togglebutton label .toggle { text-align: left; } -.togglebutton label .toggle, -.togglebutton label input[type=checkbox][disabled] + .toggle { +.i18ncontent-table-wrapper .togglebutton label .toggle, +.i18ncontent-table-wrapper .togglebutton label input[type=checkbox][disabled] + .toggle { content: ""; display: inline-block; width: 30px; @@ -107,7 +107,7 @@ transition: background 0.3s ease; vertical-align: middle; } -.togglebutton label .toggle:after { +.i18ncontent-table-wrapper .togglebutton label .toggle:after { content: ""; display: inline-block; width: 20px; @@ -120,23 +120,211 @@ top: -2px; transition: left 0.3s ease, background 0.3s ease, box-shadow 0.1s ease; } -.togglebutton label input[type=checkbox][disabled] + .toggle:after, -.togglebutton label input[type=checkbox][disabled]:checked + .toggle:after { +.i18ncontent-table-wrapper .togglebutton label input[type=checkbox][disabled] + .toggle:after, +.i18ncontent-table-wrapper .togglebutton label input[type=checkbox][disabled]:checked + .toggle:after { background-color: #BDBDBD; } -.togglebutton label input[type=checkbox] + .toggle:active:after, -.togglebutton label input[type=checkbox][disabled] + .toggle:active:after { +.i18ncontent-table-wrapper .togglebutton label input[type=checkbox] + .toggle:active:after, +.i18ncontent-table-wrapper .togglebutton label input[type=checkbox][disabled] + .toggle:active:after { box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(0, 0, 0, 0.1); } -.togglebutton label input[type=checkbox]:checked + .toggle:after { +.i18ncontent-table-wrapper .togglebutton label input[type=checkbox]:checked + .toggle:after { left: 15px; } -.togglebutton label input[type=checkbox]:checked + .toggle { +.i18ncontent-table-wrapper .togglebutton label input[type=checkbox]:checked + .toggle { background-color: rgba(60, 141, 188, 0.5); } -.togglebutton label input[type=checkbox]:checked + .toggle:after { +.i18ncontent-table-wrapper .togglebutton label input[type=checkbox]:checked + .toggle:after { background-color: #3c8dbc; } -.togglebutton label input[type=checkbox]:checked + .toggle:active:after { +.i18ncontent-table-wrapper .togglebutton label input[type=checkbox]:checked + .toggle:active:after { box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.4), 0 0 0 15px rgba(60, 141, 188, 0.1); } +.i18ncontent-table-wrapper .om-checkbox label, +.i18ncontent-form .om-checkbox label { + font-size: 16px; + line-height: 1.42857143; + font-weight: 400; +} +.i18ncontent-table-wrapper .om-checkbox input[type=checkbox], +.i18ncontent-form .om-checkbox input[type=checkbox] { + opacity: 0; + position: absolute; + margin: 0; + z-index: -1; + width: 0; + height: 0; + overflow: hidden; + left: 0; + pointer-events: none; +} +.i18ncontent-table-wrapper .om-checkbox .om-checkbox-material, +.i18ncontent-form .om-checkbox .om-checkbox-material { + vertical-align: middle; + position: relative; + top: 3px; +} +.i18ncontent-table-wrapper .om-checkbox .om-checkbox-material .check, +.i18ncontent-form .om-checkbox .om-checkbox-material .check { + position: relative; + display: inline-block; + width: 20px; + height: 20px; + border: 2px solid rgba(0, 0, 0, 0.54); + border-radius: 2px; + overflow: hidden; + z-index: 1; +} +.i18ncontent-table-wrapper .om-checkbox .om-checkbox-material .check:before, +.i18ncontent-form .om-checkbox .om-checkbox-material .check:before { + position: absolute; + content: ""; + transform: rotate(45deg); + -webkit-transform: rotate(45deg); + display: block; + margin-top: -4px; + margin-left: 6px; + width: 0; + height: 0; + animation: checkbox-off; + -webkit-animation: checkbox-off; +} +.i18ncontent-table-wrapper .om-checkbox .om-checkbox-material:before, +.i18ncontent-form .om-checkbox .om-checkbox-material:before { + display: block; + position: absolute; + left: 0; + content: ""; + background-color: rgba(0, 0, 0, 0.84); + height: 20px; + width: 20px; + border-radius: 100%; + z-index: 1; + opacity: 0; + margin: 0; + transform: scale3d(2.3, 2.3, 1); + -webkit-transform: scale3d(2.3, 2.3, 1); +} +.i18ncontent-table-wrapper .om-checkbox input[type=checkbox]:checked + .om-checkbox-material .check:before, +.i18ncontent-form .om-checkbox input[type=checkbox]:checked + .om-checkbox-material .check:before { + color: #009688; + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px; + animation: checkbox-on 0.3s forwards; + -webkit-animation: checkbox-on 0.3s forwards; +} +@keyframes checkbox-on { + 0% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 15px 2px 0 11px; + } + 50% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px 2px 0 11px; + } + 100% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px; + } +} +@-webkit-keyframes checkbox-on { + 0% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 15px 2px 0 11px; + } + 50% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px 2px 0 11px; + } + 100% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px; + } +} +@keyframes checkbox-off { + 0% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px, 0 0 0 0 inset; + } + 25% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px, 0 0 0 0 inset; + } + 50% { + transform: rotate(45deg); + -webkit-transform: rotate(45deg); + margin-top: -4px; + margin-left: 6px; + width: 0; + height: 0; + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 15px 2px 0 11px, 0 0 0 0 inset; + } + 51% { + transform: rotate(0deg); + -webkit-transform: rotate(0deg); + margin-top: -2px; + margin-left: -2px; + width: 20px; + height: 20px; + box-shadow: 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0px 0 0 10px inset; + } + 100% { + transform: rotate(0deg); + -webkit-transform: rotate(0deg); + margin-top: -2px; + margin-left: -2px; + width: 20px; + height: 20px; + box-shadow: 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0px 0 0 0 inset; + } +} +@-webkit-keyframes checkbox-off { + 0% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px, 0 0 0 0 inset; + } + 25% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px, 0 0 0 0 inset; + } + 50% { + transform: rotate(45deg); + -webkit-transform: rotate(45deg); + margin-top: -4px; + margin-left: 6px; + width: 0; + height: 0; + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 15px 2px 0 11px, 0 0 0 0 inset; + } + 51% { + transform: rotate(0deg); + -webkit-transform: rotate(0deg); + margin-top: -2px; + margin-left: -2px; + width: 20px; + height: 20px; + box-shadow: 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0px 0 0 10px inset; + } + 100% { + transform: rotate(0deg); + -webkit-transform: rotate(0deg); + margin-top: -2px; + margin-left: -2px; + width: 20px; + height: 20px; + box-shadow: 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0px 0 0 0 inset; + } +} diff --git a/assets/js/i18nContent.js b/assets/js/i18nContent.js index 85505ed..4b96b08 100644 --- a/assets/js/i18nContent.js +++ b/assets/js/i18nContent.js @@ -4,7 +4,8 @@ (function ($) { var I18nContent = function () { this.$toggleBtn = $('.togglebutton > label > input'); - + this.$greedView = $('.grid-view'); + this.$multipleDeleteButton = $('.delete-multiple'); this.init(); }; @@ -13,6 +14,7 @@ init: function () { this.toggleStatus(); + this.onDeleteCheckedItems(); }, @@ -33,6 +35,29 @@ }, + onDeleteCheckedItems: function () { + var me = this; + me.$multipleDeleteButton.on('click', function (e) { + e.preventDefault(); + var $itemIds, conf, deleteUrl; + $itemIds = me.$greedView.yiiGridView('getSelectedRows'); + if($itemIds.length < 1){ + return; + } + conf = confirm('Are you sure you want to delete this/these item(s)?'); + if(conf !== true) return; + + deleteUrl = $(this).data('url') || 'delete'; + me._post(deleteUrl, {id: $itemIds}).done(function (res) { + if(res.errorMsg){ + alert(res.errorMsg); + } + //console.log(res); + }); + }); + }, + + _get: function (url, data) { return $.ajax({ url: url, @@ -42,6 +67,7 @@ }); }, + _post: function (url, data) { return $.ajax({ url: url, diff --git a/assets/less/checkbox.less b/assets/less/checkbox.less new file mode 100644 index 0000000..6fa86e8 --- /dev/null +++ b/assets/less/checkbox.less @@ -0,0 +1,189 @@ +.i18ncontent-table-wrapper , .i18ncontent-form{ + .om-checkbox label{ + font-size: 16px; + line-height: 1.42857143; + //color: #BDBDBD; + font-weight: 400; + } + + .om-checkbox { + input[type=checkbox] { + opacity: 0; + position: absolute; + margin: 0; + z-index: -1; + width: 0; + height: 0; + overflow: hidden; + left: 0; + pointer-events: none; + } + .om-checkbox-material { + vertical-align: middle; + position: relative; + top: 3px; + .check { + position: relative; + display: inline-block; + width: 20px; + height: 20px; + border: 2px solid rgba(0, 0, 0, .54); + border-radius: 2px; + overflow: hidden; + z-index: 1; + &:before { + position: absolute; + content: ""; + transform: rotate(45deg); + -webkit-transform: rotate(45deg); + display: block; + margin-top: -4px; + margin-left: 6px; + width: 0; + height: 0; + animation: checkbox-off; + -webkit-animation: checkbox-off; + } + } + &:before { + display: block; + position: absolute; + left: 0; + content: ""; + background-color: rgba(0, 0, 0, 0.84); + height: 20px; + width: 20px; + border-radius: 100%; + z-index: 1; + opacity: 0; + margin: 0; + transform: scale3d(2.3, 2.3, 1); + -webkit-transform: scale3d(2.3, 2.3, 1); + } + } + } + .om-checkbox input[type=checkbox]:checked + .om-checkbox-material .check:before { + color: #009688; + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px; + animation: checkbox-on 0.3s forwards; + -webkit-animation: checkbox-on 0.3s forwards; + } + + //animation + @keyframes checkbox-on { + 0% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 15px 2px 0 11px; + } + 50% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px 2px 0 11px; + } + 100% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px; + } + } + @-webkit-keyframes checkbox-on { + 0% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 15px 2px 0 11px; + } + 50% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px 2px 0 11px; + } + 100% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px; + } + } + @keyframes checkbox-off { + 0% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px, 0 0 0 0 inset; + } + 25% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px, 0 0 0 0 inset; + } + 50% { + transform: rotate(45deg); + -webkit-transform: rotate(45deg); + margin-top: -4px; + margin-left: 6px; + width: 0; + height: 0; + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 15px 2px 0 11px, 0 0 0 0 inset; + } + 51% { + transform: rotate(0deg); + -webkit-transform: rotate(0deg); + margin-top: -2px; + margin-left: -2px; + width: 20px; + height: 20px; + box-shadow: 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0px 0 0 10px inset; + } + 100% { + transform: rotate(0deg); + -webkit-transform: rotate(0deg); + margin-top: -2px; + margin-left: -2px; + width: 20px; + height: 20px; + box-shadow: 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0px 0 0 0 inset; + } + } + @-webkit-keyframes checkbox-off { + 0% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px, 0 0 0 0 inset; + } + 25% { + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 20px -12px 0 11px, 0 0 0 0 inset; + } + 50% { + transform: rotate(45deg); + -webkit-transform: rotate(45deg); + margin-top: -4px; + margin-left: 6px; + width: 0; + height: 0; + box-shadow: 0 0 0 10px, 10px -10px 0 10px, 32px 0 0 20px, 0px 32px 0 20px, -5px 5px 0 10px, 15px 2px 0 11px, 0 0 0 0 inset; + } + 51% { + transform: rotate(0deg); + -webkit-transform: rotate(0deg); + margin-top: -2px; + margin-left: -2px; + width: 20px; + height: 20px; + box-shadow: 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0px 0 0 10px inset; + } + 100% { + transform: rotate(0deg); + -webkit-transform: rotate(0deg); + margin-top: -2px; + margin-left: -2px; + width: 20px; + height: 20px; + box-shadow: 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0 0 0 0, + 0px 0 0 0 inset; + } + } +} \ No newline at end of file diff --git a/assets/less/main.less b/assets/less/main.less index 2d0041d..0cd30cd 100644 --- a/assets/less/main.less +++ b/assets/less/main.less @@ -2,4 +2,5 @@ @import "helpers"; @import "tabs"; @import "table"; -@import "_togglebutton"; +@import "togglebutton"; +@import "checkbox"; diff --git a/assets/less/_togglebutton.less b/assets/less/togglebutton.less similarity index 97% rename from assets/less/_togglebutton.less rename to assets/less/togglebutton.less index 82429b3..77e8a26 100644 --- a/assets/less/_togglebutton.less +++ b/assets/less/togglebutton.less @@ -1,4 +1,4 @@ -.togglebutton { +.i18ncontent-table-wrapper .togglebutton { vertical-align: middle; &, label, input, .toggle { user-select: none; diff --git a/controllers/ArticleCategoryController.php b/controllers/ArticleCategoryController.php index d1253dc..23aa500 100644 --- a/controllers/ArticleCategoryController.php +++ b/controllers/ArticleCategoryController.php @@ -7,6 +7,7 @@ use centigen\i18ncontent\models\search\ArticleCategorySearch; use centigen\i18ncontent\web\Controller; use Yii; +use yii\helpers\Json; use yii\helpers\Url; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; @@ -118,17 +119,35 @@ public function actionUpdate($id) /** * Deletes an existing ArticleCategory model. * If deletion is successful, the browser will be redirected to the 'index' page. - * @param integer $id + * @param integer|null $id * @return mixed */ - public function actionDelete($id) + public function actionDelete($id = null) { - $model = $this->findModel($id); - if(count($model->articleCategoryArticles) > 0){ - $msg = Yii::t('i18ncontent', 'This category has articles. In order to delete this category, first you must delete all articles in this category {link}', ['link' => ''.Yii::t('i18ncontent', 'View them').'']); - return $this->renderContent($msg); + $id = $id ?: Yii::$app->request->post('id'); + if (is_array($id)) { + $categoryWithChildren = []; + foreach ($id as $item) { + $model = $this->findModel($item); + if (count($model->articleCategoryArticles) > 0) { + $categoryWithChildren[] = $model->activeTranslation->title; + continue; + } + $model->delete(); + } + if(count($categoryWithChildren)){ + $msg = Yii::t('i18ncontent', 'This categories has articles. In order to delete this categories, first you must delete all articles in this categories').': '. join(', ', $categoryWithChildren); + return Json::encode(['errorMsg' => $msg, 'success' => false]); + } + return $this->redirect(['index']); + } else { + $model = $this->findModel($id); + if (count($model->articleCategoryArticles) > 0) { + $msg = Yii::t('i18ncontent', 'This category has articles. In order to delete this category, first you must delete all articles in this category {link}', ['link' => '' . Yii::t('i18ncontent', 'View them') . '']); + return $this->renderContent($msg); + } + $model->delete(); } - $model->delete(); return $this->redirect(['index']); } diff --git a/controllers/ArticleController.php b/controllers/ArticleController.php index 3bb401d..6bebbbe 100644 --- a/controllers/ArticleController.php +++ b/controllers/ArticleController.php @@ -121,12 +121,13 @@ public function actionUpdate($id) /** * Deletes an existing Article model. * If deletion is successful, the browser will be redirected to the 'index' page. - * @param integer $id + * @param integer|array $id * @return mixed */ - public function actionDelete($id) + public function actionDelete($id = null) { - $this->findModel($id)->delete(); + $id = $id ?: Yii::$app->request->post('id'); + Article::deleteAll(['id' => $id]); return $this->redirect(['index']); } diff --git a/controllers/PageController.php b/controllers/PageController.php index 1ab52a2..6dd5722 100644 --- a/controllers/PageController.php +++ b/controllers/PageController.php @@ -115,12 +115,13 @@ public function actionUpdate($id) /** * Deletes an existing Page model. * If deletion is successful, the browser will be redirected to the 'index' page. - * @param integer $id + * @param integer|null $id * @return mixed */ - public function actionDelete($id) + public function actionDelete($id = null) { - $this->findModel($id)->delete(); + $id = $id ?: Yii::$app->request->post('id'); + Page::deleteAll(['id' => $id]); return $this->redirect(['index']); } diff --git a/controllers/WidgetCarouselController.php b/controllers/WidgetCarouselController.php index 6a024f4..4312e88 100644 --- a/controllers/WidgetCarouselController.php +++ b/controllers/WidgetCarouselController.php @@ -104,12 +104,13 @@ public function actionUpdate($id) /** * Deletes an existing WidgetCarousel model. * If deletion is successful, the browser will be redirected to the 'index' page. - * @param integer $id + * @param integer|null $id * @return mixed */ - public function actionDelete($id) + public function actionDelete($id = null) { - $this->findModel($id)->delete(); + $id = $id ?: Yii::$app->request->post('id'); + WidgetCarousel::deleteAll(['id' => $id]); return $this->redirect(['index']); } diff --git a/controllers/WidgetCarouselItemController.php b/controllers/WidgetCarouselItemController.php index f8c2d17..8f27db9 100644 --- a/controllers/WidgetCarouselItemController.php +++ b/controllers/WidgetCarouselItemController.php @@ -117,16 +117,16 @@ public function actionUpdate($id) /** * Deletes an existing WidgetCarouselItem model. * If deletion is successful, the browser will be redirected to the 'index' page. - * @param integer $id + * @param integer|null $id * @return mixed */ - public function actionDelete($id) + public function actionDelete($id = null) { - $model = $this->findModel($id); - if ($model->delete()) { - return $this->redirect(['widget-carousel/update', 'id' => $model->carousel_id]); - }; - return ""; + $id = $id ?: Yii::$app->request->post('id'); + $model = is_array($id) ? $this->findModel($id[0]) : $this->findModel($id); + WidgetCarouselItem::deleteAll(['id' => $id]); + + return $this->redirect(['widget-carousel/update', 'id' => $model->carousel_id]); } /** diff --git a/controllers/WidgetMenuController.php b/controllers/WidgetMenuController.php index 61049d2..279b6ae 100644 --- a/controllers/WidgetMenuController.php +++ b/controllers/WidgetMenuController.php @@ -11,6 +11,7 @@ use Yii; use yii\filters\VerbFilter; use centigen\i18ncontent\web\Controller; +use yii\helpers\Json; use yii\web\NotFoundHttpException; @@ -87,27 +88,37 @@ public function actionCreate() */ public function actionUpdate($id) { - $model = $this->findModel($id); - if ($model->load(Yii::$app->request->post()) && $model->save()) { - return $this->redirect(['index']); - } else { + if(Yii::$app->request->isPost) { + $postData = Yii::$app->request->post(); + $model->load($postData); + $model->items = Json::encode($model->items); + if ($model->save()) { + return $this->redirect(['index']); + } else { + return $this->render('update', [ + 'model' => $model, + ]); + } + }else { return $this->render('update', [ 'model' => $model, ]); } + } /** * Deletes an existing WidgetMenu model. * If deletion is successful, the browser will be redirected to the 'index' page. - * @param integer $id + * @param integer|null $id * @return mixed */ - public function actionDelete($id) + public function actionDelete($id = null) { - $this->findModel($id)->delete(); + $id = $id ?: Yii::$app->request->post('id'); + WidgetMenu::deleteAll(['id' => $id]); return $this->redirect(['index']); } diff --git a/controllers/WidgetTextController.php b/controllers/WidgetTextController.php index f2dd037..63c8c8f 100644 --- a/controllers/WidgetTextController.php +++ b/controllers/WidgetTextController.php @@ -111,12 +111,14 @@ public function actionUpdate($id) /** * Deletes an existing WidgetText model. * If deletion is successful, the browser will be redirected to the 'index' page. - * @param integer $id + * @param integer|null $id * @return mixed */ - public function actionDelete($id) + public function actionDelete($id = null) { - $this->findModel($id)->delete(); + $id = $id ?: Yii::$app->request->post('id'); + WidgetText::deleteAll(['id' => $id]); + return $this->redirect(['index']); } diff --git a/helpers/MenuHelper.php b/helpers/MenuHelper.php new file mode 100644 index 0000000..7b38d20 --- /dev/null +++ b/helpers/MenuHelper.php @@ -0,0 +1,66 @@ +generateItems($items, $form, $model, $depth); + } + + public function generateItems($items, $form, $model, $depth, $ttt = '[items]') + { + $html = ''; + $index = 0; + foreach ($items as $key => $item) { + $id = (int)microtime(true) + $index + $depth; + + $subItems = ""; + + $suffix = $ttt . '[' . $key . ']'; + if (!empty($item['items'])){ + $subItems = '
'.$this->generateItems($item['items'], $form, $model, $depth+1, $suffix.'[items]').'
'; + } + + $html .= '
+
+
+
' . $form->field($model, $suffix.'icon')->textInput(['maxlength' => 1024, 'value' => ArrayHelper::getValue($item, 'icon')]) . '
+
' . $form->field($model, $suffix.'label')->textInput(['maxlength' => 1024, 'value' => ArrayHelper::getValue($item, 'label')]) . '
+
' . $form->field($model, $suffix.'url')->textInput(['maxlength' => 1024, 'value' => \yii\helpers\Url::to($item['url'])]) . '
+
+ + + ' . (isset($item['items']) ? '' : '') . ' +
+
+ ' . $subItems .' +
+ +
'; + $index++; + } + + return $html; + } + +} \ No newline at end of file diff --git a/models/Article.php b/models/Article.php index a39499e..63699aa 100644 --- a/models/Article.php +++ b/models/Article.php @@ -82,7 +82,13 @@ public static function tableName() */ public static function find() { - return (new ArticleQuery(get_called_class()))->with('activeTranslation'); + return (new ArticleQuery(get_called_class())) + ->with([ + 'translations', + 'activeTranslation', + 'articleAttachments', + 'articleCategoryArticles' + ]); } /** @@ -214,6 +220,9 @@ public function save($runValidation = true, $attributeNames = null) $transaction = Yii::$app->db->beginTransaction(); if (parent::save()){ + if (!is_array($this->category_ids)){ + $this->category_ids = []; + } $existingCategoryIds = ArrayHelper::getColumn($this->articleCategoryArticles, 'category_id'); $toDeleteCategoryIds = array_diff($existingCategoryIds, $this->category_ids); $toAddCategoryIds = array_diff($this->category_ids, $existingCategoryIds); diff --git a/models/ArticleAttachment.php b/models/ArticleAttachment.php index 50416c8..ab8f771 100644 --- a/models/ArticleAttachment.php +++ b/models/ArticleAttachment.php @@ -80,6 +80,6 @@ public function getArticle() public function getUrl() { - return $this->base_url .'/'. $this->path; + return Yii::getAlias('@storageUrl') . '/source/' . $this->path; } } diff --git a/models/WidgetMenu.php b/models/WidgetMenu.php index b67f716..2d654bb 100644 --- a/models/WidgetMenu.php +++ b/models/WidgetMenu.php @@ -18,6 +18,97 @@ class WidgetMenu extends ActiveRecord { const STATUS_ACTIVE = 1; const STATUS_DRAFT = 0; + + public $icon; + /** + * @var array list of HTML attributes shared by all menu [[items]]. If any individual menu item + * specifies its `options`, it will be merged with this property before being used to generate the HTML + * attributes for the menu item tag. The following special options are recognized: + * + * - tag: string, defaults to "li", the tag name of the item container tags. + * Set to false to disable container tag. + * See also [[\yii\helpers\Html::tag()]]. + * + * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. + */ + public $itemOptions = []; + /** + * @var string the template used to render the body of a menu which is a link. + * In this template, the token `{url}` will be replaced with the corresponding link URL; + * while `{label}` will be replaced with the link text. + * This property will be overridden by the `template` option set in individual menu items via [[items]]. + */ + public $linkTemplate = '{label}'; + /** + * @var string the template used to render the body of a menu which is NOT a link. + * In this template, the token `{label}` will be replaced with the label of the menu item. + * This property will be overridden by the `template` option set in individual menu items via [[items]]. + */ + public $labelTemplate = '{label}'; + /** + * @var string the template used to render a list of sub-menus. + * In this template, the token `{items}` will be replaced with the rendered sub-menu items. + */ + public $submenuTemplate = "\n\n"; + /** + * @var boolean whether the labels for menu items should be HTML-encoded. + */ + public $encodeLabels = true; + /** + * @var string the CSS class to be appended to the active menu item. + */ + public $activeCssClass = 'active'; + /** + * @var boolean whether to automatically activate items according to whether their route setting + * matches the currently requested route. + * @see isItemActive() + */ + public $activateItems = true; + /** + * @var boolean whether to activate parent menu items when one of the corresponding child menu items is active. + * The activated parent menu items will also have its CSS classes appended with [[activeCssClass]]. + */ + public $activateParents = false; + /** + * @var boolean whether to hide empty menu items. An empty menu item is one whose `url` option is not + * set and which has no visible child menu items. + */ + public $hideEmptyItems = true; + /** + * @var array the HTML attributes for the menu's container tag. The following special options are recognized: + * + * - tag: string, defaults to "ul", the tag name of the item container tags. Set to false to disable container tag. + * See also [[\yii\helpers\Html::tag()]]. + * + * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. + */ + public $options = []; + /** + * @var string the CSS class that will be assigned to the first item in the main menu or each submenu. + * Defaults to null, meaning no such CSS class will be assigned. + */ + public $firstItemCssClass; + /** + * @var string the CSS class that will be assigned to the last item in the main menu or each submenu. + * Defaults to null, meaning no such CSS class will be assigned. + */ + public $lastItemCssClass; + /** + * @var string the route used to determine if a menu item is active or not. + * If not set, it will use the route of the current request. + * @see params + * @see isItemActive() + */ + public $route; + /** + * @var array the parameters used to determine if a menu item is active or not. + * If not set, it will use `$_GET`. + * @see route + * @see isItemActive() + */ + public $params; + + /** * @inheritdoc */ diff --git a/views/article-category/_form.php b/views/article-category/_form.php index 13b1c3c..dce5b95 100644 --- a/views/article-category/_form.php +++ b/views/article-category/_form.php @@ -68,7 +68,9 @@ field($model, 'parent_id')->dropDownList($categories, ['prompt' => '']) ?> - field($model, 'status')->checkbox() ?> + field($model, 'status')->checkbox([ + 'template' => '
{hint}{error}' + ]) ?>
isNewRecord ? Yii::t('i18ncontent', 'Create') : Yii::t('i18ncontent', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> diff --git a/views/article-category/index.php b/views/article-category/index.php index 66365a7..74f29dd 100644 --- a/views/article-category/index.php +++ b/views/article-category/index.php @@ -18,13 +18,32 @@

'Article Category', - ]), ['create'], ['class' => 'btn btn-success']) ?> + ]), ['create'], ['class' => 'btn btn-success']); + echo ' '. Html::a( + Yii::t('i18ncontent', 'Delete checked {modelClass}s', ['modelClass' => 'Article Category']), + [null], + ['class' => 'btn btn-danger delete-multiple']) + ?>

$dataProvider, 'filterModel' => $searchModel, 'columns' => [ + [ + 'class' => \centigen\base\grid\CheckboxColumn::className(), + 'prefix' => '
', + 'headerPrefix' => '
', + 'options' => [ + 'style' => 'width: 1px;', + 'class' => 'text-center', + ], + 'contentOptions' => [ + 'style' => 'vertical-align: middle;' + ] + ], 'slug', [ 'attribute' => 'title', diff --git a/views/article/_form.php b/views/article/_form.php index 6e80342..7f326a5 100644 --- a/views/article/_form.php +++ b/views/article/_form.php @@ -91,7 +91,9 @@ field($model, 'view')->textInput(['maxlength' => true]) ?> - field($model, 'status')->checkbox() ?> + field($model, 'status')->checkbox([ + 'template' => '
{hint}{error}' + ]) ?> field($model, 'published_at')->widget( 'trntv\yii\datetime\DateTimeWidget', diff --git a/views/article/index.php b/views/article/index.php index bf9ba57..df64965 100644 --- a/views/article/index.php +++ b/views/article/index.php @@ -20,6 +20,12 @@ ['create'], ['class' => 'btn btn-success']) ?> + 'Article']), + [null], + ['class' => 'btn btn-danger delete-multiple']) + ?>

$dataProvider, 'filterModel' => $searchModel, 'columns' => [ + [ + 'class' => \centigen\base\grid\CheckboxColumn::className(), + 'prefix' => '
', + 'headerPrefix' => '
', + 'options' => [ + 'style' => 'width: 1px;', + 'class' => 'text-center', + ], + 'contentOptions' => [ + 'style' => 'vertical-align: middle;' + ] + ], [ 'attribute' => 'slug', 'contentOptions' => [ diff --git a/views/page/_form.php b/views/page/_form.php index c49b58f..4e3c68f 100644 --- a/views/page/_form.php +++ b/views/page/_form.php @@ -58,7 +58,9 @@ field($model, 'view')->textInput(['maxlength' => true]) ?> - field($model, 'status')->checkbox() ?> + field($model, 'status')->checkbox([ + 'template' => '
{hint}{error}' + ]) ?>
isNewRecord ? Yii::t('i18ncontent', 'Create') : Yii::t('i18ncontent', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> diff --git a/views/page/index.php b/views/page/index.php index 1e15ef3..bb3f72e 100644 --- a/views/page/index.php +++ b/views/page/index.php @@ -18,12 +18,32 @@ 'Page', ]), ['create'], ['class' => 'btn btn-success']) ?> + 'Pages']), + [null], + ['class' => 'btn btn-danger delete-multiple']) + ?>

$dataProvider, 'filterModel' => $searchModel, 'columns' => [ + [ + 'class' => \centigen\base\grid\CheckboxColumn::className(), + 'prefix' => '
', + 'headerPrefix' => '
', + 'options' => [ + 'style' => 'width: 1px;', + 'class' => 'text-center', + ], + 'contentOptions' => [ + 'style' => 'vertical-align: middle;' + ] + ], [ 'attribute' => 'title', 'value' => function ($model) { diff --git a/views/widget-carousel/_form.php b/views/widget-carousel/_form.php index 36e1643..d430d63 100644 --- a/views/widget-carousel/_form.php +++ b/views/widget-carousel/_form.php @@ -14,7 +14,9 @@ field($model, 'key')->textInput(['maxlength' => 1024]) ?> - field($model, 'status')->checkbox() ?> + field($model, 'status')->checkbox([ + 'template' => '
{hint}{error}' + ]) ?>
isNewRecord ? Yii::t('i18ncontent', 'Create') : Yii::t('i18ncontent', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> diff --git a/views/widget-carousel/index.php b/views/widget-carousel/index.php index 8febc38..aeb89b0 100644 --- a/views/widget-carousel/index.php +++ b/views/widget-carousel/index.php @@ -15,13 +15,32 @@

'Widget Carousel', - ]), ['create'], ['class' => 'btn btn-success']) ?> + ]), ['create'], ['class' => 'btn btn-success']); + echo ' '. Html::a( + Yii::t('i18ncontent', 'Delete checked {modelClass}s', ['modelClass' => 'Widget Carousel']), + [null], + ['class' => 'btn btn-danger delete-multiple']) + ?>

$dataProvider, 'filterModel' => $searchModel, 'columns' => [ + [ + 'class' => \centigen\base\grid\CheckboxColumn::className(), + 'prefix' => '
', + 'headerPrefix' => '
', + 'options' => [ + 'style' => 'width: 1px;', + 'class' => 'text-center', + ], + 'contentOptions' => [ + 'style' => 'vertical-align: middle;' + ] + ], 'key', [ 'label' => Yii::t('i18ncontent', 'Status'), diff --git a/views/widget-carousel/item/_form.php b/views/widget-carousel/item/_form.php index 2556a81..739fc53 100644 --- a/views/widget-carousel/item/_form.php +++ b/views/widget-carousel/item/_form.php @@ -74,7 +74,9 @@ ?> - field($model, 'status')->checkbox() ?> + field($model, 'status')->checkbox([ + 'template' => '
{hint}{error}' + ]) ?>
isNewRecord ? Yii::t('i18ncontent', 'Create') : Yii::t('i18ncontent', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> diff --git a/views/widget-carousel/update.php b/views/widget-carousel/update.php index 6892114..884943d 100644 --- a/views/widget-carousel/update.php +++ b/views/widget-carousel/update.php @@ -23,7 +23,13 @@

'Widget Carousel Item', - ]), ['widget-carousel-item/create', 'carousel_id' => $model->id], ['class' => 'btn btn-success']) ?> + ]), ['widget-carousel-item/create', 'carousel_id' => $model->id], ['class' => 'btn btn-success']); + + echo ' '. Html::a( + Yii::t('i18ncontent', 'Delete checked {modelClass}s', ['modelClass' => 'Widget Carousel Item']), + [null], + ['class' => 'btn btn-danger delete-multiple', 'data-url' => '/i18ncontent/widget-carousel-item/delete']); + ?>

[ + [ + 'class' => \centigen\base\grid\CheckboxColumn::className(), + 'prefix' => '
', + 'headerPrefix' => '
', + 'options' => [ + 'style' => 'width: 1px;', + 'class' => 'text-center', + ], + 'contentOptions' => [ + 'style' => 'vertical-align: middle;' + ] + ], [ 'attribute' => 'order', 'contentOptions' => [ diff --git a/views/widget-menu/_form.php b/views/widget-menu/_form.php index e5e24a4..93d27e4 100644 --- a/views/widget-menu/_form.php +++ b/views/widget-menu/_form.php @@ -11,6 +11,8 @@ /* @var $this yii\web\View */ /* @var $model \centigen\i18ncontent\models\WidgetMenu */ /* @var $form yii\bootstrap\ActiveForm */ + +$menuItems = \yii\helpers\Json::decode($model->items); ?>
@@ -23,14 +25,13 @@ field($model, 'title')->textInput(['maxlength' => 512]) ?> - field($model, 'items')->widget( - AceEditor::className(), - [ - 'mode' => 'json' - ] - ) ?> +

+ + render('_items', ['items' => $menuItems, 'form' => $form, 'model' => $model])?> - field($model, 'status')->checkbox() ?> + field($model, 'status')->checkbox([ + 'template' => '
{hint}{error}' + ]) ?>
isNewRecord ? Yii::t('i18ncontent', 'Create') : Yii::t('i18ncontent', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> diff --git a/views/widget-menu/_items.php b/views/widget-menu/_items.php new file mode 100644 index 0000000..7b52e5f --- /dev/null +++ b/views/widget-menu/_items.php @@ -0,0 +1,16 @@ +getItems($items, $form, $model); +?> \ No newline at end of file diff --git a/views/widget-menu/_options_modal.php b/views/widget-menu/_options_modal.php new file mode 100644 index 0000000..fcbc0a6 --- /dev/null +++ b/views/widget-menu/_options_modal.php @@ -0,0 +1,23 @@ +
'. $form->field($model, 'label[]')->textInput(['maxlength' => 1024, 'value' => $item['label']]). '
'; + echo '
'. $form->field($model, 'url[]')->textInput(['maxlength' => 1024, 'value' => $item['url']]) . '
'; + } + + } +} +echo generateMenuOptions($items, $form, $model); +?> \ No newline at end of file diff --git a/views/widget-menu/_url_field_modal.php b/views/widget-menu/_url_field_modal.php new file mode 100644 index 0000000..f2b1845 --- /dev/null +++ b/views/widget-menu/_url_field_modal.php @@ -0,0 +1,53 @@ + +
+
+ +
+
+ Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. +
+
+
+
+ +
+
+ Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. +
+
+
+
+ +
+
+ Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS. +
+
+
+
diff --git a/views/widget-menu/index.php b/views/widget-menu/index.php index 89ab274..3fca452 100644 --- a/views/widget-menu/index.php +++ b/views/widget-menu/index.php @@ -12,13 +12,18 @@ $this->title = Yii::t('i18ncontent', 'Widget Menus'); $this->params['breadcrumbs'][] = $this->title; ?> -
+
render('_search', ['model' => $searchModel]); ?>

'Widget Menu', - ]), ['create'], ['class' => 'btn btn-success']) ?> + ]), ['create'], ['class' => 'btn btn-success']); + echo ' '. Html::a( + Yii::t('i18ncontent', 'Delete checked {modelClass}s', ['modelClass' => 'Widget Menu']), + [null], + ['class' => 'btn btn-danger delete-multiple']) + ?>

'grid-view table-responsive' ], 'columns' => [ + [ + 'class' => \centigen\base\grid\CheckboxColumn::className(), + 'prefix' => '
', + 'headerPrefix' => '
', + 'options' => [ + 'style' => 'width: 1px;', + 'class' => 'text-center', + ], + 'contentOptions' => [ + 'style' => 'vertical-align: middle;' + ] + ], 'title', 'key', [ diff --git a/views/widget-menu/update.php b/views/widget-menu/update.php index 38d0380..25eb535 100644 --- a/views/widget-menu/update.php +++ b/views/widget-menu/update.php @@ -15,9 +15,8 @@ $this->params['breadcrumbs'][] = Yii::t('i18ncontent', 'Update'); ?>
- + Menu options render('_form', [ 'model' => $model, ]) ?> -
\ No newline at end of file diff --git a/views/widget-text/_form.php b/views/widget-text/_form.php index 7ffe2af..8a96437 100644 --- a/views/widget-text/_form.php +++ b/views/widget-text/_form.php @@ -58,7 +58,9 @@ ?> - field($model, 'status')->checkbox() ?> + field($model, 'status')->checkbox([ + 'template' => '
{hint}{error}' + ]) ?>
'Text Block', - ]), ['create'], ['class' => 'btn btn-success']) ?> + ]), ['create'], ['class' => 'btn btn-success']); + echo ' '. Html::a( + Yii::t('i18ncontent', 'Delete checked {modelClass}s', ['modelClass' => 'Text Block']), + [null], + ['class' => 'btn btn-danger delete-multiple']) + ?>

$dataProvider, 'filterModel' => $searchModel, 'columns' => [ + [ + 'class' => \centigen\base\grid\CheckboxColumn::className(), + 'prefix' => '
', + 'headerPrefix' => '
', + 'options' => [ + 'style' => 'width: 1px;', + 'class' => 'text-center', + ], + 'contentOptions' => [ + 'style' => 'vertical-align: middle;' + ] + ], 'key', [ 'attribute' => 'title',