mirror of
https://github.com/archtechx/tenancy.git
synced 2026-02-05 18:34:04 +00:00
Merge branch 'db-users' into dbusers
This commit is contained in:
commit
d0423cfd29
18 changed files with 337 additions and 119 deletions
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: stancl
|
||||
patreon: samuelstancl
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: samuelstancl
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: ['https://www.paypal.me/samuelstancl', 'https://gumroad.com/l/tenancy']
|
||||
31
.github/workflows/ci.yml
vendored
Normal file
31
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
name: CI
|
||||
|
||||
env:
|
||||
COMPOSE_INTERACTIVE_NO_CLI: 1
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ 2.x ]
|
||||
pull_request:
|
||||
branches: [ 2.x ]
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
laravel: ["^6.0", "^7.0"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Start docker containers
|
||||
run: docker-compose up -d
|
||||
- name: Install dependencies
|
||||
run: docker-compose exec -T test composer require --no-interaction "laravel/framework:${{ matrix.laravel }}"
|
||||
- name: Run tests
|
||||
run: ./fulltest
|
||||
- name: Send code coverage to codecov
|
||||
env:
|
||||
CODECOV_TOKEN: 24382d15-84e7-4a55-bea4-c4df96a24a9b
|
||||
run: bash <(curl -s https://codecov.io/bash)
|
||||
26
.travis.yml
26
.travis.yml
|
|
@ -1,26 +0,0 @@
|
|||
env:
|
||||
- LARAVEL_VERSION="^7.0"
|
||||
- LARAVEL_VERSION="^6.0"
|
||||
|
||||
# language: php
|
||||
# php:
|
||||
# - '7.4'
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
before_install:
|
||||
- docker-compose up -d
|
||||
|
||||
install:
|
||||
- travis_retry docker-compose exec test composer require --no-interaction "laravel/framework:$LARAVEL_VERSION"
|
||||
- travis_retry docker-compose exec test composer install --no-interaction
|
||||
|
||||
before_script:
|
||||
- export DB_USERNAME=root DB_PASSWORD="" DB_DATABASE=tenancy CODECOV_TOKEN="24382d15-84e7-4a55-bea4-c4df96a24a9b"
|
||||
- cat vendor/laravel/framework/src/Illuminate/Foundation/Application.php| grep 'const VERSION'
|
||||
|
||||
script: ./fulltest
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
16
DONATIONS.md
16
DONATIONS.md
|
|
@ -4,9 +4,15 @@ Any donations will be greatly appreciated and help ensure that the package is de
|
|||
|
||||
If you're a company and this package is helping you make money, please consider donating.
|
||||
|
||||
**If you'd like to donate in your local currency, see the Bank transfer section.**
|
||||
|
||||
### Patreon
|
||||
|
||||
If you would like to support me on a monthly basis, you can use Patreon: https://patreon.com/samuelstancl
|
||||
|
||||
### PayPal
|
||||
|
||||
PayPal is the preferable donation method as it comes with the lowest fees.
|
||||
PayPal is the preferable donation method for one-time donations as it comes with the lowest fees.
|
||||
|
||||
You can donate here: [https://paypal.me/samuelstancl](https://paypal.me/samuelstancl)
|
||||
|
||||
|
|
@ -16,11 +22,17 @@ If you can't use PayPal, you may use my Gumroad link. This comes with higher fee
|
|||
|
||||
You can donate here: [https://gumroad.com/l/tenancy](https://gumroad.com/l/tenancy)
|
||||
|
||||
### Bank transfer
|
||||
|
||||
If you'd like to donate money from your bank account, you can can do that too. I use [TransferWise](https://transferwise.com/invite/u/samuels1719) (affiliate link 🙂), so I can accept bank transfers in virtually any currency.
|
||||
|
||||
Contact me on [samuel.stancl@gmail.com](mailto:samuel.stancl@gmail.com?subject=Donation) and I'll give you bank details for your local currency.
|
||||
|
||||
### Legal
|
||||
|
||||
If you're a business making a donation, you may want an invoice.
|
||||
|
||||
Contact me on [samuel.stancl@gmail.com](mailto:samuel.stancl@gmail.com) and let me know what you need to have on the invoice and I will make it happen.
|
||||
Contact me on [samuel.stancl@gmail.com](mailto:samuel.stancl@gmail.com?subject=Donation%20with%20invoice) and let me know what you need to have on the invoice and I will make it happen.
|
||||
|
||||
### Thank you!
|
||||
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -1,16 +1,16 @@
|
|||
<p align="center">
|
||||
<a href="https://tenancy.samuelstancl.me"><img width="400" height="335" src="/art/logo.png" alt="Tenancy logo" /></a>
|
||||
<a href="https://tenancyforlaravel.com"><img width="800" src="/art/logo.png" alt="Tenancy for Laravel logo" /></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://laravel.com"><img alt="Laravel 6.x" src="https://img.shields.io/badge/laravel-6.x-red.svg"></a>
|
||||
<a href="https://packagist.org/packages/stancl/tenancy"><img alt="Latest Stable Version" src="https://poser.pugx.org/stancl/tenancy/version"></a>
|
||||
<a href="https://travis-ci.com/stancl/tenancy"><img alt="Travis CI build" src="https://travis-ci.com/stancl/tenancy.svg?branch=2.x"></a>
|
||||
<a href="https://github.com/stancl/tenancy/actions"><img alt="GitHub Actions CI status" src="https://github.com/stancl/tenancy/workflows/CI/badge.svg"></a>
|
||||
<a href="https://codecov.io/gh/stancl/tenancy"><img alt="codecov" src="https://codecov.io/gh/stancl/tenancy/branch/2.x/graph/badge.svg"></a>
|
||||
<a href="https://github.com/stancl/tenancy/blob/2.x/DONATIONS.md"><img alt="Donate" src="https://img.shields.io/badge/Donate-%3C3-red"></a>
|
||||
</p>
|
||||
|
||||
<h1><a href="https://tenancy.samuelstancl.me">stancl/tenancy</a></h1>
|
||||
<h1><a href="https://tenancyforlaravel.com">Tenancy for Laravel — stancl/tenancy</a></h1>
|
||||
|
||||
### *Automatic multi-tenancy for your Laravel app.*
|
||||
|
||||
|
|
@ -20,9 +20,9 @@ You won't have to change a thing in your application's code.
|
|||
- :heavy_check_mark: No replacing of Laravel classes (`Cache`, `Storage`, ...) with tenancy-aware classes
|
||||
- :heavy_check_mark: Built-in tenant identification based on hostname (including second level domains)
|
||||
|
||||
### [Documentation](https://tenancy.samuelstancl.me/docs/v2/)
|
||||
### [Documentation](https://tenancyforlaravel.com/docs/v2/)
|
||||
|
||||
Documentation can be found here: https://tenancy.samuelstancl.me/docs/v2/
|
||||
Documentation can be found here: https://tenancyforlaravel.com/docs/v2/
|
||||
|
||||
The repository with the documentation source code can be found here: [stancl/tenancy-docs](https://github.com/stancl/tenancy-docs).
|
||||
|
||||
|
|
@ -30,5 +30,5 @@ The repository with the documentation source code can be found here: [stancl/ten
|
|||
|
||||
### Credits
|
||||
|
||||
- Created by [Samuel Štancl](https://github.com/stancl)
|
||||
- Logo by [Caneco](https://twitter.com/caneco)
|
||||
- Created by [Samuel Štancl](https://twitter.com/samuelstancl)
|
||||
- Logo by [Brian Dillingham](https://twitter.com/dillinghammm)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
If you need help with implementing the package, you can:
|
||||
- Open an [issue here on GitHub](https://github.com/stancl/tenancy/issues/new?assignees=stancl&labels=support&template=support-question.md&title=)
|
||||
- Message me (`@stancl`) on the [Unofficial Laravel Discord](https://discord.gg/zGVGFAd), in the `#stancl_tenancy` channel
|
||||
- Join our new [Discord server](https://discord.gg/7cpgPxv) and ask in `#help`
|
||||
|
||||
The methods above are preferred, but you may also
|
||||
- Contact me on Telegram: [@samuelstancl](https://t.me/samuelstancl)
|
||||
- Send me an email: [samuel.stancl@gmail.com](mailto:samuel.stancl@gmail.com)
|
||||
|
|
|
|||
BIN
art/logo.png
BIN
art/logo.png
Binary file not shown.
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 495 KiB |
BIN
art/old_logo.png
Normal file
BIN
art/old_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
|
|
@ -3,112 +3,286 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
/**
|
||||
* Storage drivers are used to store information about your tenants.
|
||||
* They hold the Tenant Storage data and keeps track of domains.
|
||||
*/
|
||||
'storage_driver' => 'db',
|
||||
'storage_drivers' => [
|
||||
/**
|
||||
* The majority of applications will want to use this storage driver.
|
||||
* The information about tenants is persisted in a relational DB
|
||||
* like MySQL or PostgreSQL. The only downside is performance.
|
||||
*
|
||||
* A database connection to the central database has to be established on each
|
||||
* request, to identify the tenant based on the domain. This takes three DB
|
||||
* queries. Then, the connection to the tenant database is established.
|
||||
*
|
||||
* Note: From v2.3.0, the performance of the DB storage driver can be improved
|
||||
* by a lot by using Cached Tenant Lookup. Be sure to enable that if you're
|
||||
* using this storage driver. Enabling that feature can completely avoid
|
||||
* querying the central database to identify build the Tenant object.
|
||||
*/
|
||||
'db' => [
|
||||
'driver' => Stancl\Tenancy\StorageDrivers\Database\DatabaseStorageDriver::class,
|
||||
'data_column' => 'data',
|
||||
'custom_columns' => [
|
||||
// 'plan',
|
||||
],
|
||||
'connection' => null, // Your central database connection. Set to null to use the default connection.
|
||||
|
||||
/**
|
||||
* Your central database connection. Set to null to use the default one.
|
||||
*
|
||||
* Note: It's recommended to create a designated central connection,
|
||||
* to let you easily use it in your app, e.g. via the DB facade.
|
||||
*/
|
||||
'connection' => null,
|
||||
|
||||
'table_names' => [
|
||||
'tenants' => 'tenants',
|
||||
'domains' => 'domains',
|
||||
],
|
||||
'cache_store' => null, // What store should be used to cache tenant resolution. Set to null to disable cache or a string with a specific cache store name.
|
||||
|
||||
/**
|
||||
* Here you can enable the Cached Tenant Lookup.
|
||||
*
|
||||
* You can specify what cache store should be used to cache the tenant resolution.
|
||||
* Set to string with a specific cache store name, or to null to disable cache.
|
||||
*/
|
||||
'cache_store' => null,
|
||||
'cache_ttl' => 3600, // seconds
|
||||
],
|
||||
|
||||
/**
|
||||
* The Redis storage driver is much more performant than the database driver.
|
||||
* However, by default, Redis is a not a durable data storage. It works well for ephemeral data
|
||||
* like cache, but to hold critical data, it needs to be configured in a way that guarantees
|
||||
* that data will be persisted permanently. Specifically, you want to enable both AOF and
|
||||
* RDB. Read this here: https://tenancy.samuelstancl.me/docs/v2/storage-drivers/#redis.
|
||||
*/
|
||||
'redis' => [
|
||||
'driver' => Stancl\Tenancy\StorageDrivers\RedisStorageDriver::class,
|
||||
'connection' => 'tenancy',
|
||||
],
|
||||
],
|
||||
|
||||
/**
|
||||
* Controller namespace used by routes in routes/tenant.php.
|
||||
*/
|
||||
'tenant_route_namespace' => 'App\Http\Controllers',
|
||||
'exempt_domains' => [ // e.g. domains which host landing pages, sign up pages, etc
|
||||
|
||||
/**
|
||||
* Central domains (hostnames), e.g. domains which host landing pages, sign up pages, etc.
|
||||
*/
|
||||
'exempt_domains' => [
|
||||
// 'localhost',
|
||||
],
|
||||
'database' => [
|
||||
'based_on' => null, // The connection that will be used as a base for the dynamically created tenant connection. Set to null to use the default connection.
|
||||
'prefix' => 'tenant',
|
||||
'suffix' => ''
|
||||
],
|
||||
'redis' => [
|
||||
'prefix_base' => 'tenant',
|
||||
'prefixed_connections' => [
|
||||
// 'default',
|
||||
],
|
||||
],
|
||||
'cache' => [
|
||||
'tag_base' => 'tenant',
|
||||
],
|
||||
'filesystem' => [ // https://tenancy.samuelstancl.me/docs/v2/filesystem-tenancy/
|
||||
'suffix_base' => 'tenant',
|
||||
'suffix_storage_path' => true, // Note: Disabling this will likely break local disk tenancy. Only disable this if you're using an external file storage service like S3.
|
||||
'asset_helper_tenancy' => true, // should asset() be automatically tenant-aware. You may want to disable this if you use tools like Horizon.
|
||||
// Disks which should be suffixed with the suffix_base + tenant id.
|
||||
'disks' => [
|
||||
'local',
|
||||
'public',
|
||||
// 's3',
|
||||
],
|
||||
'root_override' => [
|
||||
// Disks whose roots should be overriden after storage_path() is suffixed.
|
||||
'local' => '%storage_path%/app/',
|
||||
'public' => '%storage_path%/app/public/',
|
||||
],
|
||||
],
|
||||
'database_managers' => [
|
||||
// Tenant database managers handle the creation & deletion of tenant databases.
|
||||
'sqlite' => Stancl\Tenancy\TenantDatabaseManagers\SQLiteDatabaseManager::class,
|
||||
'mysql' => Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager::class,
|
||||
'pgsql' => Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLDatabaseManager::class,
|
||||
// 'pgsql' => Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLSchemaManager::class, // Separate by schema instead of database
|
||||
],
|
||||
'database_manager_connections' => [
|
||||
// Connections used by TenantDatabaseManagers. This tells, for example, the
|
||||
// MySQLDatabaseManager to use the mysql connection to create databases.
|
||||
'sqlite' => 'sqlite',
|
||||
'mysql' => 'mysql',
|
||||
'pgsql' => 'pgsql',
|
||||
],
|
||||
|
||||
/**
|
||||
* Tenancy bootstrappers are executed when tenancy is initialized.
|
||||
* Their responsibility is making Laravel features tenant-aware.
|
||||
*
|
||||
* To configure their behavior, see the config keys below.
|
||||
*/
|
||||
'bootstrappers' => [
|
||||
// Tenancy bootstrappers are executed when tenancy is initialized.
|
||||
// Their responsibility is making Laravel features tenant-aware.
|
||||
'database' => Stancl\Tenancy\TenancyBootstrappers\DatabaseTenancyBootstrapper::class,
|
||||
'cache' => Stancl\Tenancy\TenancyBootstrappers\CacheTenancyBootstrapper::class,
|
||||
'filesystem' => Stancl\Tenancy\TenancyBootstrappers\FilesystemTenancyBootstrapper::class,
|
||||
'queue' => Stancl\Tenancy\TenancyBootstrappers\QueueTenancyBootstrapper::class,
|
||||
// 'redis' => Stancl\Tenancy\TenancyBootstrappers\RedisTenancyBootstrapper::class, // Note: phpredis is needed
|
||||
],
|
||||
'features' => [
|
||||
// Features are classes that provide additional functionality
|
||||
// not needed for tenancy to be bootstrapped. They are run
|
||||
// regardless of whether tenancy has been initialized.
|
||||
|
||||
// Stancl\Tenancy\Features\Timestamps::class,
|
||||
// Stancl\Tenancy\Features\TenantConfig::class,
|
||||
// Stancl\Tenancy\Features\TelescopeTags::class,
|
||||
// Stancl\Tenancy\Features\TenantRedirect::class,
|
||||
/**
|
||||
* Database tenancy config. Used by DatabaseTenancyBootstrapper.
|
||||
*/
|
||||
'database' => [
|
||||
/**
|
||||
* The connection that will be used as a template for the dynamically created tenant connection.
|
||||
* Set to null to use the default connection.
|
||||
*/
|
||||
'based_on' => null,
|
||||
|
||||
/**
|
||||
* Tenant database names are created like this:
|
||||
* prefix + tenant_id + suffix.
|
||||
*/
|
||||
'prefix' => 'tenant',
|
||||
'suffix' => '',
|
||||
],
|
||||
|
||||
/**
|
||||
* Redis tenancy config. Used by RedisTenancyBoostrapper.
|
||||
*
|
||||
* Note: You need phpredis to use Redis tenancy.
|
||||
*
|
||||
* Note: You don't need to use this if you're using Redis only for cache.
|
||||
* Redis tenancy is only relevant if you're making direct Redis calls,
|
||||
* either using the Redis facade or by injecting it as a dependency.
|
||||
*/
|
||||
'redis' => [
|
||||
'prefix_base' => 'tenant', // Each key in Redis will be prepended by this prefix_base, followed by the tenant id.
|
||||
'prefixed_connections' => [ // Redis connections whose keys are prefixed, to separate one tenant's keys from another.
|
||||
// 'default',
|
||||
],
|
||||
],
|
||||
|
||||
/**
|
||||
* Cache tenancy config. Used by CacheTenancyBootstrapper.
|
||||
*
|
||||
* This works for all Cache facade calls, cache() helper
|
||||
* calls and direct calls to injected cache stores.
|
||||
*
|
||||
* Each key in cache will have a tag applied on it. This tag is used to
|
||||
* scope the cache both when writing to it and when reading from it.
|
||||
*/
|
||||
'cache' => [
|
||||
'tag_base' => 'tenant', // This tag_base, followed by the tenant_id, will form a tag that will be applied on each cache call.
|
||||
],
|
||||
|
||||
/**
|
||||
* Filesystem tenancy config. Used by FilesystemTenancyBootstrapper.
|
||||
* https://tenancy.samuelstancl.me/docs/v2/filesystem-tenancy/.
|
||||
*/
|
||||
'filesystem' => [
|
||||
/**
|
||||
* Each disk listed in the 'disks' array will be suffixed by the suffix_base, followed by the tenant_id.
|
||||
*/
|
||||
'suffix_base' => 'tenant',
|
||||
'disks' => [
|
||||
'local',
|
||||
'public',
|
||||
// 's3',
|
||||
],
|
||||
|
||||
/**
|
||||
* Use this for local disks.
|
||||
*
|
||||
* See https://tenancy.samuelstancl.me/docs/v2/filesystem-tenancy/
|
||||
*/
|
||||
'root_override' => [
|
||||
// Disks whose roots should be overriden after storage_path() is suffixed.
|
||||
'local' => '%storage_path%/app/',
|
||||
'public' => '%storage_path%/app/public/',
|
||||
],
|
||||
|
||||
/**
|
||||
* Should storage_path() be suffixed.
|
||||
*
|
||||
* Note: Disabling this will likely break local disk tenancy. Only disable this if you're using an external file storage service like S3.
|
||||
*
|
||||
* For the vast majority of applications, this feature should be enabled. But in some
|
||||
* edge cases, it can cause issues (like using Passport with Vapor - see #196), so
|
||||
* you may want to disable this if you are experiencing these edge case issues.
|
||||
*/
|
||||
'suffix_storage_path' => true,
|
||||
|
||||
/**
|
||||
* By default, asset() calls are made multi-tenant too. You can use global_asset() and mix()
|
||||
* for global, non-tenant-specific assets. However, you might have some issues when using
|
||||
* packages that use asset() calls inside the tenant app. To avoid such issues, you can
|
||||
* disable asset() helper tenancy and explicitly use tenant_asset() calls in places
|
||||
* where you want to use tenant-specific assets (product images, avatars, etc).
|
||||
*/
|
||||
'asset_helper_tenancy' => true,
|
||||
],
|
||||
|
||||
/**
|
||||
* TenantDatabaseManagers are classes that handle the creation & deletion of tenant databases.
|
||||
*/
|
||||
'database_managers' => [
|
||||
'sqlite' => Stancl\Tenancy\TenantDatabaseManagers\SQLiteDatabaseManager::class,
|
||||
'mysql' => Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager::class,
|
||||
'pgsql' => Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLDatabaseManager::class,
|
||||
|
||||
/**
|
||||
* Disable the pgsql manager above, enable the one below, and set the
|
||||
* tenancy.database.separate_by config key to 'schema' if you would
|
||||
* like to separate tenant DBs by schemas rather than databases.
|
||||
*/
|
||||
// 'pgsql' => Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLSchemaManager::class, // Separate by schema instead of database
|
||||
],
|
||||
|
||||
/**
|
||||
* Connections used by TenantDatabaseManagers. This tells, for example, the
|
||||
* MySQLDatabaseManager to use the mysql connection to create databases.
|
||||
*/
|
||||
'database_manager_connections' => [
|
||||
'sqlite' => 'sqlite',
|
||||
'mysql' => 'mysql',
|
||||
'pgsql' => 'pgsql',
|
||||
],
|
||||
|
||||
/**
|
||||
* Features are classes that provide additional functionality
|
||||
* not needed for tenancy to be bootstrapped. They are run
|
||||
* regardless of whether tenancy has been initialized.
|
||||
*
|
||||
* See the documentation page for each class to
|
||||
* understand which ones you want to enable.
|
||||
*/
|
||||
'features' => [
|
||||
// Stancl\Tenancy\Features\Timestamps::class, // https://tenancy.samuelstancl.me/docs/v2/features/timestamps/
|
||||
// Stancl\Tenancy\Features\TenantConfig::class, // https://tenancy.samuelstancl.me/docs/v2/features/tenant-config/
|
||||
// Stancl\Tenancy\Features\TelescopeTags::class, // https://tenancy.samuelstancl.me/docs/v2/telescope/
|
||||
// Stancl\Tenancy\Features\TenantRedirect::class, // https://tenancy.samuelstancl.me/docs/v2/features/tenant-redirect/
|
||||
],
|
||||
'storage_to_config_map' => [ // Used by the TenantConfig feature
|
||||
// 'paypal_api_key' => 'services.paypal.api_key',
|
||||
],
|
||||
|
||||
/**
|
||||
* The URL to which users will be redirected when they try to acceess a central route on a tenant domain.
|
||||
*/
|
||||
'home_url' => '/app',
|
||||
|
||||
/**
|
||||
* Automatically create a database when creating a tenant.
|
||||
*/
|
||||
'create_database' => true,
|
||||
|
||||
/**
|
||||
* Should tenant databases be created asynchronously in a queued job.
|
||||
*/
|
||||
'queue_database_creation' => false,
|
||||
'migrate_after_creation' => false, // run migrations after creating a tenant
|
||||
|
||||
/**
|
||||
* Should tenant migrations be ran after the tenant's database is created.
|
||||
*/
|
||||
'migrate_after_creation' => false,
|
||||
'migration_parameters' => [
|
||||
// '--force' => true, // force database migrations
|
||||
// '--force' => true, // Set this to true to be able to run migrations in production
|
||||
// '--path' => [], // If you need to customize paths to tenant migrations
|
||||
],
|
||||
|
||||
/**
|
||||
* Should tenant databases be automatically seeded after they're created & migrated.
|
||||
*/
|
||||
'seed_after_migration' => false, // should the seeder run after automatic migration
|
||||
'seeder_parameters' => [
|
||||
'--class' => 'DatabaseSeeder', // root seeder class, e.g.: 'DatabaseSeeder'
|
||||
// '--force' => true, // force database seeder
|
||||
// '--force' => true,
|
||||
],
|
||||
|
||||
/**
|
||||
* Should tenant databases be deleted asynchronously in a queued job.
|
||||
*/
|
||||
'queue_database_deletion' => false,
|
||||
'delete_database_after_tenant_deletion' => false, // delete the tenant's database after deleting the tenant
|
||||
|
||||
/**
|
||||
* Automatically delete the tenant's database after the tenant is deleted.
|
||||
*
|
||||
* This will save space but permanently delete data which you might want to keep.
|
||||
*/
|
||||
'delete_database_after_tenant_deletion' => false,
|
||||
|
||||
/**
|
||||
* If you don't supply an id when creating a tenant, this class will be used to generate a random ID.
|
||||
*/
|
||||
'unique_id_generator' => Stancl\Tenancy\UniqueIDGenerators\UUIDGenerator::class,
|
||||
|
||||
/**
|
||||
* Middleware pushed to the global middleware stack.
|
||||
*/
|
||||
'global_middleware' => [
|
||||
Stancl\Tenancy\Middleware\InitializeTenancy::class,
|
||||
],
|
||||
|
|
|
|||
2
fulltest
2
fulltest
|
|
@ -4,4 +4,4 @@ set -e
|
|||
# for development
|
||||
docker-compose up -d
|
||||
./test "$@"
|
||||
docker-compose exec test vendor/bin/phpcov merge --clover clover.xml coverage/
|
||||
docker-compose exec -T test vendor/bin/phpcov merge --clover clover.xml coverage/
|
||||
|
|
|
|||
|
|
@ -43,6 +43,12 @@ class Seed extends SeedCommand
|
|||
*/
|
||||
public function handle()
|
||||
{
|
||||
foreach (config('tenancy.seeder_parameters') as $parameter => $value) {
|
||||
if (! $this->input->hasParameterOption($parameter)) {
|
||||
$this->input->setOption(ltrim($parameter, '-'), $value);
|
||||
}
|
||||
}
|
||||
|
||||
if (! $this->confirmToProceed()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -52,12 +58,6 @@ class Seed extends SeedCommand
|
|||
|
||||
$this->input->setOption('database', $tenant->getConnectionName());
|
||||
|
||||
foreach (config('tenancy.seeder_parameters') as $parameter => $value) {
|
||||
if (! $this->input->hasParameterOption($parameter)) {
|
||||
$this->input->setOption(ltrim($parameter, '-'), $value);
|
||||
}
|
||||
}
|
||||
|
||||
$tenant->run(function () {
|
||||
// Seed
|
||||
parent::handle();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ namespace Stancl\Tenancy\Features;
|
|||
use Laravel\Telescope\IncomingEntry;
|
||||
use Laravel\Telescope\Telescope;
|
||||
use Stancl\Tenancy\Contracts\Feature;
|
||||
use Stancl\Tenancy\Middleware\PreventAccessFromTenantDomains;
|
||||
use Stancl\Tenancy\TenantManager;
|
||||
|
||||
class TelescopeTags implements Feature
|
||||
|
|
@ -30,7 +31,15 @@ class TelescopeTags implements Feature
|
|||
Telescope::tag(function (IncomingEntry $entry) {
|
||||
$tags = $this->getTags($entry);
|
||||
|
||||
if (in_array('tenancy', optional(request()->route())->middleware() ?? [])) {
|
||||
if (! request()->route()) {
|
||||
return $tags;
|
||||
}
|
||||
|
||||
$tenantRoute = PreventAccessFromTenantDomains::routeHasMiddleware(request()->route(), 'tenancy')
|
||||
|| PreventAccessFromTenantDomains::routeHasMiddleware(request()->route(), 'universal');
|
||||
|
||||
// Don't do anything if we're visiting a universal route on a central domain
|
||||
if ($tenantRoute && tenancy()->initialized) {
|
||||
$tags = array_merge($tags, [
|
||||
'tenant:' . tenant('id'),
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class InitializeTenancy
|
|||
try {
|
||||
tenancy()->init($request->getHost());
|
||||
} catch (TenantCouldNotBeIdentifiedException $e) {
|
||||
($this->onFail)($e);
|
||||
return ($this->onFail)($e, $request, $next);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class InitializeTenancyByRequestData
|
|||
try {
|
||||
$this->initializeTenancy($request);
|
||||
} catch (TenantCouldNotBeIdentifiedException $e) {
|
||||
($this->onFail)($e);
|
||||
return ($this->onFail)($e, $request, $next);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,16 @@ use Illuminate\Support\Facades\Route as Router;
|
|||
*/
|
||||
class PreventAccessFromTenantDomains
|
||||
{
|
||||
/** @var callable */
|
||||
protected $central404;
|
||||
|
||||
public function __construct(callable $central404 = null)
|
||||
{
|
||||
$this->central404 = $central404 ?? function () {
|
||||
return 404;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
|
|
@ -39,13 +49,13 @@ class PreventAccessFromTenantDomains
|
|||
}
|
||||
|
||||
if ($isExemptDomain && $isTenantRoute) { // accessing tenant routes on web domains
|
||||
abort(404);
|
||||
return ($this->central404)($request, $next);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
public function routeHasMiddleware(Route $route, $middleware): bool
|
||||
public static function routeHasMiddleware(Route $route, $middleware): bool
|
||||
{
|
||||
if (in_array($middleware, $route->middleware(), true)) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class CachedTenantResolver
|
|||
return $this->config->get('tenancy.storage_drivers.db.cache_ttl');
|
||||
}
|
||||
|
||||
public function getTenantIdByDomain(string $domain, Closure $query): string
|
||||
public function getTenantIdByDomain(string $domain, Closure $query): ?string
|
||||
{
|
||||
return $this->cache->remember('_tenancy_domain_to_id:' . $domain, $this->ttl(), $query);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,14 +14,8 @@ trait TenantAwareCommand
|
|||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$tenants = $this->getTenants();
|
||||
|
||||
if (count($tenants) === 1) {
|
||||
return $tenants[0]->run(function () {
|
||||
return $this->laravel->call([$this, 'handle']);
|
||||
});
|
||||
}
|
||||
|
||||
$exitCode = 0;
|
||||
|
||||
foreach ($tenants as $tenant) {
|
||||
$result = (int) $tenant->run(function () {
|
||||
return $this->laravel->call([$this, 'handle']);
|
||||
|
|
|
|||
4
test
4
test
|
|
@ -2,6 +2,6 @@
|
|||
set -e
|
||||
|
||||
printf "Variant 1 (DB)\n\n"
|
||||
docker-compose exec test env TENANCY_TEST_STORAGE_DRIVER=db vendor/bin/phpunit --coverage-php coverage/1.cov "$@"
|
||||
docker-compose exec -T test env TENANCY_TEST_STORAGE_DRIVER=db vendor/bin/phpunit --coverage-php coverage/1.cov "$@"
|
||||
printf "Variant 2 (Redis)\n\n"
|
||||
docker-compose exec test env TENANCY_TEST_STORAGE_DRIVER=redis vendor/bin/phpunit --coverage-php coverage/2.cov "$@"
|
||||
docker-compose exec -T test env TENANCY_TEST_STORAGE_DRIVER=redis vendor/bin/phpunit --coverage-php coverage/2.cov "$@"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue