Automatically create users from records
I was recently working on a rental property maintenance management system. The system allows tenants to submit maintenance requests, and the property manager can assign these requests to technicians for resolution. Each technician has a user account in the system, and the property manager is responsible for creating these accounts manually.
To simplify the process, I decided to automatically create a user account for each technician when a new record is added to the technicians
table.
This way, the property manager can simply add a new technician record, and the system will automatically create a user account for them.
This article explains how I achieved this using AppGini’s hooks., a powerful way to extend the functionality of your AppGini application.
Overview of the workflow
Here’s an overview of the workflow we’ll implement:
- To add a new technician, the property manager will add a new record to the
technicians
table.- This new record includes the technician’s name, email, desired username, and other details.
- After saving the new record, the system will automatically create a new user account for the technician.
- The account would belong to the
Technicians
group and have a random password. - The technician will need to reset their password when they first log in.
- The account would belong to the
- The
username
field in thetechnicians
table will become read-only to prevent accidental changes to the username.
For reference, here is the technicians detail view form:
Creating user accounts automatically
To make this tutorial as generic as possible, I’ve created a generic addUserToGroup()
function that you can be used in any AppGini project to add a user to a group. This function
should be added to hooks/__global.php
or hooks/__bootstrap.php
file.
This makes it available to all hooks in your project.
|
|
Here is how the above function works:
- It checks if the given user is a member of the given group.
- If the user doesn’t exist, it creates a new user account and adds it to the group.
- If the user exists but is not a member of the group, it sets an error message in the
$error
variable and aborts. - If the user exists and is already a member of the group, it returns true.
Note that $error
is passed by reference, so you can check its value after calling the function to see if an error occurred.
Implementing the workflow
To implement the workflow, we’ll customize several technicians
table hooks. These hooks
exist in the hooks/technicians.php
file.
technicians_before_insert
hook
This hook runs before a new record is inserted into the technicians
table. We’ll use it to create a new user account for the technician.
If the specified username already exists, the hook will abort and display an error message, preventing the record from being saved.
|
|
The above code does the following:
- It sanitizes the username field to allow only alphanumeric characters, underscores, and dots, and converts it to lowercase.
- It calls the
addUserToGroup()
function to create a new user account for the technician in theTechnicians
group. - If the function returns false, the hook sets an error message in the
$args['error_message']
variable and aborts.The
$args['error_message']
variable is used to display an error message to the user letting them know why the record couldn’t be saved. - If the function returns true, the insert operation continues.
technicians_after_insert
hook
This hook runs after a new record is inserted into the technicians
table. We’ll use it to set the owner of the new record to the newly created user account.
This way, the technician can log in and view their record, and the property manager can assign maintenance requests to them.
|
|
The above code does the following:
- It calls the
set_record_owner()
function to set the owner of the new record to the specified username.$data['selectedID']
contains the ID of the newly inserted record. - It displays a message informing the user (the property manager) that the username has been associated with the technician.
The
WindowMessages::add()
function is used to display a message to the user, applying thealert alert-success
CSS class to style the message. - It returns false to prevent the default ownership insert operation.
This is necessary because otherwise, the current user would be set as the owner of the new record, which is not what we want.
technicians_dv
hook
This hook runs when the detail view of a technicians
table record is displayed.
We’ll use it to make the username
field read-only to prevent accidental changes to the username.
|
|
The above code does the following:
- It checks if the record is not new and the logged member can edit the record.
- If the above conditions are met, it adds a JavaScript snippet to the detail view form to set the
username
field to read-only.
This way, the username field will be editable only when adding a new technician record, and read-only when viewing an existing record.
But since the above code only makes the field read-only on the client-side, it’s a good idea to also make the field read-only on the server-side. Otherwise, a malicious user could bypass the client-side restriction and change the username field.
To do this, we’ll need to enforce the read-only restriction in the technicians_before_update
hook.
technicians_before_update
hook
This hook runs before an existing record in the technicians
table is updated. We’ll use it to enforce the read-only restriction on the username
field.
|
|
The above code does one thing: it sets the username
field to its old value, effectively preventing the field from being updated.
The old value is available in the $args['old_data']['username']
variable.
Previewing the workflow
After implementing the above hooks, here is a video preview of the entire workflow:
Using the above code in your project
To use the above code in your project, just add the addUserToGroup()
function to your hooks/__global.php
or hooks/__bootstrap.php
file.
There is no need to modify the function as it’s generic and can be used as is.
Then, customize the relevant table hooks adding the code snippets provided above. Replace technicians
with the name of the actual table you’re working with.
And replace Technicians
with the name of the group you want to add the user to. You can actually have multiple tables associated with different groups.
For example, you can have a technicians
table associated with the Technicians
group and a tenants
table associated with the Tenants
group.
That’s it! You’ve now automated the process of creating user accounts from records in your AppGini application. Happy coding!