From adc7e08f9e3c48400becb2a86a09777dcde931bd Mon Sep 17 00:00:00 2001 From: Anastasia Date: Fri, 31 Aug 2018 12:05:03 +0300 Subject: [PATCH] add slug - main menu --- backend/actions/Create.php | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ backend/actions/Update.php | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ backend/actions/views/create.php | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ backend/actions/views/update.php | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ backend/controllers/PageController.php | 5 +++-- backend/widgets/Form.php | 699 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ console/migrations/m180831_083021_alter_page_columns.php | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ frontend/views/layouts/main.php | 26 ++++++++++++-------------- frontend/views/page/view.php | 53 +++++++---------------------------------------------- 9 files changed, 1078 insertions(+), 62 deletions(-) create mode 100755 backend/actions/Create.php create mode 100755 backend/actions/Update.php create mode 100755 backend/actions/views/create.php create mode 100755 backend/actions/views/update.php create mode 100755 backend/widgets/Form.php create mode 100644 console/migrations/m180831_083021_alter_page_columns.php diff --git a/backend/actions/Create.php b/backend/actions/Create.php new file mode 100755 index 0000000..f59738c --- /dev/null +++ b/backend/actions/Create.php @@ -0,0 +1,97 @@ +controller, + 'newModel', + ] + ); + $languages = Language::getActive(); + if ($this->hasAlias) { + /** + * @var \artbox\core\models\Alias[] $aliases + */ + $aliases = $model->loadAliases(); + } + + $post = \Yii::$app->request->post(); + + if (!empty($this->languageFields)) { + Model::loadMultiple($model->getVariationModels(), $post); + } + + if ($model->load($post) && $model->save()) { + if ($this->hasAlias) { + /** + * @var \artbox\core\models\Alias[] $aliases + */ + Model::loadMultiple($aliases, $post); + foreach ($aliases as $alias) { + $alias->route = $model->getRoute(); + if ($this->overwriteEntity === null) { + $alias->entity = $model::className(); + } else { + $alias->entity = $this->overwriteEntity; + } + $alias->save(); + + /** + * @var \yii\db\ActiveRecord $modelLang + */ + $modelLang = $model->getVariationModel($alias->language_id); + $modelLang->alias_id = $alias->id; + $modelLang->save(); + } + } + + if ($this->hasGallery) { + $model->saveImages($post); + } + + return $this->controller->redirect([ 'index' ]); + } + + return $this->controller->render( + $this->viewPath, + [ + 'action' => $this, + 'model' => $model, + 'languages' => $languages, + ] + ); + } + } \ No newline at end of file diff --git a/backend/actions/Update.php b/backend/actions/Update.php new file mode 100755 index 0000000..da7d0e7 --- /dev/null +++ b/backend/actions/Update.php @@ -0,0 +1,68 @@ +controller, + 'findModel', + ], + [ $id ] + ); + $languages = Language::getActive(); + $post = \Yii::$app->request->post(); + + if (!empty($this->languageFields)) { + Model::loadMultiple($model->getVariationModels(), $post); + } + + if ($model->load($post) && $model->save()) { + if ($this->hasAlias) { + /** + * @var \artbox\core\models\Alias[] $aliases + */ + $aliases = $model->loadAliases(); + Model::loadMultiple($aliases, $post); + foreach ($aliases as $alias) { + $alias->save(); + } + } + + if ($this->hasGallery) { + $model->saveImages($post); + } + + return $this->controller->redirect([ 'index' ]); + } + + return $this->controller->render( + $this->viewPath, + [ + 'action' => $this, + 'model' => $model, + 'languages' => $languages, + ] + ); + } + } \ No newline at end of file diff --git a/backend/actions/views/create.php b/backend/actions/views/create.php new file mode 100755 index 0000000..f5443cb --- /dev/null +++ b/backend/actions/views/create.php @@ -0,0 +1,72 @@ +getShortName(); + + $this->params[ 'breadcrumbs' ][] = [ + 'label' => \Yii::t('core', Inflector::pluralize($modelName)), + 'url' => [ $action->controller->id . '/index' ], + ]; + + $this->title = \Yii::t('core', 'Create ' . lcfirst($modelName)); + + $this->params[ 'breadcrumbs' ][] = $this->title; + +?> + +
+
+

