0

I'm creating an app and I am planning to give users a one click installation feature. The idea is to show a form when the application is first launched, sort of Installation / Configuration screen where user will type Database details (hostname, db name, username & password) and will enter user details (email, username and password for default admin account). Once he will submit the form, I want to do following tasks:

  1. Update .env file with hostname, db name, username & password
  2. Run all migrations
  3. Run all db:seeds
  4. Create a user based on user input (this is not much of an issue)

Is it possible to do via code? I have tried to google this but can't find any help.

As the title says, I'm using L5.2 for this project.

Jazzbot
  • 385
  • 1
  • 4
  • 18

2 Answers2

2

Everything can be done using code ;)

You could write a sh script which you call from your code or you can do this directly from your code.

  1. I haven't seen any functions for copying and populating .env file, but you could read .env.example using file_get_contents() and update the content before writing the new file back to disk.
  2. \Illuminate\Support\Facades\Artisan::call('migrate');
  3. \Illuminate\Support\Facades\Artisan::call('db:seed'); (Not tested since I only have done this from a test where it is possible to use $this->seed();
  4. User::create(['column', => $value])
Fabien Sa
  • 9,135
  • 4
  • 37
  • 44
rypskar
  • 2,012
  • 13
  • 13
2

So here is the final solution after playing around with this.

My controller:

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Storage;

class TestController extends Controller
{
    public function index() {

        // Values I want to insert 
        $data = [
            'APP_KEY'       => str_random(32),
            'DB_HOST'       => 'localhost',
            'DB_DATABASE'   => 'lara_test',
            'DB_USERNAME'   => 'root',
            'DB_PASSWORD'   => ''
        ];

        // default values of .env.example that I want to change
        $defaults = ['SomeRandomString', '127.0.0.1', 'homestead', 'homestead', 'secret'];

        // get contents of .env.example file
        $content = file_get_contents(base_path() . '/.env.example');

        // replace default values with new ones
        $i = 0;
        foreach ($data as $key => $value) {

            $content = str_replace($key.'='.$defaults[$i], $key.'='.$value, $content);
            $i++;
        }

        // Create new .env file
        Storage::disk('root')->put('.env', $content);

        // run all migrations
        Artisan::call('migrate');

        // run all db seeds
        Artisan::call('db:seed');

        dd('done');

    }

}

New Disk Driver:

To create a new file at project root, I had to create a new Disk Driver. I added following code in my config/app.php file:

'disks' => [

    .....

    'root' => [
        'driver' => 'local',
        'root'   => base_path(),
    ],

],

and this enabled me to create new file at root by using:

Storage::disk('root')->put('filename', $content);

Summary:

So basically I am getting the contents of .env.example file, changing the values of constants I want and then creating a new .env file. After that I ran all my migrations and seeds.

Note: I had to manually set the APP_KEY because of a stupid error No supported encrypter found. The cipher and / or key length are invalid.

Since I am trying to do everything inside code, not through commands - I tried using Artisan::call('key:generate'); but for some strange reasons it didn't work so to fix the issue, I had to create a random string manually which is 32 bit long and set it as APP_KEY.

Hope this will help someone else. :) And thanks to @rypskar for assistance.

Jazzbot
  • 385
  • 1
  • 4
  • 18