Download the PHP package michaelnabil230/laravel-multi-tenancy without Composer

On this page you can find all versions of the php package michaelnabil230/laravel-multi-tenancy. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-multi-tenancy

Tenancy for Laravel

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

This is where your description should go. Limit it to a paragraph or two. Consider adding a small example.

Installation

You can install the package via composer:

You can publish and run the migrations with:

This is the contents of the published config file:

Configuration

The package is highly configurable. This page covers what you can configure in the config/multi-tenancy.php file, but note that many more things are configurable. Some things can be changed by extending classes (e.g. the Tenant model), and many things can be changed using static properties. These things will usually be mentioned on the respective pages of the documentation, but not every time. For this reason, don't be afraid to dive into the package's source code — whenever the class you're using has a public static property, it's intended to be configured.

Static properties

You can set static properties like this (example):

A good place to put these calls is your app/Providers/TenancyServiceProvider's boot() method.

Tenant model

This config specifies what Tenant model should be used by the package. There's a high chance you're using a custom model, as instructed to by the [Tenants], so be sure to change it in the config.

Domain model

Similar to the Tenant model config. If you're using a custom model for domains, change it in this config. If you're not using domains (e.g. if you're using path or request data identification) at all, ignore this config key altogether.

Central domains

multi-tenancy.central_domains

The list of domains that host your [central app]. This is used by (among other things):

Bootstrappers

multi-tenancy.bootstrappers

This config array lets you enable, disable or add your own [tenancy bootstrappers]

Cache

multi-tenancy.cache.*

This section is relevant to cache separation, specifically, to the CacheTenancyBootstrapper.

Note: To use the cache separation, you need to use a cache store that supports tagging, which is usually Redis.

See this section in the config, it's documented with comments.

Filesystem

multi-tenancy.filesystem.*

This section is relevant to storage separation, specifically, to the FilesystemTenancyBootstrapper.

See this section in the config, it's documented with comments.

Redis

multi-tenancy.redis.*

This section is relevant to Redis data separation, specifically, to the RedisTenancyBootstrapper.

Note: To use the this bootstrapper, you need phpredis.

See this section in the config, it's documented with comments.

Features

multi-tenancy.features

This config array lets you enable, disable or add your own [feature classes]

Seeder parameters

multi-tenancy.seeder_parameters

The same as migration parameters, but for tenants:seed and the SeedDatabase job.

Event system

This package is heavily based around events, which makes it incredibly flexible.

By default, the events are configured in such a way that the package works like this:

Again, all of the above is configurable. You might even disable all tenancy bootstrappers, and just use tenant identification and scope your app manually around the tenant stored in MichaelNabil230\MultiTenancy\Tenancy. The choice is yours.

TenancyServiceProvider

This package comes with a very convenient service provider that's added to your application when you install the package. This service provider is used for mapping listeners to events specific to the package and is the place where you should put any tenancy-specific service container calls — to not pollute your AppServiceProvider.

Note that you can register listeners to this package's events anywhere you want. The event/listener mapping in the service provider exists only to make your life easier. If you want to register the listeners manually, like in the example below, you can.

Bootstrapping tenancy

By default, the BootstrapTenancy class is listening to the TenancyInitialized event (exactly as you can see in the example above). That listener will execute the configured tenancy bootstrappers to transition the application into the tenant's context. You can read more about this on the [tenancy bootstrappers]

Conversely, when the TenancyEnded event fires, the RevertToCentralContext event transitions the app back into the central context.

Available events

Note: Some database events (SeedingDatabase, DatabaseSeeded and possibly others) are fired in the tenant context. Depending on how your application bootstraps tenancy, you might need to be specific about interacting with the central database in these events' listeners — that is, if you need to.

Note: All events are located in the MichaelNabil230\MultiTenancy\Events namespace.

Tenancy

Note the difference between initializing tenancy and bootstrapping tenancy. Tenancy is initialized when a tenant is loaded into the Tenancy object. Whereas bootstrapping happens as a result of initialization — if you're using automatic tenancy, the BootstrapTenancy class is listening to the TenancyInitialized event and after it's done executing bootstrappers, it fires an event saying that tenancy was bootstrapped. You want to use the bootstrapped event if you want to execute something after the app has been transitioned to the tenant context.

Tenant

The following events are dispatched as a result of Eloquent events being fired in the default Tenant implementation (the most often used events are bold):

Domain

These events are optional. They're only relevant to you if you're using domains for your tenants.

Database

These events are also optional. They're relevant to you if you're using multi-database tenancy:

Tenant routes

You may register tenant routes in routes/tenant.php. These routes have no middleware applied on them, and their controller namespace is specified in app/Providers/TenancyServiceProvider.

By default, you will see the following setup:

Routes within this group will have the web middleware group, an initialization middleware, and finally, a middleware related to the section below applied on them.

You may do the same for the api route group, for instance.

Also, you may use different initialization middleware than the domain one. For a full list, see the [Tenant identification].

Concepts

In single-database tenancy, there are 4 types of models:

To scope your queries correctly, apply the MichaelNabil230\MultiTenancy\Traits\BelongsToTenant trait on primary models. This will ensure that all calls to your parent models are scoped to the current tenant, and that calls to their child relations are scoped through the parent relationships.

And that's it. Your models are now automatically scoped to the current tenant, and not scoped at all when there's no current tenant (e.g. in a central admin panel).

However, there's one edge case to keep in mind. Consider the following set-up:

Looks correct, but you might still accidentally access another tenant's comments.

If you use this:

then the model has no way of knowing how to scope that query, since it doesn't directly belong to the tenant. Also note that in practice, you really shouldn't be doing this much. You should ideally access secondary models through parent models in every single case.

However, sometimes you might have a use case where you really need to do that in the tenant context. For that reason, we also provide you with a BelongsToPrimaryModel trait, which lets you scope calls like the one above to the current tenant, by loading the parent relationship — which gets automatically scoped to the current tenant — on them.

So, to give you an example, you would do this:

And this will automatically scope the Comment::all() call to the current tenant. Note that the limitation of this is that you need to be able to define a relationship to a primary model, so if you need to do this on the "Vote" in Vote belongsTo Comment belongsTo Post belongsTo Tenant, you need to define some strange relationship. Laravel supports HasOneThrough, but not BelongsToThrough, so you'd need to do some hacks around that. For that reason, I recommend avoiding these Comment::all()-type queries altogether.

Database considerations

Unique indexes

If you'd have a unique index such as:

in a standard non-tenant, or multi-database-tenant, application, you need to scope this unique index to the tenant, meaning you'd do this on primary models:

and this on secondary models:

Validation

The unique and exists validation rules of course aren't scoped to the current tenant, so you need to scope them manually like this:

You'll be able to use these two methods:

Low-level database queries

And the final thing to keep in mind is that DB facade calls, or any other types of direct database queries, of course won't be scoped to the current tenant.

The package can only provide scoping logic for the abstraction logic that Eloquent is, it can't do anything with low level database queries.

Be careful with using them.

Making Artisan command tenant aware

Commands can be made tenant aware by applying the TenantAware trait. When using the trait it is required to append {--tenant=*} or {--tenant=} to the command signature.

Caution: If you append {--tenant=*}, then if no tenant option is provided when executing the command, the command will execute for all tenants.

When executing the command, the handle method will be called for each tenant.

Using the example above, the name of each tenant will be written to the output of the command.

You can also execute the command for a specific tenant:

Running artisan command for seed data to tenant

Can it run a seed command to a specific tenant or for all tenants with the same previous section

Running artisan command for create a new tenant

Can it run a create command to quickly create a tenant

Making global queries

To disable the tenant scope, simply add withoutTenancy() to your query.

The subscription section

That's it, we only have to use that trait in our User model! Now your users may subscribe to plans.

Create a Plan

Getting all plans

Get all plans with sections and features:

Get Plan Details

You can query the plan for further details, using the intuitive API as follows:

Both $plan->features and $plan->subscriptions are collections, driven from relationships, and thus you can query these relations as any normal Eloquent relationship. E.g. $plan->features()->where('name', 'listing_title_bold')->first().

Create a Subscription

You can subscribe a tenant to a plan by using the createSubscription(Plan $plan, Carbon $startDate = null) function available in the Tenant model. First, retrieve an instance of your subscriber model, which typically will be your tenant model and an instance of the plan your tenant is subscribing to. Once you have retrieved the model instance, you may use the createSubscription method to create the model's subscription.

The first argument passed to createSubscription while the argument is the plan instance your tenant is subscribing to, and there's an optional second parameter to specify custom start date as an instance of Illuminate\Support\Carbon (by default if not provided, it will start now).

Change the Plan

You can change subscription plan easily as follows:

If both plans (current and new plan) have the same billing frequency (e.g., invoice_period and invoice_interval) the subscription will retain the same billing dates. If the plans don't have the same billing frequency, the subscription will have the new plan billing frequency, starting on the day of the change and the subscription usage data will be cleared. Also if the new plan has a trial period and it's a new subscription, the trial period will be applied.

Check Subscription Status

For a subscription to be considered active one of the following must be true:

Alternatively you can use the following methods available in the subscription model:

Canceled subscriptions with an active trial or ends_at in the future are considered active.

Renew a Subscription

To renew a subscription you may use the renew method available in the subscription model. This will set a new ends_at date based on the selected plan and will clear the usage data of the subscription.

Canceled subscriptions with an ended period can't be renewed.

Cancel a Subscription

To cancel a subscription, simply use the cancel method on the user's subscription:

Scopes

Subscription Model

Models

MultiTenancy Subscriptions uses 4 models:

Support

Testing

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.


All versions of laravel-multi-tenancy with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1
facade/ignition-contracts Version ^1.0
spatie/laravel-package-tools Version ^1.11.0
illuminate/contracts Version ^9.0
spatie/dns Version ^2.5
spatie/laravel-sluggable Version ^3.4
spatie/laravel-translatable Version ^6.2
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package michaelnabil230/laravel-multi-tenancy contains the following files

Loading the files please wait ....