laravel-localization

Laravel localization and multi-language functionality in web

MAKE USE OF LARAVEL FEATURES AND BEST PACKAGES FOR LOCALIZATION

Laravel localization and multi-language functionality in web

A step by step guide to implement multi-language functionality in your web projects

Laravel made it so easy to implement a multi-language website. You can implement it with Laravel localization and just some tricks. Also, there is plenty of Laravel translation packages which you can use in your project. In this post, I will explain how to implement multi-language functionality.

Creating a multi-language website requires two steps. Firstly, you need to detect user local language setting and change it bu user choice. Secondly, you need to translate messages and strings into user local language, in which we use Laravel localization.

DETECTING AND SETTING USER LOCALE

In order to detect user language setting, we need to create a language middleware. this middleware checks for locale setting in the user session. If there was no locale setting, the middleware sets a default locale setting. Then, it sets system locale by the user session setting.

if (is_null(session('locale'))) {
    session(['locale'=> "en"]);
}
app()->setLocale(session('locale'));

Setting locale is enough for Laravel localization to work. After that, we need a simple function To change the system language. This function gets a locale string and sets the user locale session.

public function change_lang($lang) {
    if (in_array($lang,['en','tr','fa'])) {
        session(['locale'=> $lang]);
    }
    return back();
}

In order to make sure the given string is a locale string, we check the language string against an array of locales.

Any route to that function, like a drop down to select language will work perfectly and will show your website multi-language functionality for users. So they can easily choose their languages.

Using Laravel localization to translate strings

Every string that needed to be translated must be in Laravel lang directive or __ function. For example, you can manage all message strings with inside messages.

@lang('messages.successful_login')

In addition, you can find more useful information about localization like how to put variables inside translation strings in Laravel documentation.

Laravel Langman package is one of the useful packages for translation. In order to translate strings, every time you updated views with new strings, you just need to run Langman sync command:
php artisan langman:sync

Laravel Langman has a lot more commands that would help you in your Laravel project localization. Reading through its documentation will add a lot.

Although this method is easy and enough, I realized that for SEO purposes and to share localized links to your website, you better consider concatenating user locale in your projects routes. Then, you can check user locale from the query string and the rest is just as same as I explained in this post.

Keep in touch and share your ideas about Laravel localization and how you implement multi-language functionality in your web projects. What other methods and Laravel packages do you use in your multi-language projects?

Also, you can read my other post about Laravel authorization and user’s permission management in Laravel.

If you find this multi-language functionality method useful in Laravel and you may want to implement this on your Laravel projects, share your ideas with me. Follow me on Twitter, Let’s connect on LinkedIn and give me a visit to amiryousefi.com

Laravel authorization and roles permission management

EASY AND FLEXIBLE USERS PERMISSIONS MANAGEMENT

Laravel authorization and roles permission management

a simple guide for a flexible authentication and authorization

Inmany web projects, we have different user roles interacting with the system. Each role has its own permission. Every feature of the system can be enabled or disabled for these roles. We can define users permissions in our codes and check if they are authorized to do the requested action or not. A better way, mostly in more flexible systems, is to create a role and authorization management system. I’ll explain how to implement a Laravel authorization system and define users permission based on their roles.

In this post, firstly we manage users in groups we called roles. Every role has different permissions. In order to avoid permissions conflict, we assume each user has only one role. Secondly, Laravel authorization implemented by middleware. This middleware checks for the user’s role permission and authorizes user requests.

CREATING ROLES AND PERMISSIONS

In order to implement Laravel authorization, we will create roles and permissions table. To assign a role for users, we create a roles table. The migration for roles table is as simple as this:

Schema::create(‘roles’, function (Blueprint $table) {
    $table->increments(‘id’);
    $table->string(‘name’);
    $table->string(‘description’)->nullable();
    $table->timestamps();
});

We have an ID and name for roles. All users will be managed in these roles. There is also a description field, because you may need a short note on roles to describe each role for yourself.

After that, we add a foreign key, role_id, in the user table. Adding this field to the default user model helps us for Laravel authorization.

$table->unsignedInteger(‘role_id’)->index();
$table->foreign(‘role_id’)->references(‘id’)->on(‘roles’);

Now let’s talk about the permissions table. Every request leads to a method of a controller. So we store a list of all methods and their controller’s name in the permissions table. Later, we explain how we gather this list and how we check users authorization in Laravel by this permissions table.

