mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-04-07 13:41:23 +00:00
455 lines
14 KiB
PHP
Executable File
455 lines
14 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Space;
|
|
|
|
use App\Http\Requests\DatabaseEnvironmentRequest;
|
|
use App\Http\Requests\DiskEnvironmentRequest;
|
|
use App\Http\Requests\DomainEnvironmentRequest;
|
|
use App\Http\Requests\MailEnvironmentRequest;
|
|
use Exception;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class EnvironmentManager
|
|
{
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $envPath;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $delimiter = "\n";
|
|
|
|
/**
|
|
* Set the .env and .env.example paths.
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->envPath = base_path('.env');
|
|
}
|
|
|
|
/**
|
|
* Returns the .env contents
|
|
*
|
|
* @return false|string
|
|
*/
|
|
private function getEnvContents()
|
|
{
|
|
return file_get_contents($this->envPath);
|
|
}
|
|
|
|
/**
|
|
* Updates .env file - inspired by Akaunting
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function updateEnv(array $data)
|
|
{
|
|
if (empty($data) || !is_array($data) || !is_file($this->envPath)) {
|
|
return false;
|
|
}
|
|
|
|
$env = $this->getEnvContents();
|
|
|
|
$env = explode($this->delimiter, $env);
|
|
|
|
foreach ($data as $data_key => $data_value) {
|
|
$updated = false;
|
|
|
|
foreach ($env as $env_key => $env_value) {
|
|
$entry = explode('=', $env_value, 2);
|
|
|
|
// Check if new or old key
|
|
if ($entry[0] == $data_key) {
|
|
$env[$env_key] = $data_key . '=' . $this->encode($data_value);
|
|
$updated = true;
|
|
}
|
|
}
|
|
|
|
// Lets create if not available
|
|
if (!$updated) {
|
|
$env[] = $data_key . '=' . $this->encode($data_value);
|
|
}
|
|
}
|
|
|
|
$env = implode($this->delimiter, $env);
|
|
|
|
file_put_contents(base_path('.env'), $env);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Encodes value for .env
|
|
*
|
|
* @return mixed|string
|
|
*/
|
|
private function encode($str)
|
|
{
|
|
|
|
if ((strpos($str, ' ') !== false || preg_match('/' . preg_quote('^\'£$%^&*()}{@#~?><,@|-=-_+-¬', '/') . '/', $str)) && ($str[0] != '"' || $str[strlen($str) - 1] != '"')) {
|
|
$str = '"' . $str . '"';
|
|
}
|
|
|
|
return $str;
|
|
|
|
}
|
|
|
|
/**
|
|
* Save the database content to the .env file.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function saveDatabaseVariables(DatabaseEnvironmentRequest $request)
|
|
{
|
|
$dbEnv = [
|
|
'APP_URL' => $request->get('app_url'),
|
|
'APP_LOCALE' => $request->get('app_locale'),
|
|
'DB_CONNECTION' => $request->get('database_connection'),
|
|
'SANCTUM_STATEFUL_DOMAINS' => $request->get('app_domain'),
|
|
'SESSION_DOMAIN' => explode(':', $request->get('app_domain'))[0],
|
|
];
|
|
|
|
if ($dbEnv['DB_CONNECTION'] != 'sqlite') {
|
|
if ($request->has('database_username') && $request->has('database_password')) {
|
|
$dbEnv['DB_HOST'] = $request->get('database_hostname');
|
|
$dbEnv['DB_PORT'] = $request->get('database_port');
|
|
$dbEnv['DB_DATABASE'] = $request->get('database_name');
|
|
$dbEnv['DB_USERNAME'] = $request->get('database_username');
|
|
$dbEnv['DB_PASSWORD'] = $request->get('database_password');
|
|
}
|
|
} else {
|
|
// Laravel 11 requires SQLite at least v3.35.0
|
|
// https://laravel.com/docs/11.x/database#introduction
|
|
if (extension_loaded('sqlite3') && class_exists('\SQLite3') && method_exists('\SQLite3', 'version')) {
|
|
$version = \SQLite3::version();
|
|
if (!empty($version['versionString']) && version_compare($version['versionString'], '3.35.0', '<')) {
|
|
return [
|
|
'error_message' => sprintf('The minimum SQLite version is %s. Your current SQLite version is %s which is not supported. Please upgrade SQLite and retry.', '3.35.0', $version['versionString']),
|
|
];
|
|
}
|
|
} else {
|
|
return [
|
|
'error_message' => sprintf('SQLite3 is not present. Please install SQLite >=%s and retry.', '3.35.0'),
|
|
];
|
|
}
|
|
$dbEnv['DB_DATABASE'] = $request->get('database_name');
|
|
if (!empty($dbEnv['DB_DATABASE'])) {
|
|
$sqlite_path = $dbEnv['DB_DATABASE'];
|
|
} else {
|
|
$sqlite_path = database_path('database.sqlite');
|
|
}
|
|
// Create empty SQLite database if it doesn't exist.
|
|
if (!file_exists($sqlite_path)) {
|
|
copy(database_path('stubs/sqlite.empty.db'), $sqlite_path);
|
|
$dbEnv['DB_DATABASE'] = $sqlite_path;
|
|
}
|
|
}
|
|
|
|
try {
|
|
$this->checkDatabaseConnection($request);
|
|
|
|
if (\Schema::hasTable('users')) {
|
|
return [
|
|
'error' => 'database_should_be_empty',
|
|
];
|
|
}
|
|
} catch (Exception $e) {
|
|
return [
|
|
'error_message' => $e->getMessage(),
|
|
];
|
|
}
|
|
|
|
try {
|
|
$this->updateEnv($dbEnv);
|
|
} catch (Exception $e) {
|
|
return [
|
|
'error' => 'database_variables_save_error',
|
|
];
|
|
}
|
|
|
|
return [
|
|
'success' => 'database_variables_save_successfully',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Returns PDO object if all ok.
|
|
*
|
|
* @return \Closure|\PDO
|
|
*/
|
|
private function checkDatabaseConnection(DatabaseEnvironmentRequest $request)
|
|
{
|
|
$connection = $request->get('database_connection');
|
|
|
|
$settings = config("database.connections.$connection");
|
|
|
|
$connectionArray = array_merge($settings, [
|
|
'driver' => $connection,
|
|
'database' => $request->get('database_name'),
|
|
]);
|
|
|
|
if ($connection !== 'sqlite' && $request->has('database_username') && $request->has('database_password')) {
|
|
$connectionArray = array_merge($connectionArray, [
|
|
'username' => $request->get('database_username'),
|
|
'password' => $request->get('database_password'),
|
|
'host' => $request->get('database_hostname'),
|
|
'port' => $request->get('database_port'),
|
|
]);
|
|
}
|
|
|
|
config([
|
|
'database' => [
|
|
'migrations' => 'migrations',
|
|
'default' => $connection,
|
|
'connections' => [$connection => $connectionArray],
|
|
],
|
|
]);
|
|
|
|
return DB::connection()->getPdo();
|
|
}
|
|
|
|
/**
|
|
* Save the mail content to the .env file.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function saveMailVariables(MailEnvironmentRequest $request)
|
|
{
|
|
$mailEnv = $this->getMailConfiguration($request);
|
|
|
|
try {
|
|
|
|
$this->updateEnv($mailEnv);
|
|
|
|
} catch (Exception $e) {
|
|
return [
|
|
'error' => 'mail_variables_save_error',
|
|
];
|
|
}
|
|
|
|
return [
|
|
'success' => 'mail_variables_save_successfully',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Returns the mail configuration
|
|
*
|
|
* @param MailEnvironmentRequest $request
|
|
* @return array
|
|
*/
|
|
private function getMailConfiguration($request)
|
|
{
|
|
$mailEnv = [];
|
|
|
|
$driver = $request->get('mail_driver');
|
|
|
|
switch ($driver) {
|
|
case 'smtp':
|
|
|
|
$mailEnv = [
|
|
'MAIL_DRIVER' => $request->get('mail_driver'),
|
|
'MAIL_HOST' => $request->get('mail_host'),
|
|
'MAIL_PORT' => $request->get('mail_port'),
|
|
'MAIL_USERNAME' => $request->get('mail_username'),
|
|
'MAIL_PASSWORD' => $request->get('mail_password'),
|
|
'MAIL_ENCRYPTION' => $request->get('mail_encryption'),
|
|
'MAIL_FROM_ADDRESS' => $request->get('from_mail'),
|
|
'MAIL_FROM_NAME' => $request->get('from_name'),
|
|
];
|
|
|
|
break;
|
|
|
|
case 'mailgun':
|
|
|
|
$mailEnv = [
|
|
'MAIL_DRIVER' => $request->get('mail_driver'),
|
|
'MAIL_HOST' => $request->get('mail_host'),
|
|
'MAIL_PORT' => $request->get('mail_port'),
|
|
'MAIL_USERNAME' => config('mail.username'),
|
|
'MAIL_PASSWORD' => config('mail.password'),
|
|
'MAIL_ENCRYPTION' => $request->get('mail_encryption'),
|
|
'MAIL_FROM_ADDRESS' => $request->get('from_mail'),
|
|
'MAIL_FROM_NAME' => $request->get('from_name'),
|
|
'MAILGUN_DOMAIN' => $request->get('mail_mailgun_domain'),
|
|
'MAILGUN_SECRET' => $request->get('mail_mailgun_secret'),
|
|
'MAILGUN_ENDPOINT' => $request->get('mail_mailgun_endpoint'),
|
|
];
|
|
|
|
break;
|
|
|
|
case 'ses':
|
|
|
|
$mailEnv = [
|
|
'MAIL_DRIVER' => $request->get('mail_driver'),
|
|
'MAIL_HOST' => $request->get('mail_host'),
|
|
'MAIL_PORT' => $request->get('mail_port'),
|
|
'MAIL_USERNAME' => config('mail.username'),
|
|
'MAIL_PASSWORD' => config('mail.password'),
|
|
'MAIL_ENCRYPTION' => $request->get('mail_encryption'),
|
|
'MAIL_FROM_ADDRESS' => $request->get('from_mail'),
|
|
'MAIL_FROM_NAME' => $request->get('from_name'),
|
|
'SES_KEY' => $request->get('mail_ses_key'),
|
|
'SES_SECRET' => $request->get('mail_ses_secret'),
|
|
];
|
|
|
|
break;
|
|
|
|
case 'sendmail':
|
|
case 'mail':
|
|
|
|
$mailEnv = [
|
|
'MAIL_DRIVER' => $request->get('mail_driver'),
|
|
'MAIL_HOST' => config('mail.host'),
|
|
'MAIL_PORT' => config('mail.port'),
|
|
'MAIL_USERNAME' => config('mail.username'),
|
|
'MAIL_PASSWORD' => config('mail.password'),
|
|
'MAIL_ENCRYPTION' => config('mail.encryption'),
|
|
'MAIL_FROM_ADDRESS' => $request->get('from_mail'),
|
|
'MAIL_FROM_NAME' => $request->get('from_name'),
|
|
];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return $mailEnv;
|
|
}
|
|
|
|
/**
|
|
* Save the disk content to the .env file.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function saveDiskVariables(DiskEnvironmentRequest $request)
|
|
{
|
|
$diskEnv = $this->getDiskConfiguration($request);
|
|
|
|
try {
|
|
|
|
$this->updateEnv($diskEnv);
|
|
|
|
} catch (Exception $e) {
|
|
return [
|
|
'error' => 'disk_variables_save_error',
|
|
];
|
|
}
|
|
|
|
return [
|
|
'success' => 'disk_variables_save_successfully',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Returns the disk configuration
|
|
*
|
|
* @return array
|
|
*/
|
|
private function getDiskConfiguration(DiskEnvironmentRequest $request)
|
|
{
|
|
$diskEnv = [];
|
|
|
|
$driver = $request->get('app_domain');
|
|
|
|
if ($driver) {
|
|
$diskEnv['FILESYSTEM_DRIVER'] = $driver;
|
|
}
|
|
|
|
switch ($request->get('selected_driver')) {
|
|
case 's3':
|
|
|
|
$diskEnv = [
|
|
'AWS_KEY' => $request->get('aws_key'),
|
|
'AWS_SECRET' => $request->get('aws_secret'),
|
|
'AWS_REGION' => $request->get('aws_region'),
|
|
'AWS_BUCKET' => $request->get('aws_bucket'),
|
|
'AWS_ROOT' => $request->get('aws_root'),
|
|
];
|
|
|
|
break;
|
|
|
|
case 'doSpaces':
|
|
|
|
$diskEnv = [
|
|
'DO_SPACES_KEY' => $request->get('do_spaces_key'),
|
|
'DO_SPACES_SECRET' => $request->get('do_spaces_secret'),
|
|
'DO_SPACES_REGION' => $request->get('do_spaces_region'),
|
|
'DO_SPACES_BUCKET' => $request->get('do_spaces_bucket'),
|
|
'DO_SPACES_ENDPOINT' => $request->get('do_spaces_endpoint'),
|
|
'DO_SPACES_ROOT' => $request->get('do_spaces_root'),
|
|
];
|
|
|
|
break;
|
|
|
|
case 'dropbox':
|
|
|
|
$diskEnv = [
|
|
'DROPBOX_TOKEN' => $request->get('dropbox_token'),
|
|
'DROPBOX_KEY' => $request->get('dropbox_key'),
|
|
'DROPBOX_SECRET' => $request->get('dropbox_secret'),
|
|
'DROPBOX_APP' => $request->get('dropbox_app'),
|
|
'DROPBOX_ROOT' => $request->get('dropbox_root'),
|
|
];
|
|
|
|
break;
|
|
}
|
|
|
|
return $diskEnv;
|
|
}
|
|
|
|
/**
|
|
* Save sanctum stateful domain to the .env file.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function saveDomainVariables(DomainEnvironmentRequest $request)
|
|
{
|
|
try {
|
|
$this->updateEnv([
|
|
'SANCTUM_STATEFUL_DOMAINS' => $request->get('app_domain'),
|
|
'SESSION_DOMAIN' => explode(':', $request->get('app_domain'))[0],
|
|
]);
|
|
} catch (Exception $e) {
|
|
return [
|
|
'error' => 'domain_verification_failed',
|
|
];
|
|
}
|
|
|
|
return [
|
|
'success' => 'domain_variable_save_successfully',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Order the env contents
|
|
*
|
|
* @return void
|
|
*/
|
|
public function reoderEnv()
|
|
{
|
|
$contents = $this->getEnvContents();
|
|
$contents = explode($this->delimiter, $contents);
|
|
if (empty($contents)) {
|
|
return;
|
|
}
|
|
natsort($contents);
|
|
|
|
$formatted = '';
|
|
$previous = '';
|
|
foreach ($contents as $current) {
|
|
$parts_line = explode('_', $current);
|
|
$parts_last = explode('_', $previous);
|
|
if ($parts_line[0] != $parts_last[0]) {
|
|
$formatted .= $this->delimiter;
|
|
}
|
|
$formatted .= $current . $this->delimiter;
|
|
$previous = $current;
|
|
|
|
}
|
|
|
|
file_put_contents($this->envPath, trim($formatted));
|
|
}
|
|
}
|