diff --git a/backend/behaviors/LevelBehavior.php b/backend/behaviors/LevelBehavior.php new file mode 100755 index 0000000..642da53 --- /dev/null +++ b/backend/behaviors/LevelBehavior.php @@ -0,0 +1,47 @@ + 'beforeSave', + ActiveRecord::EVENT_BEFORE_UPDATE => 'beforeSave', + ]; + } + + public function beforeSave($event) + { + /** + * @var ActiveRecord $owner + */ + $levelField = $this->levelField; + $parentIdField = $this->parentIdField; + $owner = $this->owner; + + if (empty($owner->$parentIdField) && $owner->$parentIdField == 0) { + $owner->$levelField = 0; + } else { + $parent = $owner::findOne($owner->$parentIdField); + $owner->$levelField = (int) $parent->$levelField + 1; + } + + } + } \ No newline at end of file diff --git a/backend/controllers/PageController.php b/backend/controllers/PageController.php index 5fc700d..95f7234 100644 --- a/backend/controllers/PageController.php +++ b/backend/controllers/PageController.php @@ -175,11 +175,11 @@ 'name' => 'categoryIds', 'type' => Form::RELATION, 'relationAttribute' => 'title', - 'relationName' => 'categories', - 'multiple' => true, + 'relationName' => 'parent', + 'multiple' => false, ], [ - 'name' => 'in_menu', + 'name' => 'status', 'type' => Form::BOOL, ], [ diff --git a/backend/controllers/ServiceController.php b/backend/controllers/ServiceController.php new file mode 100644 index 0000000..165bd17 --- /dev/null +++ b/backend/controllers/ServiceController.php @@ -0,0 +1,187 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => [ 'POST' ], + ], + ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => [ '@' ], + ], + ], + ], + ]; + } + + public function actions() + { + return [ + 'index' => [ + 'class' => Index::className(), + 'columns' => [ + 'title' => [ + 'type' => Index::ACTION_COL, + ], + 'parent' => [ + 'type' => Index::RELATION_COL, + 'columnConfig' => [ + 'relationField' => 'title', + ], + ], + 'updated_at' => [ + 'type' => Index::DATETIME_COL, + ], + 'sort' => [ + 'type' => Index::POSITION_COL, + ], + 'status' => [ + 'type' => Index::STATUS_COL, + ], + ], + 'model' => Service::className(), + 'hasLanguage' => true, + 'enableMassDelete' => true, + 'modelPrimaryKey' => 'id', + ], + 'create' => array_merge([ 'class' => Create::className() ], self::fieldsConfig()), + 'update' => array_merge([ 'class' => Update::className() ], self::fieldsConfig()), + 'view' => [ + 'class' => View::className(), + 'model' => Service::className(), + 'hasAlias' => true, + 'languageFields' => [ + [ + 'name' => 'title', + 'type' => Form::STRING, + ], + [ + 'name' => 'body', + 'type' => Form::WYSIWYG, + ], + ], + 'fields' => [ + [ + 'name' => 'parent_id', + 'type' => Form::RELATION, + 'relationAttribute' => 'title', + 'relationName' => 'parent', + 'multiple' => false, + ], + ], + ], + 'delete' => [ + 'class' => Delete::className(), + ], + ]; + } + + public function findModel($id) + { + $model = Service::find() + ->with('languages') + ->where([ 'id' => $id ]) + ->one(); + if ($model !== null) { + return $model; + } else { + throw new NotFoundHttpException('The requested page does not exist.'); + } + } + + public function newModel() + { + return new Service(); + } + + public function deleteModel($id) + { + $page = Service::find() + ->with('languages.alias') + ->where( + [ + 'id' => $id, + ] + ) + ->one(); + $langs = call_user_func( + [ + $page, + 'getVariationModels', + ] + ); + foreach ($langs as $lang) { + if ($lang->alias !== null) { + $lang->alias->delete(); + } + } + + return $page->delete(); + } + + protected static function fieldsConfig() + { + return [ + 'model' => Service::className(), + 'hasAlias' => true, + 'languageFields' => [ + [ + 'name' => 'title', + 'type' => Form::STRING, + ], + [ + 'name' => 'body', + 'type' => Form::WYSIWYG, + ], + ], + 'fields' => [ + + [ + 'name' => 'parent_id', + 'type' => Form::RELATION, + 'relationAttribute' => 'title', + 'relationName' => 'parent', + 'multiple' => true, + ], + [ + 'name' => 'status', + 'type' => Form::BOOL, + ], + [ + 'name' => 'sort', + 'type' => Form::NUMBER, + ], + ], + ]; + } + } \ No newline at end of file diff --git a/backend/views/layouts/menu_items.php b/backend/views/layouts/menu_items.php index 439680a..0f9b6cf 100755 --- a/backend/views/layouts/menu_items.php +++ b/backend/views/layouts/menu_items.php @@ -45,6 +45,11 @@ 'url' => [ '/page-category/index' ], ], + [ + 'label' => \Yii::t('app', 'Services'), + 'url' => [ '/service/index' ], + + ], ], ], diff --git a/common/models/Service.php b/common/models/Service.php new file mode 100644 index 0000000..9aaa1ee --- /dev/null +++ b/common/models/Service.php @@ -0,0 +1,138 @@ + [ + 'class' => VariationBehavior::className(), + 'variationsRelation' => 'languages', + 'defaultVariationRelation' => 'language', + 'variationOptionReferenceAttribute' => 'language_id', + 'optionModelClass' => Language::className(), + 'defaultVariationOptionReference' => function () { + return Language::getCurrent()->id; + }, + 'optionQueryFilter' => function (ActiveQuery $query) { + $query->where( + [ + 'status' => true, + ] + ); + }, + ], + 'positionBehavior' => [ + 'class' => PositionBehavior::className(), + 'positionAttribute' => 'sort', + ], + 'timestamp' => [ + 'class' => TimestampBehavior::className(), + ], + 'level' => [ + 'class' => LevelBehavior::className(), + ], + ]; + } + /** + * {@inheritdoc} + */ + public function rules() + { + return [ + [['parent_id', 'sort', 'level', 'created_at', 'updated_at'], 'default', 'value' => null], + [['sort', 'level', 'created_at', 'updated_at'], 'integer'], + [['status'], 'boolean'], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => Yii::t('app', 'ID'), + 'parent_id' => Yii::t('app', 'Parent ID'), + 'sort' => Yii::t('app', 'Sort'), + 'status' => Yii::t('app', 'Status'), + 'level' => Yii::t('app', 'Level'), + 'created_at' => Yii::t('app', 'Created At'), + 'updated_at' => Yii::t('app', 'Updated At'), + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getLanguages() + { + return $this->hasMany(ServiceLang::className(), ['service_id' => 'id']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getParent(){ + return $this->hasOne(Service::className(), ['id' => 'parent_id']); + } + + + public function getLanguage(){ + return $this->hasDefaultVariationRelation(); + } + + /** + * @return string + */ + public function getRoute() + { + return Json::encode( + [ + 'service/view', + 'id' => $this->id, + ] + ); + } +} diff --git a/common/models/ServiceLang.php b/common/models/ServiceLang.php new file mode 100644 index 0000000..176a514 --- /dev/null +++ b/common/models/ServiceLang.php @@ -0,0 +1,135 @@ + null, + ], + [ + [ + 'service_id', + 'language_id', + 'alias_id', + ], + 'integer', + ], + [ + [ 'body' ], + 'string', + ], + [ + [ 'title' ], + 'string', + 'max' => 255, + ], + [ + [ + 'service_id', + 'language_id', + ], + 'unique', + 'targetAttribute' => [ + 'service_id', + 'language_id', + ], + ], + [ + [ 'alias_id' ], + 'exist', + 'skipOnError' => true, + 'targetClass' => Alias::className(), + 'targetAttribute' => [ 'alias_id' => 'id' ], + ], + [ + [ 'language_id' ], + 'exist', + 'skipOnError' => true, + 'targetClass' => Language::className(), + 'targetAttribute' => [ 'language_id' => 'id' ], + ], + [ + [ 'service_id' ], + 'exist', + 'skipOnError' => true, + 'targetClass' => Service::className(), + 'targetAttribute' => [ 'service_id' => 'id' ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'service_id' => Yii::t('app', 'Service ID'), + 'language_id' => Yii::t('app', 'Language ID'), + 'title' => Yii::t('app', 'Title'), + 'body' => Yii::t('app', 'Body'), + 'alias_id' => Yii::t('app', 'Alias ID'), + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getAlias() + { + return $this->hasOne(Alias::className(), [ 'id' => 'alias_id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getLanguage() + { + return $this->hasOne(Language::className(), [ 'id' => 'language_id' ]); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getService() + { + return $this->hasOne(Service::className(), [ 'id' => 'service_id' ]); + } + } diff --git a/console/migrations/m180522_094150_create_service_table.php b/console/migrations/m180522_094150_create_service_table.php new file mode 100644 index 0000000..871590f --- /dev/null +++ b/console/migrations/m180522_094150_create_service_table.php @@ -0,0 +1,42 @@ +createTable('service', [ + 'id' => $this->primaryKey(), + 'parent_id' => $this->integer(), + 'sort' => $this->integer(), + 'status' => $this->boolean(), + 'level' => $this->integer(), + 'created_at' => $this->integer(), + 'updated_at' => $this->integer() + ]); + + $this->addForeignKey('service_parent_fk', + 'service', + 'parent_id', + 'service', + 'id', + 'SET NULL', + 'CASCADE'); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropForeignKey('service_parent_fk', 'service'); + $this->dropTable('service'); + } +} diff --git a/console/migrations/m180522_094432_create_service_lang_table.php b/console/migrations/m180522_094432_create_service_lang_table.php new file mode 100644 index 0000000..534d841 --- /dev/null +++ b/console/migrations/m180522_094432_create_service_lang_table.php @@ -0,0 +1,59 @@ +createTable('service_lang', + [ + 'service_id'=> $this->integer(32)->notNull(), + 'language_id'=> $this->integer(32)->notNull(), + 'title'=> $this->string(255)->notNull(), + 'body'=> $this->text()->notNull(), + 'alias_id'=> $this->integer(), + 'PRIMARY KEY(service_id, language_id)', + ] + ); + + $this->addForeignKey('service_lang_service_fk', + 'service_lang', + 'service_id', + 'service', + 'id', + 'CASCADE', + 'CASCADE'); + $this->addForeignKey('service_lang_language_fk', + 'service_lang', + 'language_id', + 'language', + 'id', + 'CASCADE', + 'CASCADE'); + $this->addForeignKey('service_lang_alias_fk', + 'service_lang', + 'alias_id', + 'alias', + 'id', + 'SET NULL', + 'CASCADE'); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropForeignKey('service_lang_service_fk', 'service_lang'); + $this->dropForeignKey('service_lang_language_fk', 'service_lang'); + $this->dropForeignKey('service_lang_alias_fk', 'service_lang'); + $this->dropTable('service_lang'); + } +} -- libgit2 0.21.4