Schema::create(‘permissions’, function (Blueprint $table) {
    $table->increments(‘id’);
    $table->string(‘name’)->nullable();
    $table->string(‘key’)->nullable();
    $table->string(‘controller’);
    $table->string(‘method’);
    $table->timestamps();
});

Finally, a relationship created between roles and permission.

Schema::create(‘permission_role’, function (Blueprint $table) {
    $table->unsignedInteger(‘permission_id’);
    $table->unsignedInteger(‘role_id’);$table->foreign(‘permission_id’)
        ->references(‘id’)
        ->on(‘permissions’)
        ->onDelete(‘cascade’);$table->foreign(‘role_id’)
        ->references(‘id’)
        ->on(‘roles’)
        ->onDelete(‘cascade’);$table->primary([‘permission_id’, ‘role_id’]);
});

We created a complete users->roles->permissions architecture. After that, an access list will be stored in these tables. So, we can easily implement Laravel authorization by checking requests against this list.

Read Laravel migration documentation for further information about creating tables.

CREATING AN ACCESS LIST FOR USER PERMISSIONS

The whole purpose of this post is about being dynamic. Especially, in systems with a different type of roles. We need to create a list of permissions in the system. Also, this list must be updated as the system developed. List of controllers and methods is a good representation of all permissions in the system. Every route is leading to a method of a controller. So, it’s a good idea to make a list of permissions using the routes list.

In order to do that, I used a Laravel database seeder. Firstly, let’s write a role seeder. It creates basic roles we need and stores them in the roles table. Running this artisan command will create RolesSeeder for you:

php artisan make:seeder RolesTableSeeder

Inside this RolesTableSeeder, we create our basic roles:

DB::table(‘roles’)->insert([
    [‘name’ => ‘admin’],
    [‘name’ => ‘operator’],
    [‘name’ => ‘customer’],
]);

You can add as many roles as you need. Also, you can create new roles from your website whenever you need a new one.

The second step is to create an authorization list for each role. we create another Laravel seeder in which populate permissions table:

php artisan make:seeder PermissionTableSeeder

Firstly, we get all routes list. Then, We check up with the database if the permission already stored. After that, if this permission is not in the table already, we insert new permissions in the permissions table. After all, we attach all permissions to the admin role.

$permission_ids = []; // an empty array of stored permission IDs
// iterate though all routes
foreach (Route::getRoutes()->getRoutes() as $key => $route) {
    // get route action
    $action = $route->getActionname(); // separating controller and method
    $_action = explode(‘@’, $action);

    $controller = $_action[0];
    $method = end($_action);

    // check if this permission is already exists
    $permission_check = Permission::where(
        [‘controller’ => $controller, ’method’ => $method]
    )->first();
    if (!$permission_check) {
        $permission = new Permission;
        $permission->controller = $controller;
        $permission->method = $method;
        $permission->save();

        // add stored permission id in array
        $permission_ids[] = $permission->id;
    }
} // find admin role.
$admin_role = Role::where(‘name’, ’admin’)->first(); // atache all permissions to admin role
$admin_role->permissions()->attach($permission_ids);

LARAVEL AUTHORIZATION USING MIDDLEWARE

Every request in Laravel goes through middleware. Knowing that creating RolesAuth middleware will do Laravel authorization. You can create the middleware manually or by an artisan command:

php artisan make:middleware RolesAuth

Inside this middleware, we get all permissions for logged in user. Then, we check if the requested action is in the permissions list. If requested action can’t be found in permissions list, a 403 error response returns.

// get user role permissions
$role = Role::findOrFail(auth()->user()->role_id);
$permissions = $role->permissions; // get requested action
$actionName = class_basename($request->route()->getActionname()); // check if requested action is in permissions list
foreach ($permissions as $permission) {
    $_namespaces_chunks = explode(‘\’, $permission->controller);
    $controller = end($_namespaces_chunks);
    if ($actionName == $controller . ‘@’ . $permission->method) {
        // authorized request
        return $next($request);
    }
} // none authorized request
return response(‘Unauthorized Action’, 403);

Finally, you can register this middleware in Laravel and use it according to your requirements.

I started publishing my experience about Laravel development, here you can see my post about Laravel localization. Comment your questions about this post or any other Laravel development questions in this area.

Update 2020:
Now you can use my Laravel permission package build based this article. It just got better, cleaner, and easier to understand.
https://github.com/amiryousefi/laravel-permission