public function fire() { // fallback to default behaviour if we're not talking about multi tenancy if (!$this->option('tenant')) { return parent::fire(); } if (!$this->confirmToProceed()) { return; } if ($this->option('tenant') == 'all') { $websites = $this->website->all(); } else { $websites = $this->website->queryBuilder()->whereIn('id', explode(',', $this->option('tenant')))->get(); } // forces database to tenant if (!$this->option('database')) { $this->input->setOption('database', 'tenant'); } foreach ($websites as $website) { $this->info("Migrating for {$website->id}: {$website->present()->name}"); $website->database->setCurrent(); $this->prepareDatabase($website->database->name); // The pretend option can be used for "simulating" the migration and grabbing // the SQL queries that would fire if the migration were to be run against // a database for real, which is helpful for double checking migrations. $pretend = $this->input->getOption('pretend'); // Next, we will check to see if a path option has been defined. If it has // we will use the path relative to the root of this installation folder // so that migrations may be run for any path within the applications. if (!is_null($path = $this->input->getOption('path'))) { $path = $this->laravel->basePath() . '/' . $path; } else { $path = $this->getMigrationPath(); } try { $this->migrator->run($path, $pretend); } catch (PDOException $e) { if (str_contains($e->getMessage(), ['Base table or view already exists'])) { $this->comment("Migration failed for existing table; probably a system migration: {$e->getMessage()}"); continue; } } // Once the migrator has run we will grab the note output and send it out to // the console screen, since the migrator itself functions without having // any instances of the OutputInterface contract passed into the class. foreach ($this->migrator->getNotes() as $note) { $this->output->writeln($note); } // Finally, if the "seed" option has been given, we will re-run the database // seed task to re-populate the database, which is convenient when adding // a migration and a seed at the same time, as it is only this command. if ($this->input->getOption('seed')) { $this->call('db:seed', ['--force' => true]); } } }
/** * Handles the set up. */ public function handle() { $this->configuration = config('webserver'); $name = $this->option('tenant'); $email = $this->option('email'); $hostname = $this->option('hostname'); if (empty($name)) { throw new TenantPropertyException('No tenant name given; use --tenant'); } if (empty($email)) { throw new TenantPropertyException('No tenant email given; use --email'); } if (empty($hostname)) { throw new TenantPropertyException('No tenant hostname given; use --hostname'); } $this->comment('Welcome to hyn multi tenancy.'); // If the dashboard is installed we need to prevent default laravel migrations // so we run the dashboard setup command before running any migrations if (class_exists('Hyn\\ManagementInterface\\ManagementInterfaceServiceProvider')) { $this->info('The management interface will be installed first.'); $this->call('dashboard:setup'); } // now we will run all migrations $this->comment('First off, migrations for the packages will run.'); $this->runMigrations(); $tenantDirectory = config('multi-tenant.tenant-directory') ? config('multi-tenant.tenant-directory') : storage_path('multi-tenant'); if (!File::isDirectory($tenantDirectory) && File::makeDirectory($tenantDirectory, 0755, true)) { $this->comment("The directory to hold your tenant websites has been created under {$tenantDirectory}."); } $webserver = null; // Setup webserver if ($this->helper) { // creates directories $this->helper->createDirectories(); $webserver = $this->option('webserver') ?: 'no'; if ($webserver != 'no') { $webserverConfiguration = array_get($this->configuration, $webserver); $webserverClass = array_get($webserverConfiguration, 'class'); } else { $webserver = null; } // Create the first tenant configurations DB::beginTransaction(); $tenant = $this->tenant->create(compact('name', 'email')); $identifier = substr(str_replace(['.'], '-', $hostname), 0, 10); $website = $this->website->create(['tenant_id' => $tenant->id, 'identifier' => $identifier]); $host = $this->hostname->create(['hostname' => $hostname, 'website_id' => $website->id, 'tenant_id' => $tenant->id]); DB::commit(); // hook into the webservice of choice once object creation succeeded if ($webserver) { (new $webserverClass($website))->register(); } if ($tenant->exists && $website->exists && $host->exists) { $this->info('Configuration successful'); } } else { $this->error('The hyn/webserver package is not installed. Visit http://hyn.me/packages/webserver for more information.'); } }