Friday, April 29, 2016

AND-OR-AND + brackets with Eloquent-Laravel 5.1

AND-OR-AND + brackets with Eloquent-Laravel 5.1:

Eloquent is a great thing – you can build your query step-by-step and then call get() method. But sometimes it gets a little tricky for more complicated queries – for example, if you have multiple AND-OR conditions and you want to put brackets, how to do it properly?

Wrong way – easy to make mistake

Let’s say we need to filter male customers aged 18+ or female customers aged 65+ (whatever the reason is, it’s just a hypothetical example). Simple MySQL query would look something like this:

.... WHERE (gender = 'Male' and age >= 18) or (gender = 'Female' and age >= 65)
Now let’s transform it to Eloquent:

//............
$q->where('gender', 'Male');
$q->orWhere('age', '>=', 18);
$q->where('gender', 'Female');
$q->orWhere('age', '>=', 65);


But wait, if we launch it like that, MySQL query wouldn’t have any brackets and would be launches as this:


....WHERE gender = 'Male' and age >= 18 or gender = 'Female' and age >= 65
Which is wrong order – it would actually be executed in this order:


.....WHERE ((gender = 'Male' and age >= 18) or gender = 'Female') and age >= 65

The worst thing is that it wouldn’t throw any errors. And if you don’t test properly, you wouldn’t even notice that it filtered out wrong results.

Right way – putting “brackets” into Eloquent

What we actually need here is a thing called Advanced Where Clauses – where we can assign a function to a where clause, like this:

//......
$q->where(function ($query) use ($gender, $age) {
    $query->where('gender', $gender)
        ->where('age', '>=',  $age;
})->orWhere(function($query) use ($gender, $age) {
    $query->where('gender',  $gender)
        ->where('age', '>=',  $age);
})

This code will produce SQL query exactly like we need – with brackets in the right places.

Thanks.

Friday, April 15, 2016

How to generate random password in Laravel

How to generate random password in Laravel:

 This is a really really short one. I just needed to generate a random password for a user and noticed that Google doesn’t really give a one-line answer, which is really simple.

Firstly, how to generate random string – Laravel has a helper called str_random($length). In terms of saving hashed password to database, we use Hash::make($password).

So the end result for generating 8-symbol length password looks as simple as this:

$hashed_random_password = Hash::make(str_random(8));

Of course, don’t forget:
use Illuminate\Support\Facades\Hash;

Generated password can look like:

JnR390XB
2I2so1Wr
oVNBAic9

And hash is something like:

$2y$10$E1.y.jjmr7ecmMAiwFFQMO6KXn0scLB2hvVBbx8cny.lREZ6xdDMW
$2y$10$pVOI0me9sLPRbyQnxNQrDurSoJScsE6nvu6VVOsMDF8qusH7HUlo2
$2y$10$xVPUPgm1vpUTpZ8jAJE/Xeh7j8G8EFnlQYp27Zjy8qnabqessSc2i

That’s it for now, hope it’s a useful short tip.
Thanks.

Friday, April 8, 2016

Log every request & response in Laravel 5.1

Log every request & response in Laravel 5.1:

Sometimes it's useful to log some/all requests to your application. This is really convenient when you use Laravel to build your APIs.

A logging middleware might log all incoming requests to your application. In Laravel 5.1 there is a terminate method and it's call after the sending HTTP response to the browser. This way we have access to both $request and $response at the same time.

Let's take a look at how we are going to achieve this in Laravel 5.1:

Create a new middleware by type this command in terminal inside your project directory.

php artisan make:middleware LogAfterRequest

And then put below code in it(project_dir/app/Http/Middleware/LogAfterRequest.php).

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Log;

class LogAfterRequest {

    public function handle($request, Closure $next)
    {
        return $next($request);
    }

    public function terminate($request, $response)
    {
        Log::info('app.requests', ['request' => $request->all(), 'response' => $response]);
    }

}


In this code terminate method receives $request and $response. These are objects which will give you all of the handy stuffs you probably need to log.

When we have our middleware ready, we should add it to our HTTP Kernel.

Open Kernel.php and add this line to your protected $middleware property:

\App\Http\Middleware\LogAfterRequest::class

That's it. You can additionally filter what you want to actually log, but this is the basics.

Thanks.

Friday, April 1, 2016

Log every request & response in Laravel 5.1

Log every request & response in Laravel 5.1:


Today we will discuss about how to log every request & response in Laravel 5.1.

Sometimes it's useful to log some/all requests to your application. This is really convenient when you use Laravel to build your APIs.

A logging middleware might log all incoming requests to your application. In Laravel 5.1 there is a terminate method and it's call after the sending HTTP response to the browser. This way we have access to both $request and $response at the same time.

Let's take a look at how we are going to achieve this in Laravel 5.1:

Create a new middleware by type this command in terminal inside your project directory.

php artisan make:middleware LogAfterRequest

And then put below code in it(project_dir/app/Http/Middleware/LogAfterRequest.php).

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Log;

class LogAfterRequest {

    public function handle($request, Closure $next)
    {
        return $next($request);
    }

    public function terminate($request, $response)
    {
        Log::info('app.requests', ['request' => $request->all(), 'response' => $response]);
    }

}

In this code terminate method receives $request and $response. These are objects which will give you all of the handy stuffs you probably need to log.

When we have our middleware ready, we should add it to our HTTP Kernel.

Open Kernel.php and add this line to your protected $middleware property:

\App\Http\Middleware\LogAfterRequest::class

That's it. You can additionally filter what you want to actually log, but this is the basics.

Thanks.