PHP Tutorial Laravel 4 Framework (Authentication) - Creating User Account IV
Laravel 4
- Installing on Ubuntu - local
- Installing on a Shared host
- Installing on Windows
- Creating users table
- Home page with controller and blade
- Blade Templating
- Database connection and sending emails
- Creating user account I - GET
- Creating user account II - POST
- Creating user account III - Error checking & redirecting input
- Creating user account IV - User::create()
- Activating user account I - Mail::send()
- Activating user account II - Update user's status
- User account sign-in I - Route and link
- User account sign-in II - Validation
- User account sign-in III - Login Authentication
- Singing out
- Remember the user
- Changing Password I
- Changing Password II
- Recovering forgotten password I
- Recovering forgotten password II
- User Profile
- Database Migration using artisan
This tutorial is the continuation from Creating user account III - Error checking & redirecting input.
We want to do something when the submission is successful. Since we need to fill in database via Eloquent, we should setup the fillable property (in models/User.php file) to tell which attributes should be mass-assignable:
class User extends Eloquent implements UserInterface, RemindableInterface { /* Alowing Eloquent to insert data into our database */ protected $fillable = array('email', 'username', 'password', 'password_temp', 'code', 'active');
When we pass an array of data to the Model, the data is automatically mass assigned to the right columns. This is handy because it makes things a lot easier, but it also presents quite a serious security concern. For example, we may not want the a user to be able to change their user id as this should set automatically when the user is created and it should never change.
To protect against mass assignment, we need to specify which of the columns can be mass assigned. That's why we need to set the $fillable property.
Let's open AccountController.php:
<?php class AccountController extends BaseController { /* Viewing the form */ public function getCreate() { return View::make('account.create'); } /* Submitting the form */ public function postCreate() { $validator = Validator::make(Input::all(), array( 'email' => 'required|max:50|email|unique:users', 'username' => 'required|max:20|min:3|unique:users', 'password' => 'required|min:6', 'password_again'=> 'required|same:password' ) ); if($validator->fails()) { return Redirect::route('account-create') ->withErrors($validator) ->withInput(); // fills the field with the old inputs what were correct } else { // create an account $email = Input::get('email'); $username = Input::get('username'); $password = Input::get('password'); // Activation code $code = str_random(60); /* This does the same as User::create() $user = new User; $user->fill(array( 'email' => $email, 'username' => $username, 'password' => Hash::make($password), 'code' => $code, 'active' => 0, )); $userdata = $user->save(); */ // record $userdata = User::create(array( 'email' => $email, 'username' => $username, 'password' => Hash::make($password), 'code' => $code, 'active' => 0 )); if($userdata) { return Redirect::route('home') ->with('global', 'Your account has been created. We have sent you an email to activate your accout'); } } } }
The User::create() method does exactly the same as instantiating a new object, assigning the values, and calling the save method. The created object is returned, or false on failure.
Note: There was an error when we try to save the record (User::create()):
production.ERROR: exception 'Illuminate\Database\QueryException' with message 'SQLSTATE[HY000]: General error: 1364 Field 'password_temp' doesn't have a default value (SQL: insert into `users` (`email`, `username`, `password`, `code`, `active`, `updated_at`, `created_at`) values (jack@bogotobogo.com, jack, y$m6Vpjr8simWZ45EZMC8VcO78XptGwJqrsY5iZxecuTpIg10XfcS22, 4nAUMvTecsYILPoDsxGfLnHUIVoWU8vft0FUHrA1rgRtfA8g4ouYk1WRaen7, 0, 2014-05-03 08:25:55, 2014-05-03 08:25:55))' in C:\Apache2\htdocs\bogotobogo\Laravel\auth\vendor\laravel\framework\src\Illuminate\Database\Connection.php:555
Due to the error, I could not insert the new data. The fix was to set the default value for password_temp to NULL from None:
We're almost there. Let's add the following lines to main.blade.php:
<!DOCTYPE html> <html> <head> <title>Auth</title> </head> <body> @if(Session::has('global')) <p>{{ Session::get('global') }}</p> @endif @include('layout.navigation') @yield('content') </body> </html>
The Session::get('global') enables us to get the message from the global area.
Now, when we hit the "Create account"
our database will have a new record:
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization