error('.env file already exists.'); } $this->overwriteConfig(); $this->info('.env configuration file has been created.'); } /** * Overwrite config file */ protected function overwriteConfig() { foreach (array_keys($this->config()) as $config) { $this->config = $config; $this->configToEnv(); } } /** * Replace config values with env() syntax */ protected function configToEnv() { $content = $this->parseConfigFile(); $this->writeToConfigFile($content); } /** * Parse config file line by line * * @return string */ protected function parseConfigFile() { $lines = []; foreach ($this->lines() as $line) { $keys = $this->config()[$this->config]; $lines[] = $this->parseLine($line, $keys); } $this->writeToEnv("\n"); return implode('', $lines); } /** * @param $keys * @param $line * @return mixed */ protected function parseLine($line, $keys) { $line = $this->replaceConfigLine($line, $keys); $line = $this->replaceDbConfigLine($line); return $line; } /** * @param $line * @param $keys * @return mixed */ protected function replaceConfigLine($line, $keys) { foreach ($keys as $envKey => $configKey) { $pattern = $this->buildPattern($configKey); $callback = $this->buildCallback($envKey, $configKey); if (preg_match($pattern, $line)) { $line = preg_replace_callback($pattern, $callback, $line); } } return $line; } /** * @param $line * @return mixed */ protected function replaceDbConfigLine($line) { if ($this->config == 'database') { foreach ($this->dbConfig() as $connection => $settings) { $this->setCurrentConnection($line, $connection); if ($this->connection == $connection) { $line = $this->replaceConfigLine($line, $settings); } } } return $line; } /** * @param $line * @param $connection */ protected function setCurrentConnection($line, $connection) { if (preg_match("/['\"]" . $connection . "['\"]" . "\s*=>/", $line)) { $this->connection = $connection; } } /** * @param $configKey * @return string */ protected function buildPattern($configKey) { return "/['\"]" . $configKey . "['\"]" . "\s*=>\s*[^,\[]+,/"; } /** * @param $envKey * @param $configKey * @return \Closure */ protected function buildCallback($envKey, $configKey) { return function ($matches) use ($envKey, $configKey) { $value = $this->envValue($configKey); $this->saveEnvSettings($envKey, $this->normalizeForEnv($value)); // Remove protected values from the config files if (in_array($envKey, $this->protectedKeys) && !empty($value)) { $value = ''; } return $this->isEnv($matches[0]) ? $matches[0] : "'$configKey' => env('$envKey', {$this->normalizeForConfig($value)}),"; }; } /** * @param $key * @param $value */ protected function saveEnvSettings($key, $value) { if (! $this->envKeyExists($key)) { $line = sprintf("%s=%s\n", $key, $value); if ($this->config == 'database' && $key != 'DB_CONNECTION') { $this->writeDbEnvSettings($line); } else { $this->writeToEnv($line); } } } /** * @param $line */ protected function writeDbEnvSettings($line) { if ($this->connection == config('database.default') || $this->connection == 'redis') { $this->writeToEnv($line); } } /** * @param $configKey * @return string */ protected function envValue($configKey) { $value = config("$this->config.$configKey"); if ($this->config == 'database') { $value = $this->databaseConfigValue($configKey); } return $value; } /** * @param $configKey * @return string */ protected function databaseConfigValue($configKey) { if ($configKey == 'default') { return config('database.default'); } if ($configKey == 'useConfigForTesting') { return config('database.useConfigForTesting'); } if ($this->connection == 'redis') { return config("database.redis.default.$configKey"); } return config("database.connections.$this->connection.$configKey"); } /** * Normalizes a value to be inserted into the .env file * * @param $value * @return string */ protected function normalizeForEnv($value) { if (is_string($value)) { if (preg_match('/["\'#]/', $value)) { return '"' . str_replace('"', '\\"', $value) . '"'; } else { return $value; } } elseif (is_bool($value)) { return $value ? 'true' : 'false'; } elseif ($value === null) { return 'null'; } return $value; } /** * Normalizes a value to be inserted into config files. * * @param $value * @return string */ protected function normalizeForConfig($value) { if (is_string($value)) { return '\'' . addslashes($value) . '\''; } return $this->normalizeForEnv($value); } /** * @param $matches * @return bool */ protected function isEnv($matches) { return strpos($matches, 'env') !== false; } /** * @param $content */ protected function writeToEnv($content) { file_put_contents('.env', $content, FILE_APPEND); } /** * @return string */ protected function readEnvFile() { return file_exists('.env') ? file_get_contents('.env') : ''; } /** * @param $content */ protected function writeToConfigFile($content) { file_put_contents(config_path($this->config . '.php'), $content); } /** * @return array */ protected function lines() { return file(config_path($this->config . '.php')); } /** * @param $key * @return bool */ protected function envKeyExists($key) { return strpos($this->readEnvFile(), $key) !== false; } /** * @return array */ protected function config() { return [ 'app' => [ 'APP_DEBUG' => 'debug', 'APP_URL' => 'url', 'APP_KEY' => 'key', ], 'database' => [ 'DB_CONNECTION' => 'default', 'DB_USE_CONFIG_FOR_TESTING' => 'useConfigForTesting', ], 'cache' => [ 'CACHE_DRIVER' => 'default', ], 'session' => [ 'SESSION_DRIVER' => 'driver', ], 'queue' => [ 'QUEUE_DRIVER' => 'default', ], 'mail' => [ 'MAIL_DRIVER' => 'driver', 'MAIL_HOST' => 'host', 'MAIL_PORT' => 'port', 'MAIL_USERNAME' => 'username', 'MAIL_PASSWORD' => 'password', 'MAIL_ENCRYPTION' => 'encryption', ], 'cms' => [ 'ROUTES_CACHE' => 'enableRoutesCache', 'ASSET_CACHE' => 'enableAssetCache', 'LINK_POLICY' => 'linkPolicy', 'ENABLE_CSRF' => 'enableCsrfProtection', 'DATABASE_TEMPLATES' => 'databaseTemplates' ], ]; } /** * @return array */ protected function dbConfig() { return [ 'sqlite' => [ 'DB_DATABASE' => 'database', ], 'mysql' => [ 'DB_HOST' => 'host', 'DB_PORT' => 'port', 'DB_DATABASE' => 'database', 'DB_USERNAME' => 'username', 'DB_PASSWORD' => 'password', ], 'pgsql' => [ 'DB_HOST' => 'host', 'DB_PORT' => 'port', 'DB_DATABASE' => 'database', 'DB_USERNAME' => 'username', 'DB_PASSWORD' => 'password', ], 'redis' => [ 'REDIS_HOST' => 'host', 'REDIS_PASSWORD' => 'password', 'REDIS_PORT' => 'port', ], ]; } }