From 5163f1a9a91062518ee4596dce6227b0ac0b7ec7 Mon Sep 17 00:00:00 2001 From: rocho Date: Sat, 19 Sep 2015 08:29:47 +0200 Subject: [PATCH 1/3] add user CRUD --- backend/components/AdminMenuStructure.php | 74 ++++++++++ backend/controllers/UserController.php | 132 ++++++++++++++++++ backend/models/UserCreate.php | 67 +++++++++ backend/models/UserSearch.php | 73 ++++++++++ backend/models/UserUpdate.php | 69 +++++++++ backend/views/layouts/main.php | 20 +-- backend/views/user/_form.php | 28 ++++ backend/views/user/_search.php | 35 +++++ backend/views/user/create.php | 21 +++ backend/views/user/index.php | 35 +++++ backend/views/user/update.php | 23 +++ backend/views/user/view.php | 38 +++++ common/config/main.php | 2 + common/models/User.php | 16 +++ .../m150828_200317_add_default_admin_user.php | 34 +++++ 15 files changed, 653 insertions(+), 14 deletions(-) create mode 100644 backend/components/AdminMenuStructure.php create mode 100644 backend/controllers/UserController.php create mode 100644 backend/models/UserCreate.php create mode 100644 backend/models/UserSearch.php create mode 100644 backend/models/UserUpdate.php create mode 100644 backend/views/user/_form.php create mode 100644 backend/views/user/_search.php create mode 100644 backend/views/user/create.php create mode 100644 backend/views/user/index.php create mode 100644 backend/views/user/update.php create mode 100644 backend/views/user/view.php create mode 100644 console/migrations/m150828_200317_add_default_admin_user.php diff --git a/backend/components/AdminMenuStructure.php b/backend/components/AdminMenuStructure.php new file mode 100644 index 0000000..505192e --- /dev/null +++ b/backend/components/AdminMenuStructure.php @@ -0,0 +1,74 @@ +menuItems = []; + } + + protected function can($authItem){ + $result = false; + if (\Yii::$app->user->can($authItem)) { + $result = true; + } + return $result; + } + + + + + + protected function addUserMainMenu(){ + + $userMainMenu = null; + $items = []; + + +// if ( $this->can('backend.user.index')){ + $items[] = ['label' => 'Felhasználók', 'url' =>['/user/index']]; +// } + + + if ( count($items) > 0 ){ + $userMainMenu = ['label' => 'Beállítások', 'url' => null, + 'items' => $items + ]; + } + + if ( isset($userMainMenu)){ + $this->menuItems[] = $userMainMenu; + } + + + } + + + protected function addLoginMainMenu(){ + if (Yii::$app->user->isGuest) { + $mainMenuItem= ['label' => 'Login', 'url' => ['/site/login']]; + } else { + $mainMenuItem= [ + 'label' => 'Kijelentkezés (' . Yii::$app->user->identity->username . ')', + 'url' => ['/site/logout'], + 'linkOptions' => ['data-method' => 'post'] + ]; + } + $this->menuItems[] = $mainMenuItem; + } + + + public function run(){ + $this->addUserMainMenu(); + $this->addLoginMainMenu(); + return $this->menuItems; + } + + +} \ No newline at end of file diff --git a/backend/controllers/UserController.php b/backend/controllers/UserController.php new file mode 100644 index 0000000..6fff26f --- /dev/null +++ b/backend/controllers/UserController.php @@ -0,0 +1,132 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['post'], + ], + ], + ]; + } + + /** + * Lists all User models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new UserSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ]); + } + + /** + * Displays a single User model. + * @param integer $id + * @return mixed + */ + public function actionView($id) + { + return $this->render('view', [ + 'model' => $this->findModel($id), + ]); + } + + /** + * Creates a new User model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new UserCreate(); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } else { + return $this->render('create', [ + 'model' => $model, + ]); + } + } + + /** + * Updates an existing User model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + */ + public function actionUpdate($id) + { + $model = UserUpdate::findOne(['id' => $id]); + + if ( $model == null ){ + throw new NotFoundHttpException('The requested page does not exist.'); + } + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } else { + return $this->render('update', [ + 'model' => $model, + ]); + } + } + + /** + * Deletes an existing User model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id + * @return mixed + */ + public function actionDelete($id) + { +// $this->findModel($id)->delete(); + + $user = $this->findModel($id); + + $user->updateAttributes(['status' => User::STATUS_DELETED]); + + return $this->redirect(['index']); + } + + /** + * Finds the User model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return User the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = User::findOne($id)) !== null) { + return $model; + } else { + throw new NotFoundHttpException('The requested page does not exist.'); + } + } +} diff --git a/backend/models/UserCreate.php b/backend/models/UserCreate.php new file mode 100644 index 0000000..2e59786 --- /dev/null +++ b/backend/models/UserCreate.php @@ -0,0 +1,67 @@ +6 ], + [['password_repeat'] ,'validatePasswordRepeat' ] + ]; + } + + public function validatePasswordRepeat($attribute,$params){ + + if ( !$this->hasErrors()){ + if ( $this->password_plain != $this->password_repeat ){ + $this->addError($attribute, Yii::t('app', 'Jelszó és jelszó újra nem egyezik!') ); + } + } + } + + public function attributeLabels(){ + return [ + + 'email' =>'E-mail', + 'username' =>'Felhasználónév', + 'created_at' =>'Létrehozás dátuma', + 'password_plain' => Yii::t('app','Jelszó'), + 'password_repeat' => Yii::t('app','Jelszó újra'), + + ]; + } + + public function beforeSave($insert){ + if ( parent::beforeSave($insert)){ + if ( $insert ){ + $this->setPassword($this->password_plain); + $this->generateAuthKey(); + return true; + } + }else{ + return false; + } + } + + public function afterSave($insert, $changedAttributes){ + parent::afterSave($insert, $changedAttributes); +// $am = Yii::$app->authManager; +// $role = $am->getRole('admin'); +// Yii::$app->authManager->assign($role, $this->id); + } + +} \ No newline at end of file diff --git a/backend/models/UserSearch.php b/backend/models/UserSearch.php new file mode 100644 index 0000000..553b9e0 --- /dev/null +++ b/backend/models/UserSearch.php @@ -0,0 +1,73 @@ + $query, + ]); + + $this->load($params); + + if (!$this->validate()) { + // uncomment the following line if you do not want to return any records when validation fails + // $query->where('0=1'); + return $dataProvider; + } + + $query->andFilterWhere([ + 'id' => $this->id, + 'status' => $this->status, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]); + + $query->andFilterWhere(['like', 'username', $this->username]) + ->andFilterWhere(['like', 'auth_key', $this->auth_key]) + ->andFilterWhere(['like', 'password_hash', $this->password_hash]) + ->andFilterWhere(['like', 'password_reset_token', $this->password_reset_token]) + ->andFilterWhere(['like', 'email', $this->email]); + + return $dataProvider; + } +} diff --git a/backend/models/UserUpdate.php b/backend/models/UserUpdate.php new file mode 100644 index 0000000..077d07a --- /dev/null +++ b/backend/models/UserUpdate.php @@ -0,0 +1,69 @@ + User::className(), 'targetAttribute' => 'email'], + ['username' ,'unique', 'targetClass' => User::className(), 'targetAttribute' => 'username'], + [['password_plain' ,'password_repeat'] ,'string','min' =>6 ], + [['password_repeat'] ,'validatePasswordRepeat' ] + ]; + } + /** + * @formatter:on + */ + public function validatePasswordRepeat($attribute, $params) { + if (! $this->hasErrors ()) { + if ( !empty($this->password_plain) || !empty($this->password_repeat) ){ + if ($this->password_plain != $this->password_repeat) { + $this->addError ( $attribute, Yii::t ( 'app', 'Jelszó és jelszó újra nem egyezik!' ) ); + } + } + } + } + public function attributeLabels() { + return [ + + 'email' => 'E-mail', + 'username' => 'Felhasználónév', + 'created_at' => 'Létrehozás dátuma', + 'password_plain' => Yii::t ( 'app', 'Jelszó' ), + 'password_repeat' => Yii::t ( 'app', 'Jelszó újra' ) + ] + ; + } + public function beforeSave($insert) { + if (parent::beforeSave ( $insert )) { + if (! $insert) { + if ( !empty( $this->password_plain ) ) { + $this->setPassword($this->password_plain); + return true; + } + } + return true; + } else { + return false; + } + } + public function afterSave($insert, $changedAttributes) { + parent::afterSave ( $insert, $changedAttributes ); + // $am = Yii::$app->authManager; + // $role = $am->getRole('admin'); + // Yii::$app->authManager->assign($role, $this->id); + } +} \ No newline at end of file diff --git a/backend/views/layouts/main.php b/backend/views/layouts/main.php index d5ded73..a466606 100644 --- a/backend/views/layouts/main.php +++ b/backend/views/layouts/main.php @@ -9,8 +9,12 @@ use yii\bootstrap\Nav; use yii\bootstrap\NavBar; use yii\widgets\Breadcrumbs; use common\widgets\Alert; +use backend\components\AdminMenuStructure; AppAsset::register($this); + +$adminMenu = new AdminMenuStructure(); +$items = $adminMenu->run(); ?> beginPage() ?> @@ -28,27 +32,15 @@ AppAsset::register($this);
'My Company', + 'brandLabel' => 'Botond Fitness WebAdmin', 'brandUrl' => Yii::$app->homeUrl, 'options' => [ 'class' => 'navbar-inverse navbar-fixed-top', ], ]); - $menuItems = [ - ['label' => 'Home', 'url' => ['/site/index']], - ]; - if (Yii::$app->user->isGuest) { - $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']]; - } else { - $menuItems[] = [ - 'label' => 'Logout (' . Yii::$app->user->identity->username . ')', - 'url' => ['/site/logout'], - 'linkOptions' => ['data-method' => 'post'] - ]; - } echo Nav::widget([ 'options' => ['class' => 'navbar-nav navbar-right'], - 'items' => $menuItems, + 'items' => $items, ]); NavBar::end(); ?> diff --git a/backend/views/user/_form.php b/backend/views/user/_form.php new file mode 100644 index 0000000..e31eb2b --- /dev/null +++ b/backend/views/user/_form.php @@ -0,0 +1,28 @@ + + +
+ + + + + + field($model, 'username')->textInput() ?> + field($model, 'email')->textInput() ?> + field($model, 'password_plain')->passwordInput() ?> + field($model, 'password_repeat')->passwordInput() ?> + +
+ isNewRecord ? Yii::t('app', 'Mentés') : Yii::t('app', 'Mentés'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> +
+ + + +
diff --git a/backend/views/user/_search.php b/backend/views/user/_search.php new file mode 100644 index 0000000..77b0399 --- /dev/null +++ b/backend/views/user/_search.php @@ -0,0 +1,35 @@ + + +
+
+ +
+
+ +
+
\ No newline at end of file diff --git a/backend/views/user/create.php b/backend/views/user/create.php new file mode 100644 index 0000000..04a8d93 --- /dev/null +++ b/backend/views/user/create.php @@ -0,0 +1,21 @@ +title = Yii::t('app', 'Új felhasználó'); +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Felhasználók'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/views/user/index.php b/backend/views/user/index.php new file mode 100644 index 0000000..30e1329 --- /dev/null +++ b/backend/views/user/index.php @@ -0,0 +1,35 @@ +title = Yii::t('app', 'Felhasználók'); +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

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

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

+ + $dataProvider, + 'columns' => [ + ['class' => 'yii\grid\SerialColumn'], + + 'username', + 'email:email', + 'created_at:datetime', + + ['class' => 'yii\grid\ActionColumn'], + ], + ]); ?> + +
diff --git a/backend/views/user/update.php b/backend/views/user/update.php new file mode 100644 index 0000000..2e03759 --- /dev/null +++ b/backend/views/user/update.php @@ -0,0 +1,23 @@ +title = Yii::t('app', 'Update {modelClass}: ', [ + 'modelClass' => 'User', +]) . ' ' . $model->id; +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Users'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = Yii::t('app', 'Update'); +?> +
+ +

