Making the user management interface

There is no need for us to make some custom user interface. Also, for simplicity, we will not bother with separating from ORM as we did in Chapter 2, Making a Custom Application with Yii 2. Thus, we can live with the interface automatically generated by Gii as described back in Chapter 3, Automatically Generating the CRUD Code. We will not list here the exact same steps as were described already, but will present a short outline before implementing features that are specific for users.

Acceptance tests for the user management interface

Similar to the services back in Chapter 3, Automatically Generating the CRUD Code, we need to be able to create, update, view, and delete users in the system.

Tip

As the acceptance tests for user management are going to be almost exactly the same as for services management, if you just follow the lessons in this book, you don't need to implement them. However, strictly speaking, in a real-world production environment you do need to implement them anyway. They are included in the code bundle relevant to this chapter.

The easiest way right now is to copy RegisterNewServiceCept.php, EditServiceCept.php, and DeleteServiceCept.php from the tests/acceptance directory to the RegisterNewUserCept.php, EditUserCept.php, and DeleteUserCept.php files in the same directory, respectively, and then replace all mentions of the following in method names, variable names, and strings:

  • services to users
  • Services to Users

By doing this, we get the reference to a nonexistent class AcceptanceTesterCRMUsersManagementSteps, which we create by copying the file tests/acceptance/_steps/CRMServicesManagementSteps.php to tests/acceptance/_steps/CRMUsersManagementSteps.php and replacing all mentions of Services by Users.

Note

Of course, it's blatant code duplication and it really needs to be refactored out, but you can take it as the home assignment, because you really can't escape at least some duplication in your highest level feature specifications for manipulating with entities in application, and it's outside the scope of this book to teach proper refactoring techniques. Just remember that you absolutely MUST get rid of this duplication.

The only functional difference in the specs for user management will be inside the CRMUsersManagementSteps class. After the proposed replacements, it mentions the UserRecord[name] string several times now. Our user record will not have the name field, but the username one. Then, you'll need to change UserRecord[name] to UserRecord[username]. We'll stick with the username field name because it's not the actual name of the real-world person behind this UserRecord, it's just the identifier it presents to our application.

Also, the imagineUser() method in the same class becomes as follows:

    function imagineUser()
    {
        $faker = FakerFactory::create();
        return [
            'UserRecord[username]' => $faker->userName,
            'UserRecord[password]' => md5(time())
        ];
    }

We will not bother with password hashes, as all data here is the user input, not what will be stored in the database. Note the way we generate a random password, although this way we can get only alphanumeric characters. We are doing this just for simplicity, as the password ideally should be a string containing any possible characters, including non-printing ones.

The PHP built-in function md5() was chosen only as an easy way to get a long stream of pseudorandom alphanumeric characters. You should not use a fast hashing algorithm to get a password hash. See this excellent answer if you're still not convinced: http://security.stackexchange.com/a/31846.

Database table to store user records

We need to prepare the table to hold our future user records. Here's the database migration you'll need to implement the schema displayed before:

    public function up()
    {
        $this->createTable(
            'user',
            [
                'id' => 'pk',
                'username' => 'string UNIQUE',
                'password' => 'string'
            ]
        );
    }

    public function down()
    {
        $this->dropTable('user'),
    }

Generating the model and CRUD code by Gii

Perform the same steps discussed in Chapter 3, Automatically Generating the CRUD Code. We will store the UserRecord model into the separate namespace appmodelsuser.

Field name

Field value

Model class

appmodelsuserUserRecord

Search Model class

appmodelsuserUserSearchModel

Controller class

appmodelsuserUsersController

Removing the password field from the autogenerated code

We will handle the password field automatically behind the scenes, but Gii doesn't know our intentions. You need to remove mentions of this field manually from the following places. Please note that we don't want to see passwords for any user records.

  • models/user/UserSearchModel.php: First, remove the password field from the safe rule inside the rules() method. Then, remove the following line from the search() method:
    $query->andFilterWhere(['like', 'password', $this->password])
  • views/user/_search.php: Remove the following line from the ActiveForm widget configuration:
    <?= $form->field($model, 'password') ?>
    
  • views/user/index.php: Remove the password field from the columns setting inside the GridView widget configuration.
  • views/user/view.php: Remove the password field from the attributes setting inside the DetailView widget configuration.

However, we do want to be able to enter and change the password for user records, so the input field for password in the views/user/_form.php view file should stay intact.

Now the interesting part begins: password should be hashed upon saving.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.216.75