How to set up your local projects to contribute to Laravel (or any PHP library) : a practical guide

Let’s imagine this scenario: You are working on a Laravel application, and you found a bug either in the framework itself or in one of the third party libraries you are using. You edit the code inside your project, or maybe you installed a fresh copy of Laravel and library that has the issue, and you edited the code there. You saved the changes, but when you went to your terminal to commit the changes, GIT just ignored what you did. You start wondering “What’s happening here?”.

 

The first solution that might pop up in your head could be to read the “How to contribute” of the framework or the library documentation, and in most cases, you’d find there the necessary steps to contribute to the framework, but I always felt that something was missing in the documentation. Let me explain what I mean by that:

Let’s take the example of Laravel here, if you decide to contribute to the framework, you’d need to clone the laravel/framework repository, push your changes to your own copy of the repository (on github), and create a PR, but what’s missing here is How would you test your changes (bug fix, new feature, …) in a local project, since if you introduce the changes in that project you just can’t commit them and create a PR for them easily, and if you change the code in the laravel/framework repository you just cloned you might end up doing a lot of copy/pasting between this repository and your project in order to test those changes.

Luckily there is a cleaner way to deal with all this. I’m not going to walk you through the usual steps of creating a PR, I assume since you are reading this article you are already familiar with that. I’ll focus on how you should set up your local environment to streamline this whole process and show you how you could fix bugs and develop new features in the framework/library and test them locally before you create the PR you are about to send.

Prepare your test project and your repository

First, you’d need to fork the laravel/framework repository and then clone it locally (the usual steps when it comes to contributing to any open source project) and then create a test application where you are going to test those changes (I’m calling it playground)

➜ laravel pwd
/home/djug/laravel
➜ laravel ls
framework playground

Make Composer load the changes from the local repository

Now, with the most important part. We need to tell the playground application to take into consideration the changes we introduce in the /home/djug/laravel/framework repository

We can do this via composer, and according to its documentation and I’m quoting here:

Loading a package from a VCS repository

There are a few use cases for this. The most common one is maintaining
your own fork of a third party library. If you are using a certain
library for your project and you decide to change something in the
library, you will want your project to use the patched version. If the
library is on GitHub (this is the case most of the time), you can
simply fork it there and push your changes to your fork. After that,
you update the project’s composer.json. All you have to do is add your
fork as a repository and update the version constraint to point to
your custom branch.

So the first part of the composer.json file (on my playground project) should look like this:

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
    "framework",
    "laravel"
    ],

    "license": "MIT",
    "repositories": [
        {
            "type": "vcs",
            "url": "/home/djug/laravel/framework/"
        }
    ],
    "require": {
        "php": "^7.1.3",
        "fideloper/proxy": "^4.0",
        "laravel/framework": "master",
        "laravel/tinker": "^1.0"
    },
...
}

Now each time I change something in the /home/djug/laravel/framework/ repository and commit the change (you need to commit it) and if I execute composer update on my playground project it will get the changes.

3/ Push the changes to your remote repository and create a PR

Now that your playground repository can pull the changes from your framework repository, you could update add all the changes you want to your code and then test them on a “real” project.

After you finish testing, all that you need to do is to push the changes to your remote repository (your own “copy” of the framework repository on GitHub for instance) and then create the pull request.

 

Photo by John Schnobrich on Unsplash

[Laravel tips] How to redirect users to a specific URL/route when the validation fails

If you are using Form Request to validate your forms before you persist them in the database, when the validation fails, the user is usually redirected back to the same page that initiated the request.

For instance if you are on /new-article page, after you submit the article you are creating, the user will be redirected back automatically to this very same URL if the data she entered failed to pass the validation. This is the desired behavior in majority of the cases.

Lately, I was working on a form where I needed to redirect the user back to another route.

I was working on an application where we have different settings the user could update (from the settings page), and since it wasn’t desirable to send all the data in this page at once, validate it and then update the user settings, I created multiple “small form” each one is in a section of an accordion that updates just a group of related settings. So I could for instance visit /settings to view the settings page with all the sections/cards collapsed, or I could visit (/settings/personal-info) to open the settings page on that particular section.

So I might be visiting /settings/personal-info and then I’d scroll down to another section to update it (privacy for instance). In this case, if the validation fails, the user will be redirected to /settings/personal-info instead of /settings/privacy.

PS: I know this might not be the best way to handle this kind of the situation, but bear with me here, the goal is to explain how we could redirect the user to a different route 🙂

Luckily, we can redirect the user to the desired URL/route by setting up some propriety in the form request class.

Take a look at /vendor/laravel/framework/src/Illuminate/Foundation/Http/FormRequest.php

and you could find these 3 properties:

/**
* The URI to redirect to if validation fails.
*
* @var string
*/
protected $redirect;

/**
* The route to redirect to if validation fails.
*
* @var string
*/
protected $redirectRoute;
  
/**
* The controller action to redirect to if validation fails.
*
* @var string
*/
protected $redirectAction;

So all we need to do is to give the value we want to one (just one) of this properties.

protected $redirectRoute = 'get_all_articles';

PS: if you want to know what would happen if you set up more than one, take a look at the protected function getRedirectUrl() method on the same class.

One issue you might face in this situation is when you want to pass a value to redirectRoute, but you want to pass a route with a parameter like

Route::get('articles/{article}', '[email protected]')→name('view_article');

The solution is to set up the value of this property in the constructor like this:

public function __construct()

{
	$id = ….;
	$this->redirect = route('view_article', $id);
}

Note that I’m using $redirect here instead of the redirectRoute.

I hope you’ll find this tip useful 🙂