placetopay / cerberus
Allows multiple tenants on Laravel applications
Installs: 4 530
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 7
Forks: 5
Open Issues: 1
Requires
- php: ^8.0
- ext-json: *
- eduarguz/shift-php-cs: ^3.0
- spatie/laravel-multitenancy: ^3.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- laravel/legacy-factories: ^1.0.4
- orchestra/testbench: ^6.0
- phpunit/phpunit: ^9.5
- dev-main
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- v2.2.0
- 2.1.0
- 2.0.2
- v2.0.1
- v2.0.0
- 1.8.7
- v1.8.6
- v1.8.5
- v1.8.4
- v1.8.3
- v1.8.2
- v1.8.1
- v1.8.0
- v1.7.0
- v1.6.0
- v1.5
- v1.4
- v1.3
- v1.2
- v1.1
- v1.0
- dev-feature/suffix-public-url
- dev-bugfix/ignore-index-php-from-domain
- dev-feature/upgrade-php-cs-fixer
- dev-feature/cache-prefix
- dev-fix/mailer-loading
- dev-develop
- dev-feature/github-actions
- dev-feature/upgrade-spatie-multitenancy
- dev-feature/add-reset-tasks
- dev-feature/command-without-slashes
- dev-feature/merge-2.0.2
- dev-feature/adds-jobs-retry-request
- dev-bugfix/update-logger-context
- dev-feature/add-switch-mailer-task
- dev-bugfix/fix-storage-suffixed
- dev-feature/set-default-timezone-for-dates
- dev-feature/vapor-validation
- dev-feature/update-tasks
This package is auto-updated.
Last update: 2025-01-31 14:03:33 UTC
README
This package is based on the third version of package spatie/laravel-multitenancy
.
Because it is a customization, it requires override steps mentioned below for proper installation.
More information about the package.
This package aims to standardize the configuration of the tenants
table of the landlord database, in addition to reducing the number of queries made to the same database by using cache.
Prerequsites
php8.0+
Laravel 8.0+
Installation
This package can be installed via composer:
composer require "placetopay/cerberus:^3.0"
Publishing the config file
You must publish the config file:
php artisan vendor:publish --tag="multitenancy-config"
Publishing the migrate file
php artisan vendor:publish --tag="multitenancy-migrations"
Create storage folder by tenancy
This is allowed to run only if the application has the configuration variable multitenancy.suffix_storage_path set to true.
php artisan tenants:skeleton-storage --tenant=*
How to use
After publish the config and migrations files, you need to create a new connection in config/database.php
,
This connection will allow the management of the landlord database, in which the tenants of the application will be stored.
'connections' => [
...
'landlord' => [
'driver' => env('DB_LANDLORD_DRIVER', 'mysql'),
'url' => env('DB_LANDLORD_URL'),
'host' => env('DB_LANDLORD_HOST', '127.0.0.1'),
'port' => env('DB_LANDLORD_PORT', '3306'),
'database' => env('DB_LANDLORD_DATABASE', 'forge'),
'username' => env('DB_LANDLORD_USERNAME', 'forge'),
'password' => env('DB_LANDLORD_PASSWORD', ''),
'unix_socket' => env('DB_LANDLORD_SOCKET', ''),
//...
],
...
]
The migration of the landlord table in relation to the spatie package was modified, adding a config
field of json type,
with which it's intended to centralize the configuration that is carried out in front of each tenant,
in this field you can define the connection to the database using the following structure.
{ "app": { "url": "...", "name": "..." }, "database": { "connections": { "mysql": { "host": "...", "port": "...", "database": "...", "username": "..." } } } }
You can add all configurations that you needed, this json will be convert in array dot structure and then will be set in the laravel config.
Additionally, the variable APP_IDENTIFIER
is provided in the file config/multitenancy.php
which will be the project identifier
Execute migrations
To execute the migrations of the landlord database, it's necessary to specify the connection and the path to the folder where the migrations are located:
php artisan migrate --database=landlord --path=database/migrations/laandlord/
Jobs
You need to update the connection and tables for jobs and failed_jobs, config/queue.php
:
[
//...
'connections' => [
'database' => [
'connection' => env('DB_LANDLORD_CONNECTION'),
'driver' => 'database',
'table' => '{project_identifier}_jobs',
'queue' => 'default',
'retry_after' => 90,
'after_commit' => false,
],
//...
]
//...
]
//...
'failed' => [
'driver' => env('QUEUE_FAILED_DRIVER', 'database'),
'database' => env('DB_LANDLORD_CONNECTION', 'landlord'),
'table' => '{project_identifier}_failed_jobs',
],
Storage
This package will overwrite the Storage Facade by default, setting a tenant's name as a prefix for folders that use
with Storage Facade, if you need to suffix the storage_path()
method too, you need to set to true the variable
suffix_storage_path
in config/multitenant.php
file.
How change the commands
To execute any command for one tenant you need to execute the next command structure
php artisan tenants:artisan "command:execute" --tenant={tenant_domain}
Addig the --tenant={tenant_domain}
flag, will be executed the commando only for the specific tenant, without this it will execute by each tenant.
translatable attributes
You can use the translate method in the tenant model to translate some keys from the config JSON.
This method uses the app locale and fallback to search the correct values from the JSON,
addionaly you should use a config/tenant.php
file to set default values for translations in case if doesn't
exist in the JSON data:
Json data from database
{ "tenant": { "terms_and_privacy": { "es_CO": "Al continuar acepto la <a class='underline' target='_blank' href='https: //www.placetopay.com/web/politicas-de-privacidad'> política de protección</a> de datos personales de <strong>Empresas del Grupo Evertec y sus filiales y subsidiarias</strong>" } } }
Default values in config/tenant.php
:
return [
'terms_and_privacy' => [
'en' => sprintf('By continuing, you accept the <a class="underline" target="_blank" href="%s"> personal data protection policy </a> of <strong>Companies of the Evertec Group and its affiliates and subsidiaries</strong>', 'https://www.placetopay.com/web/politicas-de-privacidad'),
'it' => sprintf('Continuando ad accettare la <a class="underline" target="_blank" href="%s"> politica di protezione dei dati personali </a> di <strong>Società del Gruppo Evertec e delle sue affiliate e sussidiarie</strong>', 'https://www.placetopay.com/web/politicas-de-privacidad'),
'pt' => sprintf('Ao continuar, você aceita a <a class="underline" target="_blank" href="%s"> política de proteção de dados pessoais </a> da <strong>Empresas do Grupo Evertec e suas afiliadas e subsidiárias</strong>', 'https://www.placetopay.com/web/politicas-de-privacidad'),
],
]
Example of use:
app('currentTenant')->translate('terms_and_privacy')
Clear cache remotely
Probably you need to clear the app cache when you update the tenant information,
to do this Cerberus publish a new POST route clean-cache
that you can call from another application.
this route use middleware to validate if the application can be connected, this is an example of how you need to make the request
$data = [
'action' => 'cache:clear', //allowed action to perform
];
$signature = hash_hmac('sha256', json_encode($data), config('multitenancy.middleware_key'));
$url = 'https://tenant1.app.com/clean-cache';
Http::withHeaders(['Signature' => $signature])->post($url, $data);
You need to set this header in the request to clean the cache