Build Web Apps From Scratch With Laravel: Filters, Validations, and Files

In this Nettuts+ mini-series, we'll build a web application from scratch, while diving into a great new PHP framework that's rapidly picking up steam, called Laravel.

In this lesson, we'll be learning about some very useful Laravel features: filters, and both the validation and files libraries.


Review

Welcome back to our Web Applications from Scratch with Laravel series! In the second tutorial of our mini-series, we learned a lot about Laravel's ORM implementation:

  • Some background on “Models”
  • What the Eloquent ORM is
  • How to setup Laravel's database configuration
  • How to create your first Laravel Model
  • The basic functions of the Auth and Input libraries
  • Making use of the Eloquent ORM in a view

If you haven't seen it yet, I urge you to check out the first and second part of the mini-series — it will make it significantly easier to follow along, as we build our test application, Instapics, through each part.

So let's get started!


1 - Laravel Filters

In a nutshell, filters are functions that we can run on routes before or after the request cycle. It's especially useful for things like authentication and logging. To register a filter, we need to add something like the following to the application/routes.php file:

After we register the filter, we need to attach it to a route, like so:

In the example above, the myfilter will trigger on all request to the index page (i.e. /). Let's say we wanted to implement an authentication filter for the dashboard route:

The code above will redirect all unauthenticated requests to the dashboard route to the home route.

Global Filters

By default, Laravel includes two filters, before and after, which run before and after every request on an application. These are usually where you place things, like request logging, adding global assets or firing global events. For example:

This writes a request type log message to the application's log, and lists any input from the request.

Route Groups

If you find yourself applying the same filter to multiple routes, you can make use of Route Groups to group them all together and lessen code repetition:

Controller Filters

For applications (like our very own Instapics) that make use of controllers, we can apply filters by using the $this->filter() function in the controller's constructor:

These filters, like routes, can also be customized to apply only to certain HTTP verbs and specific controller actions:


2 - Laravel Validation

Laravel's built-in validation makes it easy to apply validation to any array of values, more specifically, form input. To do so, you simply need to build two arrays:

  • $input - this is an associative array of the values you want to validate.
  • $rules - this is an associative array (with keys which are the same as the $input array) that lists down the validation rules.

Validation Rules

Below is a list of validation rules which can be used with the Laravel validation library. Like in the example above, you are free to mix and match these by separating them with a pipe ("|"):

  • required - the value should be present in the input array

  • alpha - the value should only consist of alphabet characters

  • alpha_num - the value should only consist of alphanumeric characters

  • alpha_dash - the value should only consist of alphanumeric, dashes and/or underscores

  • size - the value should only be of a given length, or should be equal to if numeric

  • between - the value is inclusively between a specified range

  • min - the value is at least the given

  • max - the value is equal to or less than the given

  • numeric - the value is numeric

  • integer - the value is an integer

  • in - the value is contained in the given

  • not_in - the value is not in the given

  • confirmed - will check if the key_confirmation exists and is equal to the value

    This will check if the password_confirmation value exists and is equal to password

  • accepted - this will check if the value is set to 'yes' or 1. Useful for checkboxes

  • same - the value is the same as the given attribute's value

  • different - the value should be different from the given attribute's value

  • match - the value should match the given regular expression

  • unique - checks for uniqueness of the value in the given table.

    A given column is also accepted if the column name is not the same as the attribute name.

    There are times when we want to check for uniqueness, but ignore a certain record (usually the record associated with the current user). We can do this by adding a third given, which should be the ID of that record in the table.

  • exists - the value should exists in a table

    This also accepts a second given if we want to change the column name to check.

  • before - the value should be a date before the given date

  • after - the value should be a date after the given date

  • email - the value should be in a valid email format

  • url - the value is in a valid url format

  • active_url - the value is in a valid url format AND is active

  • mimes - checks for the mime-type of an uploaded file. You can use any mime-type value from the config/mimes.php file

  • image - the file should be an image

    You can also use the max validator here to check for a file's size in kilobytes


Error Handling

Once you call the Validator->fails() or Validator->passes() method, the library collects all of the errors in a class that's accessible via Validator->errors. You'll then be able to retrieve these errors with some functions in the errors class. Laravel provides some cool functionality to automate error handling that fits in most POST/REDIRECT/GET scenarios:

Here, we use the with_errors method for the Redirect library. This automatically binds the $errors variable in the view for wherever we're redirecting - in this case, the register/index page:

On the view file, we use the $errors->has() method to check if an error exists for that specifc field. If it does, we then use the $errors->get() method to display the error messages. The second parameter in this method can be used to provide a template on how we display the error message.

Custom Error Messages

Since most people would want to change the error messages for Laravel to fit their application's branding or language, the Validation library also allows for customizing the error messages that are generated by simply adding in a $messages array to the Validate::make function call:

There are two ways to create a $messages array:

  • Rule-based - you can provide a custom message for all the fields validated by a certain rule. For example:

    This will change the default error messages for all fields that have the required, same, size, between and in rules. In here, we also see that Laravel uses placeholders to replace certain values in the error message. :attribute will change into the field attribute (sans underscores) it's for. :other is used for the same rule, which refers to the other attribute it should match. :size refers to the defined size in the rule parameters. :min and :max is the minimum and maximum values, and :values is the list of values we specified that the field's value must be in.

  • Attribute-based - on the other hand, you can also provide a custom message for a specific attribute on a specific rule. Taking our example from above:

    email_required is the error message that's used when the email attribute fails the required rule, email_email is the error message that's used when the email fails the email rule, and so on.

