Sunday, 26 February 2017

Importance of Database Transaction in Laravel

Database Transaction comes into the picture when we have Sequential Operation with DB(mainly Update and Delete). A lot can happen in between transactions. So we should have system in place for the Rollback in case something bad happens.

Here is a simple code snippet for Manual use of Transaction.

DB::beginTransaction();
try {
    $user->save();
    $company->save();
    $department->save();

    //Commit to DB if all is well
    DB::commit();
} catch (Exception $ex) {
    //If you have mechanism to log or mail Exceptions
    Helper::logException($ex);

    //Rollback all previous transactions
    DB::rollBack();

    //Then we might want to redirect with some Error Message for the User
    return redirect()->route('form')->with('error', $errorMessages);
}

Luckily DB Facade controls both for Query Builder and Eloquent ORM.

Here is a simple code snippet for Automatic use of Transaction.

DB::transaction(function () {
    $user->save();
    $company->save();
    $department->save();
});

Here we don't need to manually Rollback. It does everything automatically. Only disadvantage I find of using it is we don't have control to fire email or show Error Message to the User.

Hope this helps.
Thanks
Debabrata

Send Mail on Exception in Laravel

When our application is in production, if we want to know exceptions then we will have to wait for the Customers to report it or we will have to check the Log file regularly. It would help a lot if we can know instantly when an exception happens. Well we can do that in Laravel. Even we can send an Email to the User about the Issue. Usually Customers happy when they know "Help is on the way".

There is a global Exception handler located at app/Exceptions/Handler.php. It has two functions report and render. In report we can send mail to the concerned Person(Developer) and to the Customer. In render we can redirect to an Error page.

Sometimes we don't want to perform this operation for some type of Exceptions. So we will have to filter out. Mine looks like this:

public function report(Exception $e)
{

//Don't fire mail in case of bad link
if (!($e instanceof NotFoundHttpException)) {
   HandlerService::sendMailOnException($e);
}

return parent::report($e);
}

public function render($request, Exception $e)
{
if($e instanceof NotFoundHttpException) {
   return response()->make(view('errors.404'), 404);
} elseif ($e instanceof ReflectionException) {
   return response()->make(view('errors.500'), 500);
}
return parent::render($request, $e);
}

Hope this helps.
Thanks

Monday, 20 February 2017

Usage of Middleware in Laravel

Mainly Middleware used for Authentication. For Creating and registering the Middleware please follow this link.

Let's suppose there is a third party API that needs access to our system. Then we can create a Middleware for it. So in the handle function of the Middleware we can have our own logic to authenticate.

So our Route will look something like this:

Route::group(['middleware' => ['web']], function () {
      Route::group(['middleware' => ['thirdPartyAPI']], function () {
         //Routes
      });
});

Here "web" Middleware is the wrapper of the "thirdPartyAPI" Middleware. So Routes will be filtered by Web and then by thirdPartyAPI.

Another common scenario is when we have Admin, Super Admin access in our system. So for this we can create a Middlewares for these as well. Have our own logic in Handle function.

So our Route will look something like this:

Route::group(['middleware' => ['web']], function () {
      Route::group(['middleware' => ['auth']], function () {
           Route::group(['middleware' => ['admin']], function () {
               //Routes
           });
      });
});

Here "auth" Middleware is for Session authentication. Admins have some special abilities in our system. So those abilities will go here.




Forcing Unique Rule to ignore a given value with additional conditions in Laravel

While checking for unique, sometimes we want to ignore a value. For example Email is unique in User Table. In Profile section if User saves the information without changing the Email then Validator returns an Error as it finds current email already exist. For this we need to tell the Validator to ignore a given value.

'email' => 'unique:user,email,'. $user_id

Here user = table, email = field, $user_id = Given value

If Soft-Delete is ON then we may need another condition

'email' => 'unique:user,email,'. $user_id. ',userId,deleted_at,NULL'

Here 4th parameter has to be the Auto-Increment Id of the Table. After that we can have Field-Value pairs. Here we have one, but we can multiple Field-value pairs like below:

'email' => 'unique:user,email,'. $user_id. ',userId,deleted_at,NULL,active,1'