title) ?>

+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/views/user/view.php b/backend/views/user/view.php new file mode 100644 index 0000000..f5494f3 --- /dev/null +++ b/backend/views/user/view.php @@ -0,0 +1,38 @@ +title = $model->id; +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Felhasználók'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ +

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

+ + $model, + 'attributes' => [ + 'username', + 'email:email', + 'statusHuman', + 'created_at:datetime', + ], + ]) ?> + +
diff --git a/common/config/main.php b/common/config/main.php index c9071d1..de8ff7c 100644 --- a/common/config/main.php +++ b/common/config/main.php @@ -1,6 +1,8 @@ dirname(dirname(__DIR__)) . '/vendor', +// 'language' => 'hu-HU', + 'language' => 'hu', 'components' => [ 'cache' => [ 'class' => 'yii\caching\FileCache', diff --git a/common/models/User.php b/common/models/User.php index ce78fcd..2ab5921 100644 --- a/common/models/User.php +++ b/common/models/User.php @@ -185,4 +185,20 @@ class User extends ActiveRecord implements IdentityInterface { $this->password_reset_token = null; } + + static function statuses() { + return [ + self::STATUS_ACTIVE => Yii::t('app', 'Aktív'), + self::STATUS_DELETED => Yii::t('app', 'Inaktív'), + ] ; + } + + public function getStatusHuman(){ + $result = null; + $s = self::statuses($this->status); + if ( array_key_exists($this->status, $s)){ + $result = $s[$this->status]; + } + return $result; + } } diff --git a/console/migrations/m150828_200317_add_default_admin_user.php b/console/migrations/m150828_200317_add_default_admin_user.php new file mode 100644 index 0000000..7555455 --- /dev/null +++ b/console/migrations/m150828_200317_add_default_admin_user.php @@ -0,0 +1,34 @@ +username = "admin"; + $user->email = "admin@rocho-net.hu"; + $user->setPassword("test"); + $user->generateAuthKey(); + $user->save(); + } + + public function down() + { + } + + /* + // Use safeUp/safeDown to run migration code within a transaction + public function safeUp() + { + } + + public function safeDown() + { + } + */ +} From fd181e580f82863e46a39552721d63a2a2c90db1 Mon Sep 17 00:00:00 2001 From: rocho Date: Sat, 19 Sep 2015 08:57:45 +0200 Subject: [PATCH 2/3] add i18n --- backend/views/user/_form.php | 1 - common/config/i18n.php | 81 +++++++++++++++++++++++++++++++++++ common/config/main.php | 8 ++++ common/messages/hu/app.php | 34 +++++++++++++++ common/messages/hu/common.php | 21 +++++++++ 5 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 common/config/i18n.php create mode 100644 common/messages/hu/app.php create mode 100644 common/messages/hu/common.php diff --git a/backend/views/user/_form.php b/backend/views/user/_form.php index e31eb2b..fd35256 100644 --- a/backend/views/user/_form.php +++ b/backend/views/user/_form.php @@ -12,7 +12,6 @@ use yii\widgets\ActiveForm; - field($model, 'username')->textInput() ?> field($model, 'email')->textInput() ?> diff --git a/common/config/i18n.php b/common/config/i18n.php new file mode 100644 index 0000000..df77983 --- /dev/null +++ b/common/config/i18n.php @@ -0,0 +1,81 @@ + __DIR__. '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR, + // array, required, list of language codes that the extracted messages + // should be translated to. For example, ['zh-CN', 'de']. + 'languages' => ['hu'], + // string, the name of the function for translating messages. + // Defaults to 'Yii::t'. This is used as a mark to find the messages to be + // translated. You may use a string for single function name or an array for + // multiple function names. + 'translator' => 'Yii::t', + // boolean, whether to sort messages by keys when merging new messages + // with the existing ones. Defaults to false, which means the new (untranslated) + // messages will be separated from the old (translated) ones. + 'sort' => false, + // boolean, whether to remove messages that no longer appear in the source code. + // Defaults to false, which means each of these messages will be enclosed with a pair of '@@' marks. + 'removeUnused' => false, + // array, list of patterns that specify which files (not directories) should be processed. + // If empty or not set, all files will be processed. + // Please refer to "except" for details about the patterns. + 'only' => ['*.php'], + // array, list of patterns that specify which files/directories should NOT be processed. + // If empty or not set, all files/directories will be processed. + // A path matches a pattern if it contains the pattern string at its end. For example, + // '/a/b' will match all files and directories ending with '/a/b'; + // the '*.svn' will match all files and directories whose name ends with '.svn'. + // and the '.svn' will match all files and directories named exactly '.svn'. + // Note, the '/' characters in a pattern matches both '/' and '\'. + // See helpers/FileHelper::findFiles() description for more details on pattern matching rules. + // If a file/directory matches both a pattern in "only" and "except", it will NOT be processed. + 'except' => [ + '.svn', + '.git', + '.gitignore', + '.gitkeep', + '.hgignore', + '.hgkeep', + '/messages', + ], + + // 'php' output format is for saving messages to php files. + 'format' => 'php', + // Root directory containing message translations. + 'messagePath' => __DIR__ . DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR . 'messages', + // boolean, whether the message file should be overwritten with the merged messages + 'overwrite' => true, + + // Message categories to ignore + 'ignoreCategories' => [ + 'yii', + ], + + /* + // 'db' output format is for saving messages to database. + 'format' => 'db', + // Connection component to use. Optional. + 'db' => 'db', + // Custom source message table. Optional. + // 'sourceMessageTable' => '{{%source_message}}', + // Custom name for translation message table. Optional. + // 'messageTable' => '{{%message}}', + */ + + /* + // 'po' output format is for saving messages to gettext po files. + 'format' => 'po', + // Root directory containing message translations. + 'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . 'messages', + // Name of the file that will be used for translations. + 'catalog' => 'messages', + // boolean, whether the message file should be overwritten with the merged messages + 'overwrite' => true, + */ +]; diff --git a/common/config/main.php b/common/config/main.php index de8ff7c..be6a945 100644 --- a/common/config/main.php +++ b/common/config/main.php @@ -7,5 +7,13 @@ return [ 'cache' => [ 'class' => 'yii\caching\FileCache', ], + 'i18n' => [ + 'translations' => [ + '*' => [ + 'class' => 'yii\i18n\PhpMessageSource', + 'basePath' => '@common/messages', + ], + ], + ], ], ]; diff --git a/common/messages/hu/app.php b/common/messages/hu/app.php new file mode 100644 index 0000000..7fde174 --- /dev/null +++ b/common/messages/hu/app.php @@ -0,0 +1,34 @@ + '', + 'Are you sure you want to delete this item?' => '', + 'Delete' => '', + 'Felhasználók' => '', + 'Inaktív' => '', + 'Jelszó' => '', + 'Jelszó és jelszó újra nem egyezik!' => '', + 'Jelszó újra' => '', + 'Keresés' => '', + 'Mentés' => '', + 'Update' => '', + 'Update {modelClass}: ' => '', + 'Users' => '', + 'Új felhasználó' => '', +]; diff --git a/common/messages/hu/common.php b/common/messages/hu/common.php new file mode 100644 index 0000000..565f9e5 --- /dev/null +++ b/common/messages/hu/common.php @@ -0,0 +1,21 @@ + 'Mentés', +]; From 7a48ac9d5186afa49c94ff7aea4e4568400b92ad Mon Sep 17 00:00:00 2001 From: rocho Date: Sat, 19 Sep 2015 16:07:52 +0200 Subject: [PATCH 3/3] finish feature #26 --- backend/controllers/UserController.php | 1 - backend/models/UserSearch.php | 4 ++++ common/models/User.php | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/backend/controllers/UserController.php b/backend/controllers/UserController.php index 6fff26f..88a61e5 100644 --- a/backend/controllers/UserController.php +++ b/backend/controllers/UserController.php @@ -105,7 +105,6 @@ class UserController extends Controller */ public function actionDelete($id) { -// $this->findModel($id)->delete(); $user = $this->findModel($id); diff --git a/backend/models/UserSearch.php b/backend/models/UserSearch.php index 553b9e0..bbf528d 100644 --- a/backend/models/UserSearch.php +++ b/backend/models/UserSearch.php @@ -46,6 +46,8 @@ class UserSearch extends User $dataProvider = new ActiveDataProvider([ 'query' => $query, ]); + + $query->andWhere(['status' => User::STATUS_ACTIVE]); $this->load($params); @@ -54,6 +56,8 @@ class UserSearch extends User // $query->where('0=1'); return $dataProvider; } + + $query->andFilterWhere([ 'id' => $this->id, diff --git a/common/models/User.php b/common/models/User.php index 2ab5921..dce1b33 100644 --- a/common/models/User.php +++ b/common/models/User.php @@ -201,4 +201,12 @@ class User extends ActiveRecord implements IdentityInterface } return $result; } + + + public function attributeLabels(){ + return [ + + ]; + } + }