mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 08:24:04 +00:00
Merge branch '1.x' of github.com:stancl/tenancy into 1.x
This commit is contained in:
commit
fd944b6366
7 changed files with 169 additions and 4 deletions
14
README.md
14
README.md
|
|
@ -53,6 +53,7 @@ You won't have to change a thing in your application's code.\*
|
||||||
* [Artisan commands](#artisan-commands)
|
* [Artisan commands](#artisan-commands)
|
||||||
- [`tenants:list`](#-tenants-list-)
|
- [`tenants:list`](#-tenants-list-)
|
||||||
- [`tenants:migrate`, `tenants:rollback`, `tenants:seed`](#-tenants-migrate----tenants-rollback----tenants-seed-)
|
- [`tenants:migrate`, `tenants:rollback`, `tenants:seed`](#-tenants-migrate----tenants-rollback----tenants-seed-)
|
||||||
|
- [Running your commands for tenants](#running-your-commands-for-tenants)
|
||||||
+ [Tenant migrations](#tenant-migrations)
|
+ [Tenant migrations](#tenant-migrations)
|
||||||
* [Testing](#testing)
|
* [Testing](#testing)
|
||||||
- [Tips](#tips)
|
- [Tips](#tips)
|
||||||
|
|
@ -487,6 +488,7 @@ Available commands for the "tenants" namespace:
|
||||||
tenants:list List tenants.
|
tenants:list List tenants.
|
||||||
tenants:migrate Run migrations for tenant(s)
|
tenants:migrate Run migrations for tenant(s)
|
||||||
tenants:rollback Rollback migrations for tenant(s).
|
tenants:rollback Rollback migrations for tenant(s).
|
||||||
|
tenants:run Run a command for tenant(s).
|
||||||
tenants:seed Seed tenant database(s).
|
tenants:seed Seed tenant database(s).
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -509,6 +511,18 @@ Tenant: 8075a580-1cb8-11e9-8822-49c5d8f8ff23 (laravel.localhost)
|
||||||
Database seeding completed successfully.
|
Database seeding completed successfully.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Running your commands for tenants
|
||||||
|
|
||||||
|
You can use the `tenants:run` command to run your own commands for tenants.
|
||||||
|
|
||||||
|
If your command's signature were `email:send {user} {--queue} {--subject} {body}`, you would run this command like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ artisan tenants:run email:send --tenants=8075a580-1cb8-11e9-8822-49c5d8f8ff23 --option="queue=1" --option="subject=New Feature" --argument="body=We have launched a new feature. ..."
|
||||||
|
```
|
||||||
|
|
||||||
|
The `=` separates the argument/option name from its value, but you can still use `=` in the argument's value.
|
||||||
|
|
||||||
### Tenant migrations
|
### Tenant migrations
|
||||||
|
|
||||||
Tenant migrations are located in `database/migrations/tenant`, so you should move your tenant migrations there.
|
Tenant migrations are located in `database/migrations/tenant`, so you should move your tenant migrations there.
|
||||||
|
|
|
||||||
66
src/Commands/Run.php
Normal file
66
src/Commands/Run.php
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class Run extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Run a command for tenant(s)';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = "tenants:run {commandname : The command's name.}
|
||||||
|
{--tenants= : The tenant(s) to run the command for. Default: all}
|
||||||
|
{--argument=* : The arguments to pass to the command. Default: none}
|
||||||
|
{--option=* : The options to pass to the command. Default: none}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
if ($tenancy_was_initialized = tenancy()->initialized) {
|
||||||
|
$previous_tenants_domain = tenant('domain');
|
||||||
|
}
|
||||||
|
|
||||||
|
tenant()->all($this->option('tenants'))->each(function ($tenant) {
|
||||||
|
$this->line("Tenant: {$tenant['uuid']} ({$tenant['domain']})");
|
||||||
|
tenancy()->init($tenant['domain']);
|
||||||
|
|
||||||
|
$callback = function ($prefix = '') {
|
||||||
|
return function ($arguments, $argument) use ($prefix) {
|
||||||
|
[$key, $value] = explode('=', $argument, 2);
|
||||||
|
$arguments[$prefix . $key] = $value;
|
||||||
|
|
||||||
|
return $arguments;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Turns ['foo=bar', 'abc=xyz=zzz'] into ['foo' => 'bar', 'abc' => 'xyz=zzz']
|
||||||
|
$arguments = array_reduce($this->option('argument'), $callback(), []);
|
||||||
|
|
||||||
|
// Turns ['foo=bar', 'abc=xyz=zzz'] into ['--foo' => 'bar', '--abc' => 'xyz=zzz']
|
||||||
|
$options = array_reduce($this->option('option'), $callback('--'), []);
|
||||||
|
|
||||||
|
// Run command
|
||||||
|
$this->call($this->argument('commandname'), array_merge($arguments, $options));
|
||||||
|
|
||||||
|
tenancy()->end();
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($tenancy_was_initialized) {
|
||||||
|
tenancy()->init($previous_tenants_domain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Stancl\Tenancy;
|
namespace Stancl\Tenancy;
|
||||||
|
|
||||||
|
use Stancl\Tenancy\Commands\Run;
|
||||||
use Stancl\Tenancy\Commands\Seed;
|
use Stancl\Tenancy\Commands\Seed;
|
||||||
use Illuminate\Cache\CacheManager;
|
use Illuminate\Cache\CacheManager;
|
||||||
use Stancl\Tenancy\Commands\Migrate;
|
use Stancl\Tenancy\Commands\Migrate;
|
||||||
|
|
@ -23,9 +24,10 @@ class TenancyServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
if ($this->app->runningInConsole()) {
|
if ($this->app->runningInConsole()) {
|
||||||
$this->commands([
|
$this->commands([
|
||||||
|
Run::class,
|
||||||
|
Seed::class,
|
||||||
Migrate::class,
|
Migrate::class,
|
||||||
Rollback::class,
|
Rollback::class,
|
||||||
Seed::class,
|
|
||||||
TenantList::class,
|
TenantList::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ class CommandsTest extends TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function database_connection_is_switched_to_default_after_migrating_or_seeding_or_rolling_back()
|
public function database_connection_is_switched_to_default()
|
||||||
{
|
{
|
||||||
$originalDBName = DB::connection()->getDatabaseName();
|
$originalDBName = DB::connection()->getDatabaseName();
|
||||||
|
|
||||||
|
|
@ -88,13 +88,29 @@ class CommandsTest extends TestCase
|
||||||
|
|
||||||
Artisan::call('tenants:rollback');
|
Artisan::call('tenants:rollback');
|
||||||
$this->assertSame($originalDBName, DB::connection()->getDatabaseName());
|
$this->assertSame($originalDBName, DB::connection()->getDatabaseName());
|
||||||
|
|
||||||
|
$this->run_commands_works();
|
||||||
|
$this->assertSame($originalDBName, DB::connection()->getDatabaseName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function database_connection_is_switched_to_default_after_migrating_or_seeding_or_rolling_back_when_tenancy_has_been_initialized()
|
public function database_connection_is_switched_to_default_when_tenancy_has_been_initialized()
|
||||||
{
|
{
|
||||||
tenancy()->init('localhost');
|
tenancy()->init('localhost');
|
||||||
|
|
||||||
$this->database_connection_is_switched_to_default_after_migrating_or_seeding_or_rolling_back();
|
$this->database_connection_is_switched_to_default();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function run_commands_works()
|
||||||
|
{
|
||||||
|
$uuid = tenant()->create('run.localhost')['uuid'];
|
||||||
|
|
||||||
|
Artisan::call('tenants:migrate', ['--tenants' => $uuid]);
|
||||||
|
|
||||||
|
$this->artisan("tenants:run foo --tenants=$uuid --argument='a=foo' --option='b=bar' --option='c=xyz'")
|
||||||
|
->expectsOutput("User's name is Test command")
|
||||||
|
->expectsOutput('foo')
|
||||||
|
->expectsOutput('xyz');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
tests/Etc/ConsoleKernel.php
Normal file
17
tests/Etc/ConsoleKernel.php
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Tests\Etc;
|
||||||
|
|
||||||
|
use Orchestra\Testbench\Console\Kernel;
|
||||||
|
|
||||||
|
class ConsoleKernel extends Kernel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The Artisan commands provided by your application.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $commands = [
|
||||||
|
ExampleCommand::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
39
tests/Etc/ExampleCommand.php
Normal file
39
tests/Etc/ExampleCommand.php
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Tests\Etc;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class ExampleCommand extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'foo {a} {--b=} {--c=}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
User::create([
|
||||||
|
'id' => 999,
|
||||||
|
'name' => 'Test command',
|
||||||
|
'email' => 'test@command.com',
|
||||||
|
'password' => bcrypt('password'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->line("User's name is " . User::find(999)->name);
|
||||||
|
$this->line($this->argument('a'));
|
||||||
|
$this->line($this->option('c'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class User extends \Illuminate\Database\Eloquent\Model
|
||||||
|
{
|
||||||
|
protected $guarded = [];
|
||||||
|
}
|
||||||
|
|
@ -130,6 +130,17 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
$app->singleton('Illuminate\Contracts\Http\Kernel', Etc\HttpKernel::class);
|
$app->singleton('Illuminate\Contracts\Http\Kernel', Etc\HttpKernel::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve application Console Kernel implementation.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Foundation\Application $app
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function resolveApplicationConsoleKernel($app)
|
||||||
|
{
|
||||||
|
$app->singleton('Illuminate\Contracts\Console\Kernel', Etc\ConsoleKernel::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function randomString(int $length = 10)
|
public function randomString(int $length = 10)
|
||||||
{
|
{
|
||||||
return substr(str_shuffle(str_repeat($x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length / strlen($x)))), 1, $length);
|
return substr(str_shuffle(str_repeat($x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length / strlen($x)))), 1, $length);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue