mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
fix: koel:init
This commit is contained in:
parent
971a3c2629
commit
9d3011fe2c
5 changed files with 281 additions and 176 deletions
|
@ -11,9 +11,10 @@ use Illuminate\Console\Command;
|
|||
use Illuminate\Contracts\Console\Kernel as Artisan;
|
||||
use Illuminate\Contracts\Hashing\Hasher as Hash;
|
||||
use Illuminate\Database\DatabaseManager as DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Encryption\Encrypter;
|
||||
use Illuminate\Support\Str;
|
||||
use Jackiedo\DotenvEditor\DotenvEditor;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
class InitCommand extends Command
|
||||
|
@ -23,7 +24,7 @@ class InitCommand extends Command
|
|||
private const DEFAULT_ADMIN_NAME = 'Koel';
|
||||
private const DEFAULT_ADMIN_EMAIL = 'admin@koel.dev';
|
||||
private const DEFAULT_ADMIN_PASSWORD = 'KoelIsCool';
|
||||
private const NON_INTERACTION_MAX_ATTEMPT_COUNT = 10;
|
||||
private const NON_INTERACTION_MAX_DATABASE_ATTEMPT_COUNT = 10;
|
||||
|
||||
protected $signature = 'koel:init {--no-assets}';
|
||||
protected $description = 'Install or upgrade Koel';
|
||||
|
@ -35,16 +36,20 @@ class InitCommand extends Command
|
|||
private Artisan $artisan,
|
||||
private Hash $hash,
|
||||
private DotenvEditor $dotenvEditor,
|
||||
private DB $db
|
||||
private DB $db,
|
||||
private LoggerInterface $logger
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$this->comment('Attempting to install or upgrade Koel.');
|
||||
$this->comment('Remember, you can always install/upgrade manually following the guide here:');
|
||||
$this->info('📙 ' . config('koel.misc.docs_url') . PHP_EOL);
|
||||
$this->alert('KOEL INSTALLATION WIZARD');
|
||||
$this->info(
|
||||
'As a reminder, you can always install/upgrade manually following the guide at '
|
||||
. config('koel.misc.docs_url')
|
||||
. PHP_EOL
|
||||
);
|
||||
|
||||
if ($this->inNoInteractionMode()) {
|
||||
$this->components->info('Running in no-interaction mode');
|
||||
|
@ -52,7 +57,7 @@ class InitCommand extends Command
|
|||
|
||||
try {
|
||||
$this->clearCaches();
|
||||
$this->maybeCopyEnvFile();
|
||||
$this->loadEnvFile();
|
||||
$this->maybeGenerateAppKey();
|
||||
$this->maybeSetUpDatabase();
|
||||
$this->migrateDatabase();
|
||||
|
@ -60,71 +65,79 @@ class InitCommand extends Command
|
|||
$this->maybeSetMediaPath();
|
||||
$this->maybeCompileFrontEndAssets();
|
||||
} catch (Throwable $e) {
|
||||
Log::error($e);
|
||||
$this->logger->error($e);
|
||||
|
||||
$this->components->error("Oops! Koel installation or upgrade didn't finish successfully.");
|
||||
|
||||
$this->error('Please try again, or visit '
|
||||
. config('koel.misc.docs_url')
|
||||
. ' for other options.');
|
||||
|
||||
$this->error('😥 Sorry for this. You deserve better.');
|
||||
$this->components->error('Please check the error log at storage/logs/laravel.log and try again.');
|
||||
$this->components->error('You can also visit ' . config('koel.misc.docs_url') . ' for other options.');
|
||||
$this->components->error('😥 Sorry for this. You deserve better.');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->comment(PHP_EOL . '🎆 Success! Koel can now be run from localhost with `php artisan serve`.');
|
||||
$this->newLine();
|
||||
$this->output->success('All done!');
|
||||
$this->info('Koel can now be run from localhost with `php artisan serve`.');
|
||||
|
||||
if ($this->adminSeeded) {
|
||||
$this->comment(
|
||||
$this->info(
|
||||
sprintf('Log in with email %s and password %s', self::DEFAULT_ADMIN_EMAIL, self::DEFAULT_ADMIN_PASSWORD)
|
||||
);
|
||||
}
|
||||
|
||||
if (Setting::get('media_path')) {
|
||||
$this->comment('You can also scan for media with `php artisan koel:sync`.');
|
||||
$this->info('You can also scan for media now with `php artisan koel:sync`.');
|
||||
}
|
||||
|
||||
$this->comment('Again, visit 📙 ' . config('koel.misc.docs_url') . ' for the official documentation.');
|
||||
$this->info('Again, visit 📙 ' . config('koel.misc.docs_url') . ' for more tips and tweaks.');
|
||||
|
||||
$this->comment(
|
||||
$this->info(
|
||||
"Feeling generous and want to support Koel's development? Check out "
|
||||
. config('koel.misc.sponsor_github_url')
|
||||
. ' 🤗'
|
||||
);
|
||||
|
||||
$this->comment('Thanks for using Koel. You rock! 🤘');
|
||||
$this->info('Thanks for using Koel. You rock! 🤘');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function clearCaches(): void
|
||||
{
|
||||
$this->components->info('Clearing caches');
|
||||
$this->components->task('Clearing caches', function (): void {
|
||||
$this->artisan->call('config:clear');
|
||||
$this->artisan->call('cache:clear');
|
||||
});
|
||||
}
|
||||
|
||||
private function maybeCopyEnvFile(): void
|
||||
private function loadEnvFile(): void
|
||||
{
|
||||
if (!file_exists(base_path('.env'))) {
|
||||
$this->components->info('Copying .env file');
|
||||
$this->components->task('Copying .env file', static function (): void {
|
||||
copy(base_path('.env.example'), base_path('.env'));
|
||||
});
|
||||
} else {
|
||||
$this->components->info('.env file exists -- skipping');
|
||||
}
|
||||
|
||||
$this->dotenvEditor->load(base_path('.env'));
|
||||
}
|
||||
|
||||
private function maybeGenerateAppKey(): void
|
||||
{
|
||||
if (!config('app.key')) {
|
||||
$this->components->info('Generating app key');
|
||||
$this->artisan->call('key:generate');
|
||||
} else {
|
||||
$this->components->info('App key exists -- skipping');
|
||||
}
|
||||
$key = $this->laravel['config']['app.key'];
|
||||
|
||||
$this->components->info('Using app key: ' . Str::limit(config('app.key'), 16));
|
||||
$this->components->task($key ? 'Retrieving app key' : 'Generating app key', function () use (&$key): void {
|
||||
if (!$key) {
|
||||
// Generate the key manually to prevent some clashes with `php artisan key:generate`
|
||||
$key = $this->generateRandomKey();
|
||||
$this->dotenvEditor->setKey('APP_KEY', $key);
|
||||
$this->laravel['config']['app.key'] = $key;
|
||||
}
|
||||
});
|
||||
|
||||
$this->newLine();
|
||||
$this->components->info('Using app key: ' . Str::limit($key, 16));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -189,8 +202,7 @@ class InitCommand extends Command
|
|||
|
||||
private function setUpAdminAccount(): void
|
||||
{
|
||||
$this->info("Creating default admin account");
|
||||
|
||||
$this->components->task('Creating default admin account', function (): void {
|
||||
User::create([
|
||||
'name' => self::DEFAULT_ADMIN_NAME,
|
||||
'email' => self::DEFAULT_ADMIN_EMAIL,
|
||||
|
@ -199,6 +211,74 @@ class InitCommand extends Command
|
|||
]);
|
||||
|
||||
$this->adminSeeded = true;
|
||||
});
|
||||
}
|
||||
|
||||
private function maybeSeedDatabase(): void
|
||||
{
|
||||
if (!User::count()) {
|
||||
$this->setUpAdminAccount();
|
||||
|
||||
$this->components->task('Seeding data', function (): void {
|
||||
$this->artisan->call('db:seed', ['--force' => true]);
|
||||
});
|
||||
} else {
|
||||
$this->newLine();
|
||||
$this->components->info('Data already seeded -- skipping');
|
||||
}
|
||||
}
|
||||
|
||||
private function maybeSetUpDatabase(): void
|
||||
{
|
||||
$attempt = 0;
|
||||
|
||||
while (true) {
|
||||
// In non-interactive mode, we must not endlessly attempt to connect.
|
||||
// Doing so will just end up with a huge amount of "failed to connect" logs.
|
||||
// We do retry a little, though, just in case there's some kind of temporary failure.
|
||||
if ($this->inNoInteractionMode() && $attempt >= self::NON_INTERACTION_MAX_DATABASE_ATTEMPT_COUNT) {
|
||||
$this->components->error('Maximum database connection attempts reached. Giving up.');
|
||||
break;
|
||||
}
|
||||
|
||||
$attempt++;
|
||||
|
||||
try {
|
||||
// Make sure the config cache is cleared before another attempt.
|
||||
$this->artisan->call('config:clear');
|
||||
$this->db->reconnect()->getPdo();
|
||||
|
||||
break;
|
||||
} catch (Throwable $e) {
|
||||
$this->logger->error($e);
|
||||
|
||||
// We only try to update credentials if running in interactive mode.
|
||||
// Otherwise, we require admin intervention to fix them.
|
||||
// This avoids inadvertently wiping credentials if there's a connection failure.
|
||||
if ($this->inNoInteractionMode()) {
|
||||
$warning = sprintf(
|
||||
"Cannot connect to the database. Attempt: %d/%d",
|
||||
$attempt,
|
||||
self::NON_INTERACTION_MAX_DATABASE_ATTEMPT_COUNT
|
||||
);
|
||||
|
||||
$this->components->warn($warning);
|
||||
} else {
|
||||
$this->components->warn("Cannot connect to the database. Let's set it up.");
|
||||
$this->setUpDatabase();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function migrateDatabase(): void
|
||||
{
|
||||
$this->components->task('Migrating database', function (): void {
|
||||
$this->artisan->call('migrate', ['--force' => true]);
|
||||
});
|
||||
|
||||
// Clear the media cache, just in case we did any media-related migration
|
||||
$this->mediaCacheService->clear();
|
||||
}
|
||||
|
||||
private function maybeSetMediaPath(): void
|
||||
|
@ -213,6 +293,7 @@ class InitCommand extends Command
|
|||
return;
|
||||
}
|
||||
|
||||
$this->newLine();
|
||||
$this->info('The absolute path to your media directory. If this is skipped (left blank) now, you can set it later via the web interface.'); // @phpcs-ignore-line
|
||||
|
||||
while (true) {
|
||||
|
@ -228,76 +309,10 @@ class InitCommand extends Command
|
|||
return;
|
||||
}
|
||||
|
||||
$this->components->error('The path does not exist or not readable. Try again.');
|
||||
$this->components->error('The path does not exist or not readable. Try again?');
|
||||
}
|
||||
}
|
||||
|
||||
private function maybeSeedDatabase(): void
|
||||
{
|
||||
if (!User::count()) {
|
||||
$this->setUpAdminAccount();
|
||||
$this->components->info('Seeding initial data');
|
||||
$this->artisan->call('db:seed', ['--force' => true]);
|
||||
} else {
|
||||
$this->components->info('Data seeded -- skipping');
|
||||
}
|
||||
}
|
||||
|
||||
private function maybeSetUpDatabase(): void
|
||||
{
|
||||
$attemptCount = 0;
|
||||
|
||||
while (true) {
|
||||
// In non-interactive mode, we must not endlessly attempt to connect.
|
||||
// Doing so will just end up with a huge amount of "failed to connect" logs.
|
||||
// We do retry a little, though, just in case there's some kind of temporary failure.
|
||||
if ($this->inNoInteractionMode() && $attemptCount >= self::NON_INTERACTION_MAX_ATTEMPT_COUNT) {
|
||||
$this->components->warn("Maximum database connection attempts reached. Giving up.");
|
||||
break;
|
||||
}
|
||||
|
||||
$attemptCount++;
|
||||
|
||||
try {
|
||||
// Make sure the config cache is cleared before another attempt.
|
||||
$this->artisan->call('config:clear');
|
||||
$this->db->reconnect()->getPdo();
|
||||
|
||||
break;
|
||||
} catch (Throwable $e) {
|
||||
$this->error($e->getMessage());
|
||||
|
||||
// We only try to update credentials if running in interactive mode.
|
||||
// Otherwise, we require admin intervention to fix them.
|
||||
// This avoids inadvertently wiping credentials if there's a connection failure.
|
||||
if ($this->inNoInteractionMode()) {
|
||||
$warning = sprintf(
|
||||
"%sKoel cannot connect to the database. Attempt: %d/%d",
|
||||
PHP_EOL,
|
||||
$attemptCount,
|
||||
self::NON_INTERACTION_MAX_ATTEMPT_COUNT
|
||||
);
|
||||
$this->components->warn($warning);
|
||||
} else {
|
||||
$this->components->warn(
|
||||
sprintf("%sKoel cannot connect to the database. Let's set it up.", PHP_EOL)
|
||||
);
|
||||
|
||||
$this->setUpDatabase();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function migrateDatabase(): void
|
||||
{
|
||||
$this->components->info('Migrating database');
|
||||
$this->artisan->call('migrate', ['--force' => true]);
|
||||
|
||||
// Clear the media cache, just in case we did any media-related migration
|
||||
$this->mediaCacheService->clear();
|
||||
}
|
||||
|
||||
private function maybeCompileFrontEndAssets(): void
|
||||
{
|
||||
if ($this->inNoAssetsMode()) {
|
||||
|
@ -318,7 +333,8 @@ class InitCommand extends Command
|
|||
|
||||
private function setMediaPathFromEnvFile(): void
|
||||
{
|
||||
with(config('koel.media_path'), function (?string $path): void {
|
||||
$path = config('koel.media_path');
|
||||
|
||||
if (!$path) {
|
||||
return;
|
||||
}
|
||||
|
@ -328,11 +344,18 @@ class InitCommand extends Command
|
|||
} else {
|
||||
$this->components->warn(sprintf('The path %s does not exist or not readable. Skipping.', $path));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static function isValidMediaPath(string $path): bool
|
||||
{
|
||||
return is_dir($path) && is_readable($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random key for the application.
|
||||
*/
|
||||
private function generateRandomKey(): string
|
||||
{
|
||||
return 'base64:' . base64_encode(Encrypter::generateKey($this->laravel['config']['app.cipher']));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ use Laravel\Scout\Searchable;
|
|||
* @property string $id
|
||||
* @property int $artist_id
|
||||
* @property int $mtime
|
||||
* @property int $contributing_artist_id
|
||||
* @property ?bool $liked Whether the song is liked by the current user (dynamically calculated)
|
||||
* @property ?int $play_count The number of times the song has been played by the current user (dynamically calculated)
|
||||
* @property Carbon $created_at
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"aws/aws-sdk-php-laravel": "^3.1",
|
||||
"pusher/pusher-php-server": "^4.0",
|
||||
"predis/predis": "~1.0",
|
||||
"jackiedo/dotenv-editor": "^1.0",
|
||||
"jackiedo/dotenv-editor": "^2.0",
|
||||
"ext-exif": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-fileinfo": "*",
|
||||
|
@ -25,7 +25,7 @@
|
|||
"daverandom/resume": "^0.0.3",
|
||||
"laravel/helpers": "^1.0",
|
||||
"intervention/image": "^2.5",
|
||||
"doctrine/dbal": "^2.10",
|
||||
"doctrine/dbal": "^3.0",
|
||||
"lstrojny/functional-php": "^1.14",
|
||||
"teamtnt/laravel-scout-tntsearch-driver": "^11.1",
|
||||
"algolia/algoliasearch-client-php": "^3.3",
|
||||
|
|
168
composer.lock
generated
168
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "cdcb59dddec768e6cc821e1f6dffb72f",
|
||||
"content-hash": "310243edd4bc8d4f2184ff38520a52dd",
|
||||
"packages": [
|
||||
{
|
||||
"name": "algolia/algoliasearch-client-php",
|
||||
|
@ -639,35 +639,38 @@
|
|||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
"version": "2.13.9",
|
||||
"version": "3.3.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal.git",
|
||||
"reference": "c480849ca3ad6706a39c970cdfe6888fa8a058b8"
|
||||
"reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/c480849ca3ad6706a39c970cdfe6888fa8a058b8",
|
||||
"reference": "c480849ca3ad6706a39c970cdfe6888fa8a058b8",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/9f79d4650430b582f4598fe0954ef4d52fbc0a8a",
|
||||
"reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/cache": "^1.0|^2.0",
|
||||
"composer-runtime-api": "^2",
|
||||
"doctrine/cache": "^1.11|^2.0",
|
||||
"doctrine/deprecations": "^0.5.3|^1",
|
||||
"doctrine/event-manager": "^1.0",
|
||||
"ext-pdo": "*",
|
||||
"php": "^7.1 || ^8"
|
||||
"php": "^7.3 || ^8.0",
|
||||
"psr/cache": "^1|^2|^3",
|
||||
"psr/log": "^1|^2|^3"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "9.0.0",
|
||||
"jetbrains/phpstorm-stubs": "2021.1",
|
||||
"phpstan/phpstan": "1.4.6",
|
||||
"phpunit/phpunit": "^7.5.20|^8.5|9.5.16",
|
||||
"jetbrains/phpstorm-stubs": "2022.1",
|
||||
"phpstan/phpstan": "1.7.13",
|
||||
"phpstan/phpstan-strict-rules": "^1.2",
|
||||
"phpunit/phpunit": "9.5.20",
|
||||
"psalm/plugin-phpunit": "0.16.1",
|
||||
"squizlabs/php_codesniffer": "3.6.2",
|
||||
"symfony/cache": "^4.4",
|
||||
"symfony/console": "^2.0.5|^3.0|^4.0|^5.0",
|
||||
"vimeo/psalm": "4.22.0"
|
||||
"squizlabs/php_codesniffer": "3.7.0",
|
||||
"symfony/cache": "^5.2|^6.0",
|
||||
"symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0",
|
||||
"vimeo/psalm": "4.23.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/console": "For helpful console commands such as SQL execution and import of files."
|
||||
|
@ -678,7 +681,7 @@
|
|||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\DBAL\\": "lib/Doctrine/DBAL"
|
||||
"Doctrine\\DBAL\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
|
@ -721,14 +724,13 @@
|
|||
"queryobject",
|
||||
"sasql",
|
||||
"sql",
|
||||
"sqlanywhere",
|
||||
"sqlite",
|
||||
"sqlserver",
|
||||
"sqlsrv"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/dbal/issues",
|
||||
"source": "https://github.com/doctrine/dbal/tree/2.13.9"
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.3.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -744,7 +746,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-05-02T20:28:55+00:00"
|
||||
"time": "2022-06-13T21:43:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
|
@ -1900,26 +1902,29 @@
|
|||
},
|
||||
{
|
||||
"name": "jackiedo/dotenv-editor",
|
||||
"version": "1.1.2",
|
||||
"version": "2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/JackieDo/Laravel-Dotenv-Editor.git",
|
||||
"reference": "44062c804e6fa777c01d9fba3bd8fe9a57ec25f0"
|
||||
"reference": "0971d876567b4bcf96078f8e55700b4726431704"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/JackieDo/Laravel-Dotenv-Editor/zipball/44062c804e6fa777c01d9fba3bd8fe9a57ec25f0",
|
||||
"reference": "44062c804e6fa777c01d9fba3bd8fe9a57ec25f0",
|
||||
"url": "https://api.github.com/repos/JackieDo/Laravel-Dotenv-Editor/zipball/0971d876567b4bcf96078f8e55700b4726431704",
|
||||
"reference": "0971d876567b4bcf96078f8e55700b4726431704",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/config": ">=5.0",
|
||||
"illuminate/container": ">=5.0",
|
||||
"illuminate/support": ">=5.0",
|
||||
"php": ">=5.4.0"
|
||||
"illuminate/console": "^9.0|^8.0|7.0|^6.0|^5.8",
|
||||
"illuminate/contracts": "^9.0|^8.0|7.0|^6.0|^5.8",
|
||||
"illuminate/support": "^9.0|^8.0|7.0|^6.0|^5.8",
|
||||
"jackiedo/path-helper": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Jackiedo\\DotenvEditor\\DotenvEditorServiceProvider"
|
||||
|
@ -1931,7 +1936,7 @@
|
|||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Jackiedo\\DotenvEditor\\": "src/Jackiedo/DotenvEditor"
|
||||
"Jackiedo\\DotenvEditor\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
|
@ -1944,7 +1949,7 @@
|
|||
"email": "anhvudo@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "The .env file editor tool for Laravel 5+",
|
||||
"description": "The .env file editor tool for Laravel 5.8+",
|
||||
"keywords": [
|
||||
"dotenv",
|
||||
"dotenv-editor",
|
||||
|
@ -1952,9 +1957,61 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/JackieDo/Laravel-Dotenv-Editor/issues",
|
||||
"source": "https://github.com/JackieDo/Laravel-Dotenv-Editor/tree/master"
|
||||
"source": "https://github.com/JackieDo/Laravel-Dotenv-Editor/tree/2.0.1"
|
||||
},
|
||||
"time": "2020-06-07T00:55:45+00:00"
|
||||
"time": "2022-03-10T17:04:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jackiedo/path-helper",
|
||||
"version": "v1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/JackieDo/Path-Helper.git",
|
||||
"reference": "43179cfa17d01f94f4889f286430c2cec1071fb2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/JackieDo/Path-Helper/zipball/43179cfa17d01f94f4889f286430c2cec1071fb2",
|
||||
"reference": "43179cfa17d01f94f4889f286430c2cec1071fb2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Jackiedo\\PathHelper\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jackie Do",
|
||||
"email": "anhvudo@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Helper class for working with local paths in PHP",
|
||||
"homepage": "https://github.com/JackieDo/path-helper",
|
||||
"keywords": [
|
||||
"helper",
|
||||
"helpers",
|
||||
"library",
|
||||
"path",
|
||||
"paths",
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/JackieDo/Path-Helper/issues",
|
||||
"source": "https://github.com/JackieDo/Path-Helper/tree/v1.0.0"
|
||||
},
|
||||
"time": "2022-03-07T20:28:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "james-heinrich/getid3",
|
||||
|
@ -4369,6 +4426,55 @@
|
|||
],
|
||||
"time": "2022-01-05T17:46:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
"version": "3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/cache.git",
|
||||
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
|
||||
"reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Cache\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for caching libraries",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"psr",
|
||||
"psr-6"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/cache/tree/3.0.0"
|
||||
},
|
||||
"time": "2021-02-03T23:26:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "2.0.2",
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class RenameContributingArtistId extends Migration
|
||||
|
@ -10,29 +9,7 @@ class RenameContributingArtistId extends Migration
|
|||
public function up(): void
|
||||
{
|
||||
Schema::table('songs', static function (Blueprint $table): void {
|
||||
if (DB::getDriverName() !== 'sqlite') { // @phpstan-ignore-line
|
||||
$table->dropForeign(['contributing_artist_id']);
|
||||
}
|
||||
});
|
||||
|
||||
Schema::table('songs', static function (Blueprint $table): void {
|
||||
$table->renameColumn('contributing_artist_id', 'artist_id');
|
||||
$table->foreign('artist_id')->references('id')->on('artists')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('songs', static function (Blueprint $table): void {
|
||||
if (DB::getDriverName() !== 'sqlite') { // @phpstan-ignore-line
|
||||
$table->dropForeign(['contributing_artist_id']);
|
||||
}
|
||||
|
||||
$table->renameColumn('artist_id', 'contributing_artist_id');
|
||||
$table->integer('artist_id')->unsigned()->nullable();
|
||||
$table->foreign('artist_id')->references('id')->on('artists')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue