[
MAINHACK
]
Mail Test
BC
Config Scan
HOME
Create...
New File
New Folder
Viewing / Editing File: InstallCommand.php
<?php namespace Laravel\Jetstream\Console; use Exception; use Illuminate\Console\Command; use Illuminate\Contracts\Console\PromptsForMissingInput; use Illuminate\Filesystem\Filesystem; use Illuminate\Support\Arr; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Str; use RuntimeException; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Finder\Finder; use Symfony\Component\Process\PhpExecutableFinder; use Symfony\Component\Process\Process; use function Laravel\Prompts\confirm; use function Laravel\Prompts\multiselect; use function Laravel\Prompts\select; #[AsCommand(name: 'jetstream:install')] class InstallCommand extends Command implements PromptsForMissingInput { /** * The name and signature of the console command. * * @var string */ protected $signature = 'jetstream:install {stack : The development stack that should be installed (inertia,livewire)} {--dark : Indicate that dark mode support should be installed} {--teams : Indicates if team support should be installed} {--api : Indicates if API support should be installed} {--verification : Indicates if email verification support should be installed} {--pest : Indicates if Pest should be installed} {--ssr : Indicates if Inertia SSR support should be installed} {--composer=global : Absolute path to the Composer binary which should be used to install packages}'; /** * The console command description. * * @var string */ protected $description = 'Install the Jetstream components and resources'; /** * Execute the console command. * * @return int|null */ public function handle() { if (! in_array($this->argument('stack'), ['inertia', 'livewire'])) { $this->components->error('Invalid stack. Supported stacks are [inertia] and [livewire].'); return 1; } // Publish... $this->callSilent('vendor:publish', ['--tag' => 'jetstream-config', '--force' => true]); $this->callSilent('vendor:publish', ['--tag' => 'jetstream-migrations', '--force' => true]); $this->callSilent('vendor:publish', ['--tag' => 'fortify-config', '--force' => true]); $this->callSilent('vendor:publish', ['--tag' => 'fortify-support', '--force' => true]); $this->callSilent('vendor:publish', ['--tag' => 'fortify-migrations', '--force' => true]); // Storage... $this->callSilent('storage:link'); $this->replaceInFile('/home', '/dashboard', config_path('fortify.php')); if (file_exists(resource_path('views/welcome.blade.php'))) { $this->replaceInFile('/home', '/dashboard', resource_path('views/welcome.blade.php')); $this->replaceInFile('Home', 'Dashboard', resource_path('views/welcome.blade.php')); } // Fortify Provider... ServiceProvider::addProviderToBootstrapFile('App\Providers\FortifyServiceProvider'); // Configure Session... $this->configureSession(); // Configure API... if ($this->option('api')) { $this->replaceInFile('// Features::api(),', 'Features::api(),', config_path('jetstream.php')); } // Configure Email Verification... if ($this->option('verification')) { $this->replaceInFile('// Features::emailVerification(),', 'Features::emailVerification(),', config_path('fortify.php')); } // Install Stack... if ($this->argument('stack') === 'livewire') { if (! $this->installLivewireStack()) { return 1; } } elseif ($this->argument('stack') === 'inertia') { if (! $this->installInertiaStack()) { return 1; } } // Emails... (new Filesystem)->ensureDirectoryExists(resource_path('views/emails')); (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/resources/views/emails', resource_path('views/emails')); // Tests... $stubs = $this->getTestStubsPath(); if ($this->option('pest') || $this->isUsingPest()) { if ($this->hasComposerPackage('phpunit/phpunit')) { $this->removeComposerDevPackages(['phpunit/phpunit']); } if (! $this->requireComposerDevPackages(['pestphp/pest', 'pestphp/pest-plugin-laravel'])) { return 1; } copy($stubs.'/Pest.php', base_path('tests/Pest.php')); copy($stubs.'/ExampleTest.php', base_path('tests/Feature/ExampleTest.php')); copy($stubs.'/ExampleUnitTest.php', base_path('tests/Unit/ExampleTest.php')); } copy($stubs.'/AuthenticationTest.php', base_path('tests/Feature/AuthenticationTest.php')); copy($stubs.'/EmailVerificationTest.php', base_path('tests/Feature/EmailVerificationTest.php')); copy($stubs.'/PasswordConfirmationTest.php', base_path('tests/Feature/PasswordConfirmationTest.php')); copy($stubs.'/PasswordResetTest.php', base_path('tests/Feature/PasswordResetTest.php')); copy($stubs.'/RegistrationTest.php', base_path('tests/Feature/RegistrationTest.php')); } /** * Configure the session driver for Jetstream. * * @return void */ protected function configureSession() { $this->replaceInFile('SESSION_DRIVER=cookie', 'SESSION_DRIVER=database', base_path('.env')); $this->replaceInFile('SESSION_DRIVER=cookie', 'SESSION_DRIVER=database', base_path('.env.example')); } /** * Install the Livewire stack into the application. * * @return bool */ protected function installLivewireStack() { // Install Livewire... if (! $this->requireComposerPackages('livewire/livewire:^3.0')) { return false; } $this->call('install:api', [ '--without-migration-prompt' => true, ]); // Update Configuration... $this->replaceInFile('inertia', 'livewire', config_path('jetstream.php')); // NPM Packages... $this->updateNodePackages(function ($packages) { return [ '@tailwindcss/forms' => '^0.5.7', '@tailwindcss/typography' => '^0.5.10', 'autoprefixer' => '^10.4.16', 'postcss' => '^8.4.32', 'tailwindcss' => '^3.4.0', ] + $packages; }); // Tailwind Configuration... copy(__DIR__.'/../../stubs/livewire/tailwind.config.js', base_path('tailwind.config.js')); copy(__DIR__.'/../../stubs/livewire/postcss.config.js', base_path('postcss.config.js')); copy(__DIR__.'/../../stubs/livewire/vite.config.js', base_path('vite.config.js')); // Directories... (new Filesystem)->ensureDirectoryExists(app_path('Actions/Fortify')); (new Filesystem)->ensureDirectoryExists(app_path('Actions/Jetstream')); (new Filesystem)->ensureDirectoryExists(app_path('View/Components')); (new Filesystem)->ensureDirectoryExists(resource_path('css')); (new Filesystem)->ensureDirectoryExists(resource_path('markdown')); (new Filesystem)->ensureDirectoryExists(resource_path('views/api')); (new Filesystem)->ensureDirectoryExists(resource_path('views/auth')); (new Filesystem)->ensureDirectoryExists(resource_path('views/components')); (new Filesystem)->ensureDirectoryExists(resource_path('views/layouts')); (new Filesystem)->ensureDirectoryExists(resource_path('views/profile')); (new Filesystem)->deleteDirectory(resource_path('sass')); // Terms Of Service / Privacy Policy... copy(__DIR__.'/../../stubs/resources/markdown/terms.md', resource_path('markdown/terms.md')); copy(__DIR__.'/../../stubs/resources/markdown/policy.md', resource_path('markdown/policy.md')); // Service Providers... copy(__DIR__.'/../../stubs/app/Providers/JetstreamServiceProvider.php', $provider = app_path('Providers/JetstreamServiceProvider.php')); $this->replaceInFile([ PHP_EOL.'use Illuminate\Support\Facades\Vite;', PHP_EOL.PHP_EOL.' Vite::prefetch(concurrency: 3);', ], '', $provider); ServiceProvider::addProviderToBootstrapFile('App\Providers\JetstreamServiceProvider'); // Models... copy(__DIR__.'/../../stubs/app/Models/User.php', app_path('Models/User.php')); // Factories... copy(__DIR__.'/../../database/factories/UserFactory.php', base_path('database/factories/UserFactory.php')); // Actions... copy(__DIR__.'/../../stubs/app/Actions/Fortify/CreateNewUser.php', app_path('Actions/Fortify/CreateNewUser.php')); copy(__DIR__.'/../../stubs/app/Actions/Fortify/UpdateUserProfileInformation.php', app_path('Actions/Fortify/UpdateUserProfileInformation.php')); copy(__DIR__.'/../../stubs/app/Actions/Jetstream/DeleteUser.php', app_path('Actions/Jetstream/DeleteUser.php')); // Components... (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/livewire/resources/views/components', resource_path('views/components')); // View Components... copy(__DIR__.'/../../stubs/livewire/app/View/Components/AppLayout.php', app_path('View/Components/AppLayout.php')); copy(__DIR__.'/../../stubs/livewire/app/View/Components/GuestLayout.php', app_path('View/Components/GuestLayout.php')); // Layouts... (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/livewire/resources/views/layouts', resource_path('views/layouts')); // Single Blade Views... copy(__DIR__.'/../../stubs/livewire/resources/views/dashboard.blade.php', resource_path('views/dashboard.blade.php')); copy(__DIR__.'/../../stubs/livewire/resources/views/navigation-menu.blade.php', resource_path('views/navigation-menu.blade.php')); copy(__DIR__.'/../../stubs/livewire/resources/views/terms.blade.php', resource_path('views/terms.blade.php')); copy(__DIR__.'/../../stubs/livewire/resources/views/policy.blade.php', resource_path('views/policy.blade.php')); // Other Views... (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/livewire/resources/views/api', resource_path('views/api')); (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/livewire/resources/views/profile', resource_path('views/profile')); (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/livewire/resources/views/auth', resource_path('views/auth')); if (! Str::contains(file_get_contents(base_path('routes/web.php')), "'/dashboard'")) { (new Filesystem)->append(base_path('routes/web.php'), $this->livewireRouteDefinition()); } // Assets... copy(__DIR__.'/../../stubs/resources/css/app.css', resource_path('css/app.css')); // Tests... $stubs = $this->getTestStubsPath(); copy($stubs.'/livewire/ApiTokenPermissionsTest.php', base_path('tests/Feature/ApiTokenPermissionsTest.php')); copy($stubs.'/livewire/BrowserSessionsTest.php', base_path('tests/Feature/BrowserSessionsTest.php')); copy($stubs.'/livewire/CreateApiTokenTest.php', base_path('tests/Feature/CreateApiTokenTest.php')); copy($stubs.'/livewire/DeleteAccountTest.php', base_path('tests/Feature/DeleteAccountTest.php')); copy($stubs.'/livewire/DeleteApiTokenTest.php', base_path('tests/Feature/DeleteApiTokenTest.php')); copy($stubs.'/livewire/ProfileInformationTest.php', base_path('tests/Feature/ProfileInformationTest.php')); copy($stubs.'/livewire/TwoFactorAuthenticationSettingsTest.php', base_path('tests/Feature/TwoFactorAuthenticationSettingsTest.php')); copy($stubs.'/livewire/UpdatePasswordTest.php', base_path('tests/Feature/UpdatePasswordTest.php')); // Teams... if ($this->option('teams')) { $this->installLivewireTeamStack(); } if (! $this->option('dark')) { $this->removeDarkClasses((new Finder) ->in(resource_path('views')) ->name('*.blade.php') ->filter(fn ($file) => $file->getPathname() !== resource_path('views/welcome.blade.php')) ); } if (file_exists(base_path('pnpm-lock.yaml'))) { $this->runCommands(['pnpm install', 'pnpm run build']); } elseif (file_exists(base_path('yarn.lock'))) { $this->runCommands(['yarn install', 'yarn run build']); } else { $this->runCommands(['npm install', 'npm run build']); } $this->line(''); $this->runDatabaseMigrations(); $this->components->info('Livewire scaffolding installed successfully.'); return true; } /** * Install the Livewire team stack into the application. * * @return void */ protected function installLivewireTeamStack() { // Directories... (new Filesystem)->ensureDirectoryExists(resource_path('views/teams')); // Other Views... (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/livewire/resources/views/teams', resource_path('views/teams')); // Tests... $stubs = $this->getTestStubsPath(); copy($stubs.'/livewire/CreateTeamTest.php', base_path('tests/Feature/CreateTeamTest.php')); copy($stubs.'/livewire/DeleteTeamTest.php', base_path('tests/Feature/DeleteTeamTest.php')); copy($stubs.'/livewire/InviteTeamMemberTest.php', base_path('tests/Feature/InviteTeamMemberTest.php')); copy($stubs.'/livewire/LeaveTeamTest.php', base_path('tests/Feature/LeaveTeamTest.php')); copy($stubs.'/livewire/RemoveTeamMemberTest.php', base_path('tests/Feature/RemoveTeamMemberTest.php')); copy($stubs.'/livewire/UpdateTeamMemberRoleTest.php', base_path('tests/Feature/UpdateTeamMemberRoleTest.php')); copy($stubs.'/livewire/UpdateTeamNameTest.php', base_path('tests/Feature/UpdateTeamNameTest.php')); $this->ensureApplicationIsTeamCompatible(); } /** * Get the route definition(s) that should be installed for Livewire. * * @return string */ protected function livewireRouteDefinition() { return <<<'EOF' Route::middleware([ 'auth:sanctum', config('jetstream.auth_session'), 'verified', ])->group(function () { Route::get('/dashboard', function () { return view('dashboard'); })->name('dashboard'); }); EOF; } /** * Install the Inertia stack into the application. * * @return bool */ protected function installInertiaStack() { // Install Inertia... if (! $this->requireComposerPackages('inertiajs/inertia-laravel:^1.0', 'tightenco/ziggy:^2.0')) { return false; } $this->call('install:api', [ '--without-migration-prompt' => true, ]); // Install NPM packages... $this->updateNodePackages(function ($packages) { return [ '@inertiajs/vue3' => '^1.0.14', '@tailwindcss/forms' => '^0.5.7', '@tailwindcss/typography' => '^0.5.10', '@vitejs/plugin-vue' => '^5.0.0', 'autoprefixer' => '^10.4.16', 'postcss' => '^8.4.32', 'tailwindcss' => '^3.4.0', 'vue' => '^3.3.13', ] + $packages; }); // Tailwind Configuration... copy(__DIR__.'/../../stubs/inertia/tailwind.config.js', base_path('tailwind.config.js')); copy(__DIR__.'/../../stubs/inertia/postcss.config.js', base_path('postcss.config.js')); copy(__DIR__.'/../../stubs/inertia/vite.config.js', base_path('vite.config.js')); // jsconfig.json... copy(__DIR__.'/../../stubs/inertia/jsconfig.json', base_path('jsconfig.json')); // Directories... (new Filesystem)->ensureDirectoryExists(app_path('Actions/Fortify')); (new Filesystem)->ensureDirectoryExists(app_path('Actions/Jetstream')); (new Filesystem)->ensureDirectoryExists(resource_path('css')); (new Filesystem)->ensureDirectoryExists(resource_path('js/Components')); (new Filesystem)->ensureDirectoryExists(resource_path('js/Layouts')); (new Filesystem)->ensureDirectoryExists(resource_path('js/Pages')); (new Filesystem)->ensureDirectoryExists(resource_path('js/Pages/API')); (new Filesystem)->ensureDirectoryExists(resource_path('js/Pages/Auth')); (new Filesystem)->ensureDirectoryExists(resource_path('js/Pages/Profile')); (new Filesystem)->ensureDirectoryExists(resource_path('views')); (new Filesystem)->ensureDirectoryExists(resource_path('markdown')); (new Filesystem)->deleteDirectory(resource_path('sass')); // Terms Of Service / Privacy Policy... copy(__DIR__.'/../../stubs/resources/markdown/terms.md', resource_path('markdown/terms.md')); copy(__DIR__.'/../../stubs/resources/markdown/policy.md', resource_path('markdown/policy.md')); // Service Providers... copy(__DIR__.'/../../stubs/app/Providers/JetstreamServiceProvider.php', app_path('Providers/JetstreamServiceProvider.php')); ServiceProvider::addProviderToBootstrapFile('App\Providers\JetstreamServiceProvider'); // Middleware... (new Filesystem)->ensureDirectoryExists(app_path('Http/Middleware')); (new Process([$this->phpBinary(), 'artisan', 'inertia:middleware', 'HandleInertiaRequests', '--force'], base_path())) ->setTimeout(null) ->run(function ($type, $output) { $this->output->write($output); }); $this->installMiddleware([ '\App\Http\Middleware\HandleInertiaRequests::class', '\Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class', ]); // Models... copy(__DIR__.'/../../stubs/app/Models/User.php', app_path('Models/User.php')); // Factories... copy(__DIR__.'/../../database/factories/UserFactory.php', base_path('database/factories/UserFactory.php')); // Actions... copy(__DIR__.'/../../stubs/app/Actions/Fortify/CreateNewUser.php', app_path('Actions/Fortify/CreateNewUser.php')); copy(__DIR__.'/../../stubs/app/Actions/Fortify/UpdateUserProfileInformation.php', app_path('Actions/Fortify/UpdateUserProfileInformation.php')); copy(__DIR__.'/../../stubs/app/Actions/Jetstream/DeleteUser.php', app_path('Actions/Jetstream/DeleteUser.php')); // Blade Views... copy(__DIR__.'/../../stubs/inertia/resources/views/app.blade.php', resource_path('views/app.blade.php')); if (file_exists(resource_path('views/welcome.blade.php'))) { unlink(resource_path('views/welcome.blade.php')); } // Inertia Pages... copy(__DIR__.'/../../stubs/inertia/resources/js/Pages/Dashboard.vue', resource_path('js/Pages/Dashboard.vue')); copy(__DIR__.'/../../stubs/inertia/resources/js/Pages/PrivacyPolicy.vue', resource_path('js/Pages/PrivacyPolicy.vue')); copy(__DIR__.'/../../stubs/inertia/resources/js/Pages/TermsOfService.vue', resource_path('js/Pages/TermsOfService.vue')); copy(__DIR__.'/../../stubs/inertia/resources/js/Pages/Welcome.vue', resource_path('js/Pages/Welcome.vue')); (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/inertia/resources/js/Components', resource_path('js/Components')); (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/inertia/resources/js/Layouts', resource_path('js/Layouts')); (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/inertia/resources/js/Pages/API', resource_path('js/Pages/API')); (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/inertia/resources/js/Pages/Auth', resource_path('js/Pages/Auth')); (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/inertia/resources/js/Pages/Profile', resource_path('js/Pages/Profile')); copy(__DIR__.'/../../stubs/inertia/routes/web.php', base_path('routes/web.php')); // Assets... copy(__DIR__.'/../../stubs/resources/css/app.css', resource_path('css/app.css')); copy(__DIR__.'/../../stubs/inertia/resources/js/app.js', resource_path('js/app.js')); // Tests... $stubs = $this->getTestStubsPath(); copy($stubs.'/inertia/ApiTokenPermissionsTest.php', base_path('tests/Feature/ApiTokenPermissionsTest.php')); copy($stubs.'/inertia/BrowserSessionsTest.php', base_path('tests/Feature/BrowserSessionsTest.php')); copy($stubs.'/inertia/CreateApiTokenTest.php', base_path('tests/Feature/CreateApiTokenTest.php')); copy($stubs.'/inertia/DeleteAccountTest.php', base_path('tests/Feature/DeleteAccountTest.php')); copy($stubs.'/inertia/DeleteApiTokenTest.php', base_path('tests/Feature/DeleteApiTokenTest.php')); copy($stubs.'/inertia/ProfileInformationTest.php', base_path('tests/Feature/ProfileInformationTest.php')); copy($stubs.'/inertia/TwoFactorAuthenticationSettingsTest.php', base_path('tests/Feature/TwoFactorAuthenticationSettingsTest.php')); copy($stubs.'/inertia/UpdatePasswordTest.php', base_path('tests/Feature/UpdatePasswordTest.php')); // Teams... if ($this->option('teams')) { $this->installInertiaTeamStack(); } if ($this->option('ssr')) { $this->installInertiaSsrStack(); } if (! $this->option('dark')) { $this->removeDarkClasses((new Finder) ->in(resource_path('js')) ->name('*.vue') ->notPath('Pages/Welcome.vue') ); } if (file_exists(base_path('pnpm-lock.yaml'))) { $this->runCommands(['pnpm install', 'pnpm run build']); } elseif (file_exists(base_path('yarn.lock'))) { $this->runCommands(['yarn install', 'yarn run build']); } else { $this->runCommands(['npm install', 'npm run build']); } $this->line(''); $this->runDatabaseMigrations(); $this->components->info('Inertia scaffolding installed successfully.'); return true; } /** * Install the Inertia team stack into the application. * * @return void */ protected function installInertiaTeamStack() { // Directories... (new Filesystem)->ensureDirectoryExists(resource_path('js/Pages/Profile')); // Pages... (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/inertia/resources/js/Pages/Teams', resource_path('js/Pages/Teams')); // Tests... $stubs = $this->getTestStubsPath(); copy($stubs.'/inertia/CreateTeamTest.php', base_path('tests/Feature/CreateTeamTest.php')); copy($stubs.'/inertia/DeleteTeamTest.php', base_path('tests/Feature/DeleteTeamTest.php')); copy($stubs.'/inertia/InviteTeamMemberTest.php', base_path('tests/Feature/InviteTeamMemberTest.php')); copy($stubs.'/inertia/LeaveTeamTest.php', base_path('tests/Feature/LeaveTeamTest.php')); copy($stubs.'/inertia/RemoveTeamMemberTest.php', base_path('tests/Feature/RemoveTeamMemberTest.php')); copy($stubs.'/inertia/UpdateTeamMemberRoleTest.php', base_path('tests/Feature/UpdateTeamMemberRoleTest.php')); copy($stubs.'/inertia/UpdateTeamNameTest.php', base_path('tests/Feature/UpdateTeamNameTest.php')); $this->ensureApplicationIsTeamCompatible(); } /** * Ensure the installed user model is ready for team usage. * * @return void */ protected function ensureApplicationIsTeamCompatible() { // Publish Team Migrations... $this->callSilent('vendor:publish', ['--tag' => 'jetstream-team-migrations', '--force' => true]); // Configuration... $this->replaceInFile('// Features::teams([\'invitations\' => true])', 'Features::teams([\'invitations\' => true])', config_path('jetstream.php')); // Directories... (new Filesystem)->ensureDirectoryExists(app_path('Actions/Jetstream')); (new Filesystem)->ensureDirectoryExists(app_path('Events')); (new Filesystem)->ensureDirectoryExists(app_path('Policies')); // Service Providers... copy(__DIR__.'/../../stubs/app/Providers/JetstreamWithTeamsServiceProvider.php', app_path('Providers/JetstreamServiceProvider.php')); // Models... copy(__DIR__.'/../../stubs/app/Models/Membership.php', app_path('Models/Membership.php')); copy(__DIR__.'/../../stubs/app/Models/Team.php', app_path('Models/Team.php')); copy(__DIR__.'/../../stubs/app/Models/TeamInvitation.php', app_path('Models/TeamInvitation.php')); copy(__DIR__.'/../../stubs/app/Models/UserWithTeams.php', app_path('Models/User.php')); // Actions... copy(__DIR__.'/../../stubs/app/Actions/Jetstream/AddTeamMember.php', app_path('Actions/Jetstream/AddTeamMember.php')); copy(__DIR__.'/../../stubs/app/Actions/Jetstream/CreateTeam.php', app_path('Actions/Jetstream/CreateTeam.php')); copy(__DIR__.'/../../stubs/app/Actions/Jetstream/DeleteTeam.php', app_path('Actions/Jetstream/DeleteTeam.php')); copy(__DIR__.'/../../stubs/app/Actions/Jetstream/DeleteUserWithTeams.php', app_path('Actions/Jetstream/DeleteUser.php')); copy(__DIR__.'/../../stubs/app/Actions/Jetstream/InviteTeamMember.php', app_path('Actions/Jetstream/InviteTeamMember.php')); copy(__DIR__.'/../../stubs/app/Actions/Jetstream/RemoveTeamMember.php', app_path('Actions/Jetstream/RemoveTeamMember.php')); copy(__DIR__.'/../../stubs/app/Actions/Jetstream/UpdateTeamName.php', app_path('Actions/Jetstream/UpdateTeamName.php')); copy(__DIR__.'/../../stubs/app/Actions/Fortify/CreateNewUserWithTeams.php', app_path('Actions/Fortify/CreateNewUser.php')); // Policies... (new Filesystem)->copyDirectory(__DIR__.'/../../stubs/app/Policies', app_path('Policies')); // Factories... copy(__DIR__.'/../../database/factories/UserFactory.php', base_path('database/factories/UserFactory.php')); copy(__DIR__.'/../../database/factories/TeamFactory.php', base_path('database/factories/TeamFactory.php')); // Seeders... copy(__DIR__.'/../../database/seeders/DatabaseSeeder.php', base_path('database/seeders/DatabaseSeeder.php')); } /** * Install the Inertia SSR stack into the application. * * @return void */ protected function installInertiaSsrStack() { $this->updateNodePackages(function ($packages) { return [ '@vue/server-renderer' => '^3.3.13', ] + $packages; }); copy(__DIR__.'/../../stubs/inertia/resources/js/ssr.js', resource_path('js/ssr.js')); $this->replaceInFile("input: 'resources/js/app.js',", "input: 'resources/js/app.js',".PHP_EOL." ssr: 'resources/js/ssr.js',", base_path('vite.config.js')); (new Filesystem)->ensureDirectoryExists(app_path('Http/Middleware')); copy(__DIR__.'/../../stubs/inertia/app/Http/Middleware/HandleInertiaRequests.php', app_path('Http/Middleware/HandleInertiaRequests.php')); $this->replaceInFile('vite build', 'vite build && vite build --ssr', base_path('package.json')); $this->replaceInFile('/node_modules', '/bootstrap/ssr'.PHP_EOL.'/node_modules', base_path('.gitignore')); } /** * Install the given middleware names into the application. * * @param array|string $name * @param string $group * @param string $modifier * @return void */ protected function installMiddleware($names, $group = 'web', $modifier = 'append') { $bootstrapApp = file_get_contents(base_path('bootstrap/app.php')); $names = collect(Arr::wrap($names)) ->filter(fn ($name) => ! Str::contains($bootstrapApp, $name)) ->whenNotEmpty(function ($names) use ($bootstrapApp, $group, $modifier) { $names = $names->map(fn ($name) => "$name")->implode(','.PHP_EOL.' '); $bootstrapApp = str_replace( '->withMiddleware(function (Middleware $middleware) {', '->withMiddleware(function (Middleware $middleware) {' .PHP_EOL." \$middleware->$group($modifier: [" .PHP_EOL." $names," .PHP_EOL.' ]);' .PHP_EOL, $bootstrapApp, ); file_put_contents(base_path('bootstrap/app.php'), $bootstrapApp); }); } /** * Returns the path to the correct test stubs. * * @return string */ protected function getTestStubsPath() { return $this->option('pest') || $this->isUsingPest() ? __DIR__.'/../../stubs/pest-tests' : __DIR__.'/../../stubs/tests'; } /** * Determine if the given Composer package is installed. * * @param string $package * @return bool */ protected function hasComposerPackage($package) { $packages = json_decode(file_get_contents(base_path('composer.json')), true); return array_key_exists($package, $packages['require'] ?? []) || array_key_exists($package, $packages['require-dev'] ?? []); } /** * Installs the given Composer Packages into the application. * * @param mixed $packages * @return bool */ protected function requireComposerPackages($packages) { $composer = $this->option('composer'); if ($composer !== 'global') { $command = [$this->phpBinary(), $composer, 'require']; } $command = array_merge( $command ?? ['composer', 'require'], is_array($packages) ? $packages : func_get_args() ); return ! (new Process($command, base_path(), ['COMPOSER_MEMORY_LIMIT' => '-1'])) ->setTimeout(null) ->run(function ($type, $output) { $this->output->write($output); }); } /** * Removes the given Composer Packages as "dev" dependencies. * * @param mixed $packages * @return bool */ protected function removeComposerDevPackages($packages) { $composer = $this->option('composer'); if ($composer !== 'global') { $command = [$this->phpBinary(), $composer, 'remove', '--dev']; } $command = array_merge( $command ?? ['composer', 'remove', '--dev'], is_array($packages) ? $packages : func_get_args() ); return (new Process($command, base_path(), ['COMPOSER_MEMORY_LIMIT' => '-1'])) ->setTimeout(null) ->run(function ($type, $output) { $this->output->write($output); }) === 0; } /** * Install the given Composer Packages as "dev" dependencies. * * @param mixed $packages * @return bool */ protected function requireComposerDevPackages($packages) { $composer = $this->option('composer'); if ($composer !== 'global') { $command = [$this->phpBinary(), $composer, 'require', '--dev']; } $command = array_merge( $command ?? ['composer', 'require', '--dev'], is_array($packages) ? $packages : func_get_args() ); return (new Process($command, base_path(), ['COMPOSER_MEMORY_LIMIT' => '-1'])) ->setTimeout(null) ->run(function ($type, $output) { $this->output->write($output); }) === 0; } /** * Update the "package.json" file. * * @param callable $callback * @param bool $dev * @return void */ protected static function updateNodePackages(callable $callback, $dev = true) { if (! file_exists(base_path('package.json'))) { return; } $configurationKey = $dev ? 'devDependencies' : 'dependencies'; $packages = json_decode(file_get_contents(base_path('package.json')), true); $packages[$configurationKey] = $callback( array_key_exists($configurationKey, $packages) ? $packages[$configurationKey] : [], $configurationKey ); ksort($packages[$configurationKey]); file_put_contents( base_path('package.json'), json_encode($packages, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT).PHP_EOL ); } /** * Run the database migrations. * * @return void */ protected function runDatabaseMigrations() { if (confirm('New database migrations were added. Would you like to re-run your migrations?', true)) { (new Process([$this->phpBinary(), 'artisan', 'migrate:fresh', '--force'], base_path())) ->setTimeout(null) ->run(function ($type, $output) { $this->output->write($output); }); } } /** * Replace a given string within a given file. * * @param string $replace * @param string|array $search * @param string $path * @return void */ protected function replaceInFile($search, $replace, $path) { file_put_contents($path, str_replace($search, $replace, file_get_contents($path))); } /** * Remove Tailwind dark classes from the given files. * * @param \Symfony\Component\Finder\Finder $finder * @return void */ protected function removeDarkClasses(Finder $finder) { foreach ($finder as $file) { file_put_contents($file->getPathname(), preg_replace('/\sdark:[^\s"\']+/', '', $file->getContents())); } } /** * Get the path to the appropriate PHP binary. * * @return string */ protected function phpBinary() { if (function_exists('Illuminate\Support\php_binary')) { return \Illuminate\Support\php_binary(); } return (new PhpExecutableFinder())->find(false) ?: 'php'; } /** * Run the given commands. * * @param array $commands * @return void */ protected function runCommands($commands) { $process = Process::fromShellCommandline(implode(' && ', $commands), null, null, null, null); if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) { try { $process->setTty(true); } catch (RuntimeException $e) { $this->output->writeln(' <bg=yellow;fg=black> WARN </> '.$e->getMessage().PHP_EOL); } } $process->run(function ($type, $line) { $this->output->write(' '.$line); }); } /** * Prompt for missing input arguments using the returned questions. * * @return array */ protected function promptForMissingArgumentsUsing() { return [ 'stack' => fn () => select( label: 'Which Jetstream stack would you like to install?', options: [ 'inertia' => 'Vue with Inertia', 'livewire' => 'Livewire', ] ), ]; } /** * Interact further with the user if they were prompted for missing arguments. * * @param \Symfony\Component\Console\Input\InputInterface $input * @param \Symfony\Component\Console\Output\OutputInterface $output * @return void */ protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output) { collect(multiselect( label: 'Would you like any optional features?', options: collect([ 'teams' => 'Team support', 'api' => 'API support', 'verification' => 'Email verification', 'dark' => 'Dark mode', ])->when( $input->getArgument('stack') === 'inertia', fn ($options) => $options->put('ssr', 'Inertia SSR') )->sort()->all(), ))->each(fn ($option) => $input->setOption($option, true)); $input->setOption('pest', select( label: 'Which testing framework do you prefer?', options: ['Pest', 'PHPUnit'], default: 'Pest', ) === 'Pest'); } /** * Determine whether the project is already using Pest. * * @return bool */ protected function isUsingPest() { return class_exists(\Pest\TestSuite::class); } }
Save Changes
Cancel / Back
Close ×
Server Info
Hostname: server1.winmanyltd.com
Server IP: 203.161.60.52
PHP Version: 8.3.27
Server Software: Apache
System: Linux server1.winmanyltd.com 4.18.0-553.22.1.el8_10.x86_64 #1 SMP Tue Sep 24 05:16:59 EDT 2024 x86_64
HDD Total: 117.98 GB
HDD Free: 59.82 GB
Domains on IP: N/A (Requires external lookup)
System Features
Safe Mode:
Off
disable_functions:
None
allow_url_fopen:
On
allow_url_include:
Off
magic_quotes_gpc:
Off
register_globals:
Off
open_basedir:
None
cURL:
Enabled
ZipArchive:
Enabled
MySQLi:
Enabled
PDO:
Enabled
wget:
Yes
curl (cmd):
Yes
perl:
Yes
python:
Yes (py3)
gcc:
Yes
pkexec:
Yes
git:
Yes
User Info
Username: eliosofonline
User ID (UID): 1002
Group ID (GID): 1003
Script Owner UID: 1002
Current Dir Owner: 1002