stancl / tenancy-docs Goto Github PK
View Code? Open in Web Editor NEWstancl/tenancy docs & website
Home Page: https://tenancyforlaravel.com/docs
License: MIT License
stancl/tenancy docs & website
Home Page: https://tenancyforlaravel.com/docs
License: MIT License
Just a note that when using backpack for laravel you will need to set dont-discover:laravel/crud in composer, then manually register the service provider just below RouteServiceProvider. Otherwise Backpack loads after TenancyServiceProvider and messes up you central route /
Writing down notes to mention in v4 docs, so that we can clean up the issues here.
Artisan::call('tenants:run', ...)
#120Document archtechx/tenancy#145
The TenantAwareCommand
trait is a great time saver, allowing us to avoid writing loops on potentially many nightly commands.
If I add the TenantAwareCommand
and then the HasATenantsOption
, the docs state that if I use these traits, I won't have to change a thing in my commands. However, when I combine these two traits, I see the following error on all commands:
The "tenants" option does not exist.
If I remove the HasATenantsOption
and implement getTenants()
per the docs, it works perfectly with this code in my commands - but I don't know if I'm implementing this correctly or if I should be adding more:
protected function getTenants(): array { return tenancy()->all()->toArray(); }
So, I have two questions:
all()
and $this->option('tenants')
in the getTenants()
method? I don't understand what this is doing / what its purpose is in this instance?I am using this package with Spatie media library (https://docs.spatie.be/laravel-medialibrary/v8/basic-usage/retrieving-media/)
When I upload an image, it will be added to storage/{tenant_id}/app/public
. Normally, when I want to return the image URL, I just use: $mediaItems[0]->getFullUrl()
or $mediaItems[0]->getUrl()
, but it return an global of storage path:
http://domain.test/storage/16/conversions/image-medium.jpg
.
Right now, I have to do some string handling to make that above URL turn to:
http://tenant.domain.test/tenancy/assets/16/conversions/image-medium.jpg
Are there any ways to make the getFullUrl
or getUrl
return the right URL without handle string stuff? Thank you!
On central domain ORM working fine but when i go to tenant domain
instead of getting data from tenant database table. it applies all ORM condition on central database tenant(table name ) table.
Actually it should have to validate tenant domain from central database table tenant and then switch to tenant database table ...table_name but it cant doing this
Help me Plz
Hi,
I have correctly configured laravel, stancl / tenancy and other package but ...
How do I configure the values ββin ".env", for example MAIL_FROM_ADDRESS different for each tenant?
the documentation talks about tenant config but it is not very clear
or in the past I created a file /config/mail.php in the specific folder of the tenant, so a kind of root override but now it doesn't work.
if I create the file in storage / / <tenant_id> /config/mail.php it doesn't work,where am i wrong?
Thanks and regards,
G
I get these errors in the console on chrome. when accessing tenant domain.
GET https://xxx.xxx.test/tenancy/assets/images/icons/manifest.json 500
Manifest: Line: 1, column: 1, Syntax error.
Hello.
I would like to know how do I set the database server IP address for each tenant.
Appends the link to the end of whichever tab you are currently on instead of intended redirect.
https://tenancy.samuelstancl.me/docs/v2/getting-started/ click on HTTPS Certificates in nav
maybe do somthing like: save a sqlite file in storage folder
and call to db when the tenancy load
After the SQLite :memory: bug is resolved.
Hi,
I wrote this migration that will do the proper work for the passport setup for each client. Since the default connection may not be mysql, it's not worth to add this in the package, but it's ok to add this in the documentation, I think. You probably can make it better as I'm still adapting our system here to get the continuous deployment working - I still did not get too deep in the code, but in the build process only.
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class SeedOAuthCredentials extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$tenant = tenancy()->getTenant();
DB::purge('mysql');
Config::set('database.connections.mysql.database',config('tenancy.database.prefix'.$tenant->id));
\Illuminate\Support\Facades\Artisan::call('passport:install');
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
}
}
I have implemented multi tenancy with subdomain. web route is working properly but api route return 404 not found
Exception :- Symfony\Component\HttpKernel\Exception\NotFoundHttpException
In the documentation there a guides for integration of several laravel packages. It would be nice to have a guide on how to make the multi-tenancy package work with laravel scout.
We have a use case where we only want the database to be created if it doesn't already exist. For production there's an ops process that bootstraps everything for a particular deployment of the app. Kind of weird and probably fringe case but it's essentially a multi-tenant deployment of the multi-tenant Laravel app.
In that environment we don't want to give each individual deployment permissions to create databases on a shared instance so they're made before hand along with locked down user grants. We've just modified our own database manager to add IF NOT EXISTS
on createDatabase
, but was wondering if you'd be open to a PR adding this to the default managers?
Thanks for the package, works great!
how to use nova in central app and tenet app with different resources?
I hope this is the right place to ask this.
I am using laravel 8 and tenancy v3.
I have been trying to get fortify/jetstream to work properly with tenancy, but it wants to use the central db.
I have gotten the routes to work properly by removing them from the package itself and putting them directly into my tenants route file. This "seems" to be working fine, however when I register a user under a tenant, it stores it in the central Db.
Then when It tries to auto login after registration, or after using the login, I end up in a loop. It seems the registration route and login route are not using the tenant connection. Therefore my user gets authenticated but then fails when going to the dashboard, presumably because the logged in check is somehow using the tenant connection now.
Has anyone had any luck with this?
Is this where the "gotcha" for automatic exists and I should be doing some earlier detection?
If that's the case, the documentation confused me, any suggestion on how to implement earlier tenancy detection?
https://sponsors.tenancyforlaravel.com/ this url doesn't work
When I try to create a user in a tenant context it gives me this error.
My Laravel version is 8.0
Error Call to undefined function App\Models\isNotLumen()
Hello,
I want to install Horizon. I have followed the installation instructions on https://laravel.com/docs/7.x/horizon and i have checked your documentation https://tenancy.samuelstancl.me/docs/v2/horizon/ and searched in this issues list.
It is not clear for me how to access the horizon dashboard on /horizon.
Do i have to access this via the central app or can i also access the dashboard via the tenant url's.
When i use the tenant url there is a redirect to /app with a 404 error.
Hopefully you can bring some clarification.
I have the following error:
Method Illuminate\Auth\RequestGuard::loginUsingId does not exist.
Full error here:
https://flareapp.io/share/xPQ6n4k7#F59
tenant.php:
Route::get('/impersonate/{token}', [UserImpersonationController::class, 'index']);
Route::middleware(['auth:sanctum', 'verified'])->group(function () {
Route::get('/impersonate/{user}', function (User $user) {
$redirectUrl = '/user/profile';
$token = tenancy()->impersonate(privacy_tenant(), $user->id, $redirectUrl);
//dd($token);
//dd($token);
return redirect('/impersonate/'.$token->token);
});
changing Route::middleware(['auth:sanctum'... to Route::middleware(['auth'... works like a charm.
Hi,
I followed the steps to get it working with Nova. This worked in L7. But after L8 I'm doing the same and it's not working anymore. What to change in the routes?
Nova::routes(['tenant', 'universal'])
->withAuthenticationRoutes(['tenant', 'universal'])
->withPasswordResetRoutes(['tenant', 'universal'])
->register();
laravel-permission integration section seems to have wrong code , there is no tenancy()->hook function
Laravel does auto open db connection when needed but it does not auto close simply because it doesnt know is the connection really no usage anymore. This behavior creates a unique problem in this package.
Let's see... when we enter the tenent's context, the database bootstrapper creates new db config and named it tenant
and set the default db config to it, at the same time the old connection is still there and most probably already opened for fetching the tenants table and.... it stays open but most of the time like http request or queue job, that connection will not be used anymore just stay there until the end.
It still doesn't seems a problem because when the request done everything will gone and the connection will closed also.... until someone wrote tons of bad codes causing the request and queue job run for long time and there is sufficient user to cause the system hits the db connections limit. This behavior indirectly cut the db connections capacity into half.
This is not really a big deal (only for those who will study the package they used for their project rather than just install and hopes everything goes fine), an event listener for closing the central connection can solve the problem, but i think it still great to warn developers this might happens somewhere in the document.
p/s: this issue wont exists if the tenant db is hosted in different db instance
i couldn't find any tickets/comments regarding it, so i thought i would add what i've found to help others.
so far no changes needed except for the cmnd scheduling.
--only-db
wont work "this is mostly related to how tenancy handle cmnds with args like that" ex.--option="only-db"
--only-db
--option="--only-db"
make sure to use ->withoutOverlapping();
or the db dump cmnd will overlap each other.
if u r going to schedule both central & tenant backup, do it on a different interval or the db dump cmnd will overlap each other.
$schedule->exec('php artisan backup:run && php artisan tenants:run backup:run' . $this->getTenants())->everyMinute()->runInBackground()->withoutOverlapping();
as for $this->getTenants()
check archtechx/tenancy#502 (comment)
I'm following the quickstart guide at https://tenancyforlaravel.com/docs/v3/quickstart.
But, when I'm at creating tenant using Tinker command.
$ php artisan tinker
>>> $tenant1 = Tenant::create(['id' => 'foo']);
It shows.
PHP Error: Class 'Tenant' not found
I already created Tenant model, nothing happens. Any help?
I'm not sure of all the ins and outs of the file. I am not advanced enough to really do a great job describing how to do this, but it would be GREAT to add to the documentation how to call the tenants:run command with Artisan::call()
. It is possible! I just figured it out, but it's not well documented and certainly it's something that someone else has had to figure out. I'd love to fork this repository and add it, but I'm not sure how to do it, git is not a strong point for me.
Anyway this is my use case if you want to use it as an example:
Artisan::call('tenants:run', [
'commandname' => "db:seed",
'--tenants' => ["sample"],
'--option' => ["class=SampleDatabaseSeeder"]
]);
The rough part for me was figuring out how to add the commandname
argument as I found no documentation for it and because the vendor/stancl/tenancy/src/Commands/Run.php
file has a kind of abstract name and because you can't just click through to it in the IDE ('tenants:run'
= no clicky clicky) I didn't find it until I was able to get my code close enough that an error was thrown in it and a stack trace could help me find it.
The most difficult areas on this without documentation are:
Knowing to use the commandname
argument
Knowing how to use the commandname
argument (ie: NOT --commandname
)
Knowing when to put the value in an array and when to not do it - (command name requires string
while the options and tenants require an array
.
So, if you feel it's warranted, I think it could be crazy helpful to others. If not, hopefully, I've put enough keywords in this post that someone else can find it. All the best and THANK YOU for such an incredible package.
So that you can recognize the pages better in the browser
Hi,
First, thank you for creating this awesome package!
In our case when a tenant is created a record will be added to the Tenant table but we need to postpone the creation of the tenant database as it requires approval (we have managed this behavior using additional event instead of TenantCreated
, thanks for the flexibility of this package). Thus, there will be any tenant records which the databases haven't been created yet, this causes an issue if we have additional migration for tenants, when running artisan tenants:migrate
it will raise TenantDatabaseDoesNotExistException
.
at \vendor\stancl\tenancy\src\Bootstrappers\DatabaseTenancyBootstrapper.php:30
27| if (app()->environment('local')) {
28| $database = $tenant->database()->getName();
29| if (! $tenant->database()->manager()->databaseExists($database)) {
> 30| throw new TenantDatabaseDoesNotExistException($database);
31| }
32| }
Specifically for my case above, running artisan tenants:migrate
will raise TenantDatabaseDoesNotExistException
.
It may show just a message that the database doesn't exist and continue the migration for the rest of the other tenants.
Model code:
`namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Stancl\Tenancy\Database\Models\Domain as BaseDomain;
class ModelName extends BaseDomain
{
use HasFactory;
}Controler
$model = new ModeName;
$model->save();
`
Argument 1 passed to Stancl\Tenancy\Resolvers\Contracts\CachedTenantResolver::invalidateCache() must implement interface Stancl\Tenancy\Contracts\Tenant, null given, called in D:\Saash\PMS\clientappl8\vendor\stancl\tenancy\src\Database\Concerns\InvalidatesTenantsResolverCache.php on line 29
Thank you for great package.
In the Tenants document says
If you wish to use numerical ids, change the create_tenants_table migration to use bigIncrements()
or some such column type, and set tenancy.id_generator config to null. That will disable
the ID generation altogether, falling back to the database's autoincrement mechanism.
and I wanted to use numeric tenant id so I followed the instruction(changing migration and disabling ID generator in config) and it worked well.
Next I wished to use resource syncing feature, so followed the sample codes. but when I tried to create new user in tenant route it failed with SQL error.
SQLSTATE[HY000]: General error: 1364 Field 'global_id' doesn't have a default value
...
After some debug, I found below codes at ResourceSyncing
trait.
static::creating(function (self $model) {
if (! $model->getAttribute($model->getGlobalIdentifierKeyName()) && app()->bound(UniqueIdentifierGenerator::class)) {
$model->setAttribute(
$model->getGlobalIdentifierKeyName(),
app(UniqueIdentifierGenerator::class)->generate($model)
);
}
});
It checks app()->bound(UniqueIdentifierGenerator::class)
so I enabled ID generator in config and it worked again.
I think it will be good if there is some note in doc about resource syncing feature requires ID generator.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.