If you find yourself consantly recreating the same custom messages though, it would be easier to just specify the custom error messages globally. You can do that by editing the application/langauge/en/validation.php file, and editing the custom array found there:


3 - Laravel Files

Handling File Uploads

Laravel's Files library makes it easy to handle file uploads by using the Input::upload method, which is a simple wrapper to the PHP's move_uploaded_file function:

To validate the file uploads, you can use the Validator library we discussed above like so:

File Manipulation

The Files library also has some file manipulation methods, like:

File-related functions

Laravel also provides some general purpose file-related functionalities that can be used throughout your code. For example, the File::extension method returns the extension of a string filename:

The File::is function checks if a file is of a certain type. Take note that this does not simply check the file's extension, but uses the Fileinfo PHP extension to read the actual contents of the file. This is useful for determining that a file is actually of a correct file type:

A list of compatible extensions can be seen in application/config/mimes.php.

Speaking of mime types, you can also use the File::mime function to get the mime types of an extension. The mime type returned is based on the same mimes.php file:

The File::cpdir and the File::rmdir methods can copy and delete a directory, respectively.

Now that we've learned all about Filters, the Validation library and the Files library, let's implement them in our application, Instapics.


Step 1 Create an auth Filter

Instapics

Add filters to Base_Controller

Let's start off by making sure our users are only able to see authenticated pages by creating an auth filter that runs before all requests. Since we use controller-based routing, we'll have to configure our filters in our controller. Let's put the filters in the __construct method of the Base_Controller to make sure the auth filter runs on all controllers which extends it. While we're at it, let's add a nonauth filter as well to make sure people can only visited certain pages when they're no authenticated:

Here we define that any requests to the home route will require non-authenticated user, which is good since this is where the login screen lies. Any other request though will default to requiring an authenticated user. For the User_Controller, we actually have two separate methods that require both non-authenticated users (authenticate) and authenticated users (logout), so we make use of the only method to specify which controller actions the filters apply to.

Create filter definitions in routes.php

Now, open application/routes.php, which is where we'll define the auth and nonauth filters. Take note that you might already have an existing auth filter definition so just replace it with the one we have below:

In the auth filter, we check if a user is authenticated with the Auth library. If the user is not authenticated, we redirect them back to the home route where the login screen is, otherwise, they are allowed to continue. The same thing with the nonauth filter - check if the user is authenticated, if he is, then redirect him to the dashboard.


Step 2 Implement User Uploads

Create photo upload form

Now that we know a little more about how to handle file uploads in Laravel, let's start implementing one of Instapics' main features — uploading photos. Begin by creating a folder called application/views/plugins folder, and inside this create a Blade view file named upload_modal.blade.php. Paste the following HTML:

Create the button trigger

Let's trigger this modal form with a button - add this into application/views/layouts/main.blade.php, after the .nav-collapse div:

Here, we include a view file called loggedin_postnav if the user is logged in. This is where we'll add the button for the modal upload form. In the same file, append this after the .container div:

This is where we include the upload_modal HTML. We make sure though that the user isn't logged in before including this HTML file, since like the button trigger, this wouldn't really be needed if the user isn't authenticated.

Now, create application/views/plugins/loggedin_postnav.blade.php

Refresh the page and you should see the new upload button - click it to see that it works!

Upload Instapic

Hook up the form to the appropriate controller

Now that we have our front-end stuff working, let's start working on the back-end portion of the form. Create application/controllers/photo.php, and put in the following code for the controller:

Try it out - you should be able to start uploading new Instapics.

Add validation to the upload form

Let's add some validation rules to this to make sure the user only submits the correct stuff. Update the controller with the following:

See how we validate the input? We make sure that the photo is present, an image and less than 500kb. We also make sure that the description is present after sanitation. We won't be able to see our error messages yet though, so let's fix that by adding some HTML to render our error messages. Open application/views/layouts/main.blade.php and add the following inside the .container div:

Now, create application/views/plugins/status.blade.php. This is where we'll render the actual error messages. We'll also add support for session-based status messages (like the one we use inside the $upload_success check on the Photos controller code):

Try causing errors on the upload form now by submitting without any file selected or without a description (since both are required). You should see the error messages being rendered on top:

Instapic Errors

Step 3 Add Validation to the Registration and Login Form

Now that we know how to use Laravel's Validation library, let's revisit our first form - the login and registration form. At the moment, we just use an echo to see that the login or registration failed — let's replace that with proper validation. Open application/controllers/user.php and update it like so:

Since we made our status message renderings in a modular fashion, we don't even need to write any additional HTML to see the error messages in action! Just try it out!

Instapic Errors

Conclusion

In the third tutorial in our Laravel series, we learned:

  • How, when and where to use Laravel Filters
  • How to use Laravel's Validation library, and how to handle the Validation library's errors.
  • How to manage files in Laravel using the Files library

Laravel comes with a lot of these small functions and libraries, that although implementable in other ways, is made easier and simpler (e.g. file uploads in a single line!) by adopting Laravel's expressive nature. It's these little time-saving libraries add up and over time, saves you a ton of wasted productivity rewriting code.

Next in our Web Applications from Scratch with Laravel series, we'll learn more about events, migrations and some advanced usage of the Eloquent ORM!

What do you think of the Laravel libraries discussed in the tutorial? Is it something that you find useful? Let me know in the comments! And, if you're a Tuts+ Premium member, stay tuned for our upcoming Laravel Essentials course!

Tags:

Comments

Related Articles