Skip to content
This repository has been archived by the owner on Dec 8, 2020. It is now read-only.

How we ported to Laravel

wcd-will edited this page Jun 1, 2018 · 6 revisions

Objectives:

Our objective throughout this process was to make as little as possible changes to the existing build, so that it behaved in the same way as the original. Compared to a normal PHP build the transition to Laravel was a smoother since the project already had an MVC (Model, View, Controller) architecture. Overall, it needed to be the same product just with a few performance and visual tweaks.

General Approach:

Firstly we decided to get a feel for how the product functioned already by navigating our way through the community demo that was supplied to us. Then the task was to recreate this experience in Laravel. Laravel boasts a bunch of performance benefits as well an abundance of built-in functions that help with both programming the site and reading the code. To take on such a massive build we split it up into a number of sections that are listed below.

Migrations:

The build already had some migrations of its own but all were in raw SQL. Laravel has its own built-in module that handles all the stuff to do with Databases which is called Eloquent. Previous migrations were translated to Eloquent and all future migrations will use the same format to help with continuity between builds. An example of this:

 `public function getRolePermissions($role){
        $sql = 'SELECT p.idpermissions, p.permission, r.idroles, r.role FROM permissions AS p
                INNER JOIN roles_permissions AS rp ON rp.permission = p.idpermissions
                INNER JOIN roles AS r ON rp.role= r.idroles
                WHERE r.role = :role';

        $stmt = $this->database->prepare($sql);
        $stmt->bindParam(':role', $role, PDO::PARAM_STR);

        $stmt->execute();

        return $stmt->fetchAll(PDO::FETCH_OBJ);
    }`

Went to this:

   `public function getRolePermissions($role){
    return DB::select(DB::raw('SELECT p.idpermissions, p.permission, r.idroles, r.role FROM permissions AS p
            INNER JOIN roles_permissions AS rp ON rp.permission = p.idpermissions
            INNER JOIN roles AS r ON rp.role= r.idroles
            WHERE r.role = :role'), array('role' => $role));
   }`

A lot simpler!

Models:

All models in the build were converted to Laravel models. Eloquent was used to recreate the functions used, however, the sql remained the same in order to complete the build in the time provided and to get the same results that the original build would have got. To do this the statements just included the relevant Laravel Raw functions e.g. selectRaw(), insertRaw() etc. In the future, it would be advised to convert these fully to Eloquent statements to utilise the full power of Laravel.

Controllers:

Controller functions were linked up to routes in the web.php file and returned views that were stored in the resources folder. The code in these controllers was converted so that it didn’t have to use constructors and used some more of Laravel’s features. These all were made as extensions of the Laravel controller class.

Helper Files:

To convert some of the class files that were stored in the lib folder of the previous build they were put into the FixometerHelper and FixometerFile helper files. These were included in the composer.json autoload and added as an alias in the app.php file in config so that they were loaded in at launch and could be used anywhere in the build. The FixometerHelper file was just functions that were used frequently whereas the FixometerFile was a class that was needed in order to handle file uploads an example being profile pictures.

Major Changes:

Some of the major changes to the build were:

  • Removed constructors in controllers - instead of constructors we have just used public functions so that they can be easily accessed across the site.

  • Changed the FILE usage to FixometerFile - This was changed so that it didn’t conflict with Laravel's built-in File facade.

  • Return views() instead of setting variables on Controllers - This is because it uses Laravel's built views helper to transfer to the frontend, so sets all variables in one statement

                  `return view('user.edit', [
                    'title' => 'Edit User',
                    'langs' => $fixometer_languages,
                    'user' => $user,
                    'header' => true,
                    'response' => $response,
                    'roles' => $Roles,
                    'groups' => $Groups,
                    'data' => $userdata,
                  ]);`
    
  • Removed the need for the privileged user on DB - This was done to make the DB easier to access by the site; since it was preventing some of the functionality of Laravel

  • Laravel Auth was used instead on the previous add-on Auth used - this change was made just to make the transition to Laravel an easier process

HTTPS:

In an effort to make the site more secure we have included middleware that will force HTTPS, therefore, providing the site with an encrypted way of transmission between the client and site. However, this is only triggered when the .env environment variable is set to prod or dev to represent the dev server or live; since this middleware does not work on local.

Blade Templating:

Laravel uses blade templates to simplify the use of php within the frontend view files. In order to utilise this function, all the previous php view files had to be translated into blade files this was done by adding the extension .blade to any view files, making them view.blade.php. Then all php usage in the file was replaced with their blade counterparts, e.g. = @if () and can be @endif. This also makes it easier to read as a programmer.

Assets:

In order to keep the same look as the original site we copied across all the assets used in the original site like the CSS and javascript. We then used Laravel Mix to compile all these assets into one main file, for instance, all the javascript files were compiled using ‘npm run dev’ to add it all to the app.js file. Meaning, fewer files have to be loaded when the website is accessed.