Now we need to write a route that will have to listen to our post
request. For this, we open our routes.php
file under the app
folder and add the following code:
Route::post('/',function(){ //We first define the Form validation rule(s) $rules = array( 'link' => 'required|url' ); //Then we run the form validation $validation = Validator::make(Input::all(),$rules); //If validation fails, we return to the main page with an error info if($validation->fails()) { return Redirect::to('/') ->withInput() ->withErrors($validation); } else { //Now let's check if we already have the link in our database. If so, we get the first result $link = Link::where('url','=',Input::get('link')) ->first(); //If we have the URL saved in our database already, we provide that information back to view. if($link) { return Redirect::to('/') ->withInput() ->with('link',$link->hash); //Else we create a new unique URL } else { //First we create a new unique Hash do { $newHash = Str::random(6); } while(Link::where('hash','=',$newHash)->count() > 0); //Now we create a new database record Link::create(array('url' => Input::get('link'),'hash' => $newHash )); //And then we return the new shortened URL info to our action return Redirect::to('/') ->withInput() ->with('link',$newHash); } } });
Using the post
action function that we've coded now, we will be validating the user's input with the Laravel's built-in Validation
class. This class helps us prevent invalid inputs from getting into our database.
We first define a $rules
array to set the rules for each field. In our case, we want the link to have a valid URL format. Then we can run the form validation using the Validator::make()
method and assign it to the $validation
variable. Let's understand the parameters of the
Validator::make()
method:
The first parameter of the
Validator::make()
method takes an array of inputs and values to be validated. In our case, the whole form has only one field called link, so we've put theInput::all()
method, which returns all the inputs from the form.The second parameter takes the validation rules to be checked. The stored
$validation
variable holds some information for us. For example, we can check whether the validation has failed or passed (using$validation->fails()
and$validation->passes()
). These two methods return Boolean results, so we can easily check if the validation has passed or failed. Also, the$validation
variable holds a methodmessages()
, which contains the information of a failed validation. And we can catch them using$validation->messages()
.
If the form validation fails, we redirect the user back to our index page (return Redirect::to('/')
), which holds the URL shortener form, and we return some flash data back to the form. In Laravel, we do this by adding the withVariableName
object to the redirected page. Using with
is mandatory here, which will tell Laravel that we are returning something additional. We can do this for both redirecting and making views. If we are making views and showing some content to the end user, those withVariableName
will be variables, and we can call them directly using $VariableName
, but if we are redirecting to a page with the withVariableName
object, VariableName
will be a flash session data, and we can call it using the Session
class (Session::get('VariableName')
).
In our example, to return the errors, we used a special method withErrors($validation)
, instead of returning $validation->messages()
. We could also return using that, but the $errors
variable is always defined on views, so we can use our $validation
variable as a parameter with withErrors()
directly. The withInput()
method is also a special method, which will return the results back to the form.
//If validation fails, we return to the main page with an error info if($validation->fails()) { return Redirect::to('/') ->withInput() ->withErrors($validation); }
If the user forgets one field in the form, and if the validation fails and shows the form again with error messages, using the withInput()
method, the form can be filled with the old inputs again. To show these old inputs in Laravel, we use the old()
method of the Input
class. For example, Input::old('link')
will return us the old input of the form field named link
.
To return the error message back to the form, we can add the following HTML code into form.blade.php
:
@if(Session::has('errors')) <h3 class="error">{{$errors->first('link')}}</h3> @endif
As you can already guess, Session::has('variableName')
returns a Boolean value to check whether there is a variable name for the session. Then, with the first('formFieldName')
method of Laravel's Validator
class, we are returning the first error message of a form field. In our case, we are showing the first error message of our link
form field.