master

laravel/framework

Last updated at: 29/12/2023 09:22

KeyGenerateCommand.php

TLDR

The KeyGenerateCommand.php file in the Illuminate\Foundation\Console namespace provides a command to generate an application key. It sets the application key by replacing it in the environment file and updates the configuration file. It also has a method to generate a random key and helper methods to set the key in the environment file and write a new environment file.

Methods

handle

The handle method executes the console command. It generates a random key, displays it if the --show option is used, replaces the application key in the environment file if it is not empty, and updates the configuration file.

generateRandomKey

The generateRandomKey method generates a random key for the application. It uses the Encrypter class to generate the key and base64 encodes it.

setKeyInEnvironmentFile

The setKeyInEnvironmentFile method sets the application key in the environment file. It checks if the current key is not empty and confirms the operation if needed. It then calls the writeNewEnvironmentFileWith method to replace the key in the environment file.

writeNewEnvironmentFileWith

The writeNewEnvironmentFileWith method writes a new environment file with the given key. It replaces the existing key in the file using a regular expression pattern. If the replacement is successful, it updates the environment file with the new content.

keyReplacementPattern

The keyReplacementPattern method returns a regular expression pattern that matches the existing APP_KEY value in the environment file. It is used by the writeNewEnvironmentFileWith method to find and replace the key.

Classes

No classes in the file

<?php

namespace Illuminate\Foundation\Console;

use Illuminate\Console\Command;
use Illuminate\Console\ConfirmableTrait;
use Illuminate\Encryption\Encrypter;
use Symfony\Component\Console\Attribute\AsCommand;

#[AsCommand(name: 'key:generate')]
class KeyGenerateCommand extends Command
{
    use ConfirmableTrait;

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'key:generate
                    {--show : Display the key instead of modifying files}
                    {--force : Force the operation to run when in production}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Set the application key';

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function handle()
    {
        $key = $this->generateRandomKey();

        if ($this->option('show')) {
            return $this->line('<comment>'.$key.'</comment>');
        }

        // Next, we will replace the application key in the environment file so it is
        // automatically setup for this developer. This key gets generated using a
        // secure random byte generator and is later base64 encoded for storage.
        if (! $this->setKeyInEnvironmentFile($key)) {
            return;
        }

        $this->laravel['config']['app.key'] = $key;

        $this->components->info('Application key set successfully.');
    }

    /**
     * Generate a random key for the application.
     *
     * @return string
     */
    protected function generateRandomKey()
    {
        return 'base64:'.base64_encode(
            Encrypter::generateKey($this->laravel['config']['app.cipher'])
        );
    }

    /**
     * Set the application key in the environment file.
     *
     * @param  string  $key
     * @return bool
     */
    protected function setKeyInEnvironmentFile($key)
    {
        $currentKey = $this->laravel['config']['app.key'];

        if (strlen($currentKey) !== 0 && (! $this->confirmToProceed())) {
            return false;
        }

        if (! $this->writeNewEnvironmentFileWith($key)) {
            return false;
        }

        return true;
    }

    /**
     * Write a new environment file with the given key.
     *
     * @param  string  $key
     * @return bool
     */
    protected function writeNewEnvironmentFileWith($key)
    {
        $replaced = preg_replace(
            $this->keyReplacementPattern(),
            'APP_KEY='.$key,
            $input = file_get_contents($this->laravel->environmentFilePath())
        );

        if ($replaced === $input || $replaced === null) {
            $this->error('Unable to set application key. No APP_KEY variable was found in the .env file.');

            return false;
        }

        file_put_contents($this->laravel->environmentFilePath(), $replaced);

        return true;
    }

    /**
     * Get a regex pattern that will match env APP_KEY with any random key.
     *
     * @return string
     */
    protected function keyReplacementPattern()
    {
        $escaped = preg_quote('='.$this->laravel['config']['app.key'], '/');

        return "/^APP_KEY{$escaped}/m";
    }
}