Missing notes for Laravel 4

Tutorial: Missing notes for Laravel 4

Note: This is an on-going blog. I’ll be updating it whenever I have new findings for Laravel 4.

I had been learning CodeIgniter and CakePHP for some time now when I chanced upon this new(er) framework called Laravel (http://laravel.com) via Twitter.

I’m not going to tell you how wonderful it is, but here’re some references:

There’s an official documentation and another one which is almost recommended everywhere I googled.

The thing is, the official documentation isn’t very complete. It covers most of the basics, but when you want to dig deeper, you’ll get lost. The other recommended tutorial site is almost outdated. I couldn’t find some of the things when I’m comparing it to the official documentation.

So I’m taking notes on the things that I’ve found out (either through googling or the official API documentation). Here we go:

1. Form::open_for_files() is outdated

If you’re trying to create a form for uploading files, the old way was to open the form with Form::open_for_files().

It isn’t clear in the official documentation or the API that we should now use the same Form::open() but now with an additional argument ‘file’ => true.

{{ Form::open(array('action' => 'UploadController@postImage','files'=>true)) }}

2. Using Input::file()

You must always set ‘files’ => true in the Form::open() otherwise Input::file() will never work.

3. Getting filename from Input::file()

There were many tutorials saying that the following will return the filename of the upload file. But it didn’t work for me.

$filename_neverwork_forme = Input::file('image.name');

Instead, use this to get the filename of the upload file.

$filename_worked = Input::file('image')->getClientOriginalName();

Of course, using the filename directly without verification is dangerous. But that’s up to you to decide.

4. Redirect with validation error message and inputs

I realize most methods with underscores are outdated.

So this is wrong:

return Redirect::to('form/create')->with_errors($validation)->with_input();

This is the correct method:

return Redirect::to('form/create')->withErrors($validation)->withInput();

5. Getting URL of a location using URL::to()

To get the full URL of any location or route, simply use URL::to().

For example, if you need the URL of the route ‘about’

{{ URL::to('about') }}

Note: Remember to set your route.php correctly. This function depends on that.

6. Checking current location with Request::is()

I needed to track the current location so that I can mark the corresponding navigation button as active. In this case, you can use Request::is().

Example

@if ( Request::is('about') )
    <li class='active'>
@else
    <li>
@endif
        <a href='{{ URL::to("about") }}'>About</a>
    </li>

 7. Get distinct values from a table column

I had a list of string from a table column that can be repeated. So I needed to query the database to give me an array of string which are distinct.

This is how you can do it:

DB::table('tableName')->select('columnName')->distinct()->get()

 8. Using Mail::send()

This is quite frustrating because the official documentation didn’t describe how to use the $data parameter which is required when using Mail::send().

Found this very good tutorial:

http://maxoffsky.com/code-blog/sending-e-mail-with-laravel-4-using-mail/

 9. Deploying your Laravel project to a shared hosting

Reference: http://stackoverflow.com/questions/16683046/how-to-install-laravel-4-to-a-web-host-subfolder-without-publicly-exposing-app

9.1 Look for your root or home directory

If you’re not sure where is your root or home directory, login to your shared hosting’s cpanel (control panel) and look for the Home Directory. It’s usually something like “/home/domainname”.

9.2 Create a new folder to host the protected Laravel files

We need to create a new folder in the root directory so that they’re not accessible to public. Under the root directory (e.g. /home/domainname/ or example.com), create a folder “applications”.

Under “applications”, create a folder with your project name (e.g. project_name) and place all your Laravel files (except the “public” folder) into this folder.

9.3 Public folder

Put all your files inside Laravel’s public folder into /home/domainname/public_html/project_name.

9.4 Final folder structure

The end result of the folder structure will look like this:

- /home/domainname
    - applications
        - project_name
            - app
            - bootstrap
            - vendor
            - artisan
            - composer.json
            - phpunit.xml
            - server.php
    - public_html
        - project_name

9.5 Edit Laravel’s /bootstrap/paths.php

I was very lost how many “../” I need to add in order to get to the correct path. So we won’t use __DIR__ at all. We’re going to define the full path base on the root directory so that there’s no confusion.

So change from this:

return array(
    'app'     => __DIR__.'/../app', 
    'public'  => __DIR__.'/../public',
    'base'    => __DIR__.'/..',
    'storage' => __DIR__.'/../app/storage',
);

To this:

return array(
    'app'     => '/home/domainname/applications/project_name/app', 
    'public'  => '/home/domainname/public_html/project_name',
    'base'    => '/home/domainname/applications/project_name',
    'storage' => '/home/domainname/applications/project_name/app/storage',
);

9.6 Edit Laravel’s /public/index.php

Same as the point above, we’re not going to use __DIR__. Let’s change all the path to full path.

From this:

require __DIR__.'/../bootstrap/autoload.php';
$app = require_once __DIR__.'/../bootstrap/start.php';

To this:

require '/home/domainname/applications/project_name/bootstrap/autoload.php'; 
$app = require_once '/home/domainname/applications/project_name/bootstrap/start.php';

9.7 Edit .htaccess

If your shared hosting’s default PHP version is < 5.3.7 but they support higher versions, you can edit the .htaccess file inside the “public” folder.

For Mac users, you can access it via the Terminal.

Use this command to go to the folder

cd your/laravel/path/public

Then list hidden files with this command

ls -a

You should see .htaccess there. By default, this file is protected. In order to change it, you need to open it using super user like this:

sudo open -e .htaccess

Note: -e means open with text editor.

Then append this line to the bottom and save it.

AddHandler application/x-httpd-php53 .php

Or if you want version 5.4

AddHandler application/x-httpd-php54 .php

Upload the updated .htaccess to the public_html/project_name folder and you’re done!

10. Returning view with Error message

When you need to return to a page with error messages (especially if you use validation), you can pass the error messages back to a view with this:

return Redirect::to('form')->withErrors($validation)->withInput();

However, if you need to return an error that is not captured in Laravel’s validation, for example, I needed to check if the reCAPTCHA returns a matching input, you can create a new MessageBag and return that error messages instead.

$errors = new IlluminateSupportMessageBag;
$errors->add('customError', "The reCAPTCHA wasn't entered correctly.");
return Redirect::to('form')->withErrors($errors)->withInput();

But what if you have both validation and custom message? This is how I’ll do it: first, check that validation has passed, if not, return with validation error messages. Then, check that, in my case, reCAPTCHA is matching, if not return that error message.

Example:

if( !$validation->passes() )
{
    return Redirect::to('form')->withErrors($validation)->withInput();
}

// CAPTCHA was entered incorrectly
if (!$reCaptcha->is_valid) {
    $errors = new IlluminateSupportMessageBag;
    $errors->add('reCaptcha', "The reCAPTCHA wasn't entered correctly.");
    return Redirect::to('form')->withErrors($errors)->withInput();
}

11.Creating a Package

Reference:

Important commands:

  1. To generate the class map of package:
    composer dump-autoload
  2. To move package’s assets into public/packages:
    php artisan asset:publish --bench="vendor/package"

12. Laravel requires Mcrypt PHP extension

If you’re using Mac like me, the default PHP installed on the Mac doesn’t insclude Mcrypt extension. I’m using MAMP for development and testing, so I followed this method and it worked for me.

Reference: http://stackoverflow.com/questions/16830405/laravel-requires-the-mcrypt-php-extension

Enter “which php” in terminal to see which PHP you are using.

which php

By default, Mac uses PHP from this path:

/usr/bin/php

If it’s not the PHP version from MAMP, you should edit or add .bash_profile under user root document (cd ~).

In .bash_profile, add following line (your MAMP version may be different, so does your PHP version. Check it up on the folder /Applications/MAMP/bin/php/):

export PATH=/Applications/MAMP/bin/php/php5.4.4/bin:$PATH

And restart Terminal to see which PHP you are using now. And it’ll be working by now.

13. Using lists for Form::select()

The shorter way to populate an array to be used in Form::select() is using query builder ‘lists’ to retrieve just the id column and a value column.

For example:

$select_array = Classname::lists('name', 'id');

Read the link below for more tips about this trick.

Laravel 4: Using query builder lists for Form::select


One Comments

Leave a Reply