title; ?>

+ +
+ languageFields)) {?> +
+ + + + + + + +
+ +
+ + languageFields)) {?> + Языковой блок + + Основной блок + hasAlias){?> + Seo + + hasGallery){?> + Галерея + +
+
+
+
+ $action, + 'model' => $model, + ] + ); + + + ?> +
+ diff --git a/backend/actions/views/update.php b/backend/actions/views/update.php new file mode 100755 index 0000000..ab9175a --- /dev/null +++ b/backend/actions/views/update.php @@ -0,0 +1,72 @@ +getShortName(); + + $this->params[ 'breadcrumbs' ][] = [ + 'label' => \Yii::t('core', Inflector::pluralize($modelName)), + 'url' => [ $action->controller->id . '/index' ], + ]; + + $this->title = \Yii::t('core', 'Update ' . lcfirst($modelName)); + + $this->params[ 'breadcrumbs' ][] = $this->title; +?> + +
+ +
+

title; ?>

+ +
+ languageFields)) {?> +
+ + + + + + + +
+ +
+ languageFields)) {?> + Языковой блок + + Основной блок + hasAlias){?> + Seo + + hasGallery){?> + Галерея + +
+
+
+
+ $action, + 'model' => $model, + ] + ); + + + ?> +
+ diff --git a/backend/controllers/PageController.php b/backend/controllers/PageController.php index e3b2153..4d109a0 100755 --- a/backend/controllers/PageController.php +++ b/backend/controllers/PageController.php @@ -3,10 +3,10 @@ namespace backend\controllers; use function array_merge; - use artbox\core\admin\actions\Create; + use backend\actions\Create; use artbox\core\admin\actions\Delete; use backend\actions\Index; - use artbox\core\admin\actions\Update; + use backend\actions\Update; use artbox\core\admin\actions\View; use artbox\core\admin\interfaces\ControllerInterface; use artbox\core\admin\widgets\Form; @@ -159,6 +159,7 @@ [ 'name' => 'title', 'type' => Form::STRING, + 'decorate' => true ], [ 'name' => 'body', diff --git a/backend/widgets/Form.php b/backend/widgets/Form.php new file mode 100755 index 0000000..5b41564 --- /dev/null +++ b/backend/widgets/Form.php @@ -0,0 +1,699 @@ +
{title}
{tab}'; + + /** + * Template for block of all languages tabs + * + * @var string + */ + public $langBlockTemplate = '
{tabs}
'; + /** + * @var array fields for seo value + */ + public $decorateField = []; + /** + * @inheritdoc + * @todo Remove H1 stabs + * @return string|void + * @throws \Exception + * @throws \yii\base\InvalidConfigException + */ + public function run() + { + Switchery::register($this->view); + + $js = <<< JS +$('.switchery').each(function(idx, elem) { + new Switchery(elem, { + color:'#46b749', + secondaryColor:'#e2e2e2' + }); +}); +JS; + + + $this->languages = new Languages(); + + $this->view->registerJs($js, \yii\web\View::POS_READY); + $notify = << 0){ + new PNotify({ + title: 'Info', + text: 'Проверьте заполнение полей', + type: 'info', + styling: "bootstrap3" + }); + } + }); +JS; + + $this->view->registerJs($notify, \yii\web\View::POS_READY); + + $form = ActiveForm::begin(); + if (!empty($this->action->languageFields)) { + echo str_replace( + [ + '{tabs}', + '{title}', + ], + [ + $this->generateLangBlock($form), + 'Языковой блок', + ], + $this->langBlockTemplate + ); + } + + echo '
'; + + echo '
'; + echo '
Основной блок
'; + $this->generateCommonBlock($form); + echo '
'; + + echo '
'; + + if ($this->action->hasAlias) { + echo str_replace( + [ + '{tabs}', + '{title}', + ], + [ + $this->generateAliasBlock($form), + 'Seo блок', + ], + $this->langBlockTemplate + ); + } + + if ($this->action->hasGallery) { + echo '
'; + echo '
'; + echo '
Галерея
'; + echo GalleryWidget::widget( + [ + 'model' => $this->model, + ] + ); + echo '
'; + echo '
'; + } + + echo '
'; + echo Html::submitButton( + \Yii::t('core', 'Save'), + [ + 'class' => 'btn btn-success', + ] + ); + echo '
'; + + $form::end(); + + $this->registerClientScripts(); + } + + protected function registerClientScripts() + { + $js = << 0) { + input.val(newVal); + } + }); + $(document) + .on('click', '.pos-pluse-adm', function(e) { + e.preventDefault(); + var input = $(this) + .parent() + .find('input'); + var newVal = parseInt((input.val() === '' ? 0 : input.val())) + 1; + input.val(newVal); + }); + + $('#page-sort').keypress(function(e) { + var symbol = (e.which) ? e.which : e.keyCode; + if (symbol < 48 || symbol > 57) { + return false; + } + }) +JS; + + $this->view->registerJs($js, \yii\web\View::POS_READY); + } + + /** + * If model has languages + * + * @param \yii\widgets\ActiveForm $form + * + * @return string + * @throws \yii\base\InvalidConfigException + */ + protected function generateLangBlock(ActiveForm $form): string + { + $tabs = ''; + $i = 1; + foreach ($this->getVariationModels() as $index => $variationModel) { + $tab = ''; + foreach ($this->action->languageFields as $languageField) { + switch ($languageField[ 'type' ]) { + case self::STRING: + if (isset($languageField[ 'decorate' ]) and $languageField[ 'decorate' ]) { + $this->decorateField[ $index ] = $form->field( + $variationModel, + '[' . $index . ']' . $languageField[ 'name' ] + ) + ->label( + self::getLanguageLabel( + $variationModel, + $languageField[ 'name' ], + $variationModel->language_id + ) + ); + $tab .= $this->decorateField[ $index ]; + } else { + $tab .= $form->field($variationModel, '[' . $index . ']' . $languageField[ 'name' ]) + ->label( + self::getLanguageLabel( + $variationModel, + $languageField[ 'name' ], + $variationModel->language_id + ) + ); + } + break; + case self::TEXTAREA: + $tab .= $form->field($variationModel, '[' . $index . ']' . $languageField[ 'name' ]) + ->textarea( + [ + 'rows' => 6, + ] + ) + ->label( + self::getLanguageLabel( + $variationModel, + $languageField[ 'name' ], + $variationModel->language_id + ) + ); + break; + case self::IMAGE: + $tab .= $form->field( + $variationModel, + '[' . $index . ']' . $languageField[ 'name' ], + [ 'options' => [ 'class' => 'form-group filed-upload-imgs' ] ] + ) + ->widget( + ImageInput::className(), + [ + 'showPreview' => true, + ] + ) + ->label( + self::getLanguageLabel( + $variationModel, + $languageField[ 'name' ], + $variationModel->language_id + ) + ); + break; + case self::WYSIWYG: + $tab .= $form->field($variationModel, '[' . $index . ']' . $languageField[ 'name' ]) + ->widget( + TinyMce::className(), + $this->action->getTinyMceConfig() + ) + ->label( + self::getLanguageLabel( + $variationModel, + $languageField[ 'name' ], + $variationModel->language_id + ) + ); + break; + default: + throw new InvalidConfigException( + \Yii::t( + 'core', + 'Unavailable or unknown type: {type}', + [ + 'type' => $languageField[ 'type' ], + ] + ) + ); + } + } + + if ($variationModel->language_id === $this->languages->getDefault()->id) { + $tabs .= str_replace( + [ + '{tab}', + '{display}', + ], + [ + $tab, + 'block', + ], + $this->langTabTemplate + ); + } else { + $tabs .= str_replace( + [ + '{tab}', + '{display}', + ], + [ + $tab, + 'none', + ], + $this->langTabTemplate + ); + } + + $i++; + } + + return $tabs; + } + + /** + * Common block + * + * @param \yii\widgets\ActiveForm $form + * + * @throws \yii\base\InvalidConfigException + */ + protected function generateCommonBlock(ActiveForm $form) + { + foreach ($this->action->fields as $field) { + switch ($field[ 'type' ]) { + case self::STRING: + echo $form->field($this->model, $field[ 'name' ]); + break; + case self::TEXTAREA: + echo $form->field($this->model, $field[ 'name' ]) + ->textarea( + [ + 'rows' => 6, + ] + ); + break; + case self::WYSIWYG: + echo $form->field($this->model, $field[ 'name' ]) + ->widget( + TinyMce::className(), + $this->action->getTinyMceConfig() + ); + break; + case self::BOOL: + echo $form->field( + $this->model, + $field[ 'name' ], + [ + 'template' => "
{label}
\n{input}\n{error}", + ] + ) + ->checkbox( + [ + 'class' => 'switchery', + ], + false + ); + break; + case self::NUMBER: + echo $form->field( + $this->model, + $field[ 'name' ], + [ + 'template' => '{label}{input} + {error}{hint}', + 'options' => [ 'class' => 'form-group filed-sort' ], + ] + ); + break; + case self::RELATION: + $isMultiple = $field[ 'multiple' ] ?? false; + echo $form->field($this->model, $field[ 'name' ]) + ->widget( + Select2::classname(), + [ + 'data' => $this->action->relationalData[ $field[ 'name' ] ], + 'options' => [ + 'placeholder' => \Yii::t('core', 'Select ...'), + 'multiple' => $isMultiple, + ], + 'pluginOptions' => [ + 'allowClear' => true, + ], + ] + ); + break; + case self::SELECT: + $isMultiple = $field[ 'multiple' ] ?? false; + echo $form->field($this->model, $field[ 'name' ]) + ->widget( + Select2::classname(), + [ + 'data' => $field['data'], + 'options' => [ + 'placeholder' => \Yii::t('core', 'Select ...'), + 'multiple' => $isMultiple, + ], + 'pluginOptions' => [ + 'allowClear' => true, + ], + ] + ); + + break; + case self::IMAGE: + echo $form->field( + $this->model, + $field[ 'name' ], + [ 'options' => [ 'class' => 'form-group filed-upload-imgs' ] ] + ) + ->widget( + ImageInput::className(), + [ + 'showPreview' => true, + ] + ); + break; + case self::DATE: + DateRangePicker::register($this->view); + $mindate = date("d-m-Y H:i"); + $value = $this->model->{$field['name']}; + $js = <<< JS +var dateRangeInputFrom = $('#date_field'); +var dateFormat = '{$this->model->clientDateFormat}'; +dateRangeInputFrom.daterangepicker({ + singleDatePicker: true, + autoUpdateInput: true, + showDropdowns: true, + minDate: '{$mindate}', + timePicker: true, + timePicker24Hour: true, + locale: { + cancelLabel: 'Clear', + format: dateFormat + } +}, function(){ + + }); +dateRangeInputFrom.on('cancel.daterangepicker', function(ev, picker) { + //do something, like clearing an input + dateRangeInputFrom.val(''); +}); +if ("{$value}" == ""){ + dateRangeInputFrom.val(''); +} +JS; + $this->view->registerJs($js, \yii\web\View::POS_READY); + echo $form->field( + $this->model, + $field[ 'name' ], + [ 'options' => [ 'class' => 'form-group date-search' ] ] + )->textInput(['id' => "date_field"]); + break; + + default: + throw new InvalidConfigException( + \Yii::t( + 'core', + 'Unavailable or unknown type: {type}', + [ + 'type' => $field[ 'type' ], + ] + ) + ); + } + } + } + + /** + * Generate seo block + * + * @param \yii\widgets\ActiveForm $form + * + * @return string + */ + protected function generateAliasBlock(ActiveForm $form) + { + $tabs = ''; + $i = 1; + foreach ($this->getAliases() as $index => $alias) { + $tab = ''; + if (isset($this->decorateField[ $index ])) { + $tab .= '
' . SlugifyDecorator::decorate( + $form->field($alias, "[$index]value"), + [ '/seo/alias/slugify' ], + $this->decorateField[ $index ], + false, + $alias->language_id + ) + ->textInput( + [ 'maxlength' => true ] + ) . "
"; + } else { + $tab .= $form->field($alias, '[' . $index . ']value') + ->label( + self::getLanguageLabel($alias, 'value', $alias->language_id) + ); + } + + $tab .= $form->field($alias, '[' . $index . ']title') + ->label( + self::getLanguageLabel($alias, 'title', $alias->language_id) + ); + + $tab .= $form->field($alias, '[' . $index . ']description') + ->textarea( + [ + 'rows' => 6, + ] + ) + ->label( + self::getLanguageLabel($alias, 'description', $alias->language_id) + ); + + $tab .= $form->field($alias, '[' . $index . ']h1') + ->label( + self::getLanguageLabel($alias, 'h1', $alias->language_id) + ); + + $tab .= $form->field($alias, '[' . $index . ']seo_text') + ->widget( + TinyMce::className(), + $this->action->getTinyMceConfig() + ) + ->label( + self::getLanguageLabel($alias, 'seo_text', $alias->language_id) + ); + + $tab .= $form->field($alias, '[' . $index . ']robots') + ->widget( + Select2::class, + [ + 'data' => [ + 'index, follow' => 'index, follow', + 'index, nofollow' => 'index, nofollow', + 'noindex, follow' => 'noindex, follow', + 'noindex, nofollow' => 'noindex, nofollow', + ], + ] + ) + ->label( + self::getLanguageLabel($alias, 'robots', $alias->language_id) + ); + + if ($alias->language_id === $this->languages->getDefault()->id) { + $tabs .= str_replace( + [ + '{tab}', + '{display}', + ], + [ + $tab, + 'block', + ], + $this->langTabTemplate + ); + } else { + $tabs .= str_replace( + [ + '{tab}', + '{display}', + ], + [ + $tab, + 'none', + ], + $this->langTabTemplate + ); + } + + $i++; + } + + return $tabs; + } + + /** + * Appends language short name to label + * + * @param \yii\db\ActiveRecord $model + * @param string $field + * @param $language_id + * + * @return string + */ + protected static function getLanguageLabel(ActiveRecord $model, string $field, $language_id): string + { + $languages = Language::getActive(); + return $model->getAttributeLabel( + $field + ) . ' (' . $languages[ $language_id ]->url . ')'; + + } + + /** + * @return ActiveRecord[] + */ + protected function getVariationModels(): array + { + return call_user_func( + [ + $this->model, + 'getVariationModels', + ] + ); + } + + /** + * @return \artbox\core\models\Alias[] + */ + protected function getAliases(): array + { + return call_user_func( + [ + $this->model, + 'loadAliases', + ] + ); + } + } + +?> + + + diff --git a/console/migrations/m180831_083021_alter_page_columns.php b/console/migrations/m180831_083021_alter_page_columns.php new file mode 100644 index 0000000..2245d44 --- /dev/null +++ b/console/migrations/m180831_083021_alter_page_columns.php @@ -0,0 +1,48 @@ +dropColumn('page', 'created_at'); + $this->dropColumn('page', 'updated_at'); + + $this->addColumn('page', 'created_at', $this->integer()); + $this->addColumn('page', 'updated_at', $this->integer()); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropColumn('page', 'created_at'); + $this->dropColumn('page', 'updated_at'); + + $this->addColumn('page', 'created_at', $this->timestamp()); + $this->addColumn('page', 'updated_at', $this->timestamp()); + } + + /* + // Use up()/down() to run migration code without a transaction. + public function up() + { + + } + + public function down() + { + echo "m180831_083021_alter_page_columns cannot be reverted.\n"; + + return false; + } + */ +} diff --git a/frontend/views/layouts/main.php b/frontend/views/layouts/main.php index 61da3a1..50e0d9f 100755 --- a/frontend/views/layouts/main.php +++ b/frontend/views/layouts/main.php @@ -139,17 +139,16 @@ JS;