{"id":15021802,"url":"https://github.com/funkymed/tenant-aware-bundle","last_synced_at":"2025-04-10T20:12:24.183Z","repository":{"id":242565183,"uuid":"809007805","full_name":"funkymed/tenant-aware-bundle","owner":"funkymed","description":" Symfony bundle to handle tenant-specific configurations","archived":false,"fork":false,"pushed_at":"2024-06-03T19:38:28.000Z","size":10,"stargazers_count":23,"open_issues_count":2,"forks_count":3,"subscribers_count":4,"default_branch":"develop","last_synced_at":"2025-03-24T17:52:51.759Z","etag":null,"topics":["bundle","multitenant","symfony","tenant"],"latest_commit_sha":null,"homepage":"https://medium.com/@cyrilgeorgespereira/multi-tenant-and-symfony-b4b69c187f36","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/funkymed.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-01T12:22:16.000Z","updated_at":"2025-02-28T03:58:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"31597465-9cc8-46c3-b6cb-d197fef20453","html_url":"https://github.com/funkymed/tenant-aware-bundle","commit_stats":null,"previous_names":["funkymed/tenant-aware-bundle"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkymed%2Ftenant-aware-bundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkymed%2Ftenant-aware-bundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkymed%2Ftenant-aware-bundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkymed%2Ftenant-aware-bundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/funkymed","download_url":"https://codeload.github.com/funkymed/tenant-aware-bundle/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248288361,"owners_count":21078903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bundle","multitenant","symfony","tenant"],"created_at":"2024-09-24T19:57:05.139Z","updated_at":"2025-04-10T20:12:24.176Z","avatar_url":"https://github.com/funkymed.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tenant-aware-bundle\n\nTenant Aware Bundle will help you to manage multiple configuration of your app.\n\nThe configuration come from database.\n\n## Installation\n\n```bash\ncomposer require funkymed/tenant-aware-bundle\n```\n\ncreate your a configuration `config/packages/tenant_aware.yaml`\n\n```yaml\ntenant_aware:\n    processors:\n        - Funkymed\\TenantAwareBundle\\DependencyInjection\\Compiler\\Processor\\DummyProcessor\n        - Funkymed\\TenantAwareBundle\\DependencyInjection\\Compiler\\Processor\\DatabaseProcessor\n```\n\nModify you Kernel.php like this to use a cache by tenant\n\n```php\n\u003c?php\n\n// src/Kernel.php\n\nnamespace App;\n\nuse Funkymed\\TenantAwareBundle\\TenantAwareKernel;\nuse Symfony\\Bundle\\FrameworkBundle\\Kernel\\MicroKernelTrait;\nuse Symfony\\Component\\HttpKernel\\Kernel as BaseKernel;\n\nclass Kernel extends BaseKernel\n{\n    use MicroKernelTrait;\n    private ?string $hostname;\n\n    public function __construct(\n        string $environment,\n        bool $debug,\n        string $hostname\n    ) {\n        parent::__construct($environment, $debug);\n        $this-\u003ehostname = $hostname;\n    }\n\n    public function getCacheDir(): string\n    {\n        if ($this-\u003egetHostname()) {\n            return $this-\u003egetProjectDir().'/var/cache/'.$this-\u003eenvironment.'/'.$this-\u003egetHostname();\n        }\n        return $this-\u003egetProjectDir().'/var/cache/'.$this-\u003eenvironment;\n    }\n\n    public function getLogDir(): string\n    {\n        if ($this-\u003egetHostname()) {\n            return $this-\u003egetProjectDir().'/var/log/'.$this-\u003egetHostname();\n        }\n        return $this-\u003egetProjectDir().'/var/log';\n    }\n\n    public function getName()\n    {\n        return str_replace('-', '_', $this-\u003egetHostname());\n    }\n\n    public function getKernelParameters(): array\n    {\n        $parameters = parent::getKernelParameters();\n        $parameters['kernel.hostname'] = $this-\u003egetHostname();\n\n        return $parameters;\n    }\n    public function getHostname()\n    {\n        $hostname = $this-\u003egetHost();\n        return $hostname ? $hostname : $this-\u003ehostname;\n\n    }\n    public function getHost()\n    {\n        $possibleHostSources = array('HTTP_X_FORWARDED_HOST', 'HTTP_HOST', 'SERVER_NAME', 'SERVER_ADDR');\n        $sourceTransformations = array(\n            \"HTTP_X_FORWARDED_HOST\" =\u003e function ($value) {\n                $elements = explode(',', $value);\n                return trim(end($elements));\n            }\n        );\n        $host = '';\n        foreach ($possibleHostSources as $source) {\n            if (!empty($host)) {\n                break;\n            }\n            if (empty($_SERVER[$source])) {\n                continue;\n            }\n            $host = $_SERVER[$source];\n            if (array_key_exists($source, $sourceTransformations)) {\n                $host = $sourceTransformations[$source]($host);\n            }\n        }\n\n        // Remove port number from host\n        $host = preg_replace('/:\\d+$/', '', $host);\n\n        return trim($host);\n    }\n}\n```\n\nand then replace `bin/console` with this code to make it compatible\n\n```php\n#!/usr/bin/env php\n\u003c?php\n\n// bin/console\n\nuse App\\Kernel;\nuse Funkymed\\TenantAwareBundle\\Command\\TenantAwareApplication;\nuse Symfony\\Component\\Console\\Input\\ArgvInput;\n\nif (!is_dir(dirname(__DIR__).'/vendor')) {\n    throw new LogicException('Dependencies are missing. Try running \"composer install\".');\n}\n\nif (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {\n    throw new LogicException('Symfony Runtime is missing. Try running \"composer require symfony/runtime\".');\n}\n\nrequire_once dirname(__DIR__).'/vendor/autoload_runtime.php';\n\nreturn function (array $context) {\n    $input = new ArgvInput();\n    $env = $input-\u003egetParameterOption(['--env', '-e'], getenv('APP_ENV') ?: 'dev');\n    $debug = getenv('APP_DEBUG') !== '0' \u0026\u0026 $env !== 'prod';\n\n    // Added support for tenant\n    $hostname = $input-\u003egetParameterOption('--tenant');\n\n    $kernel = new Kernel($env, $debug, $hostname);\n    $kernel-\u003eboot();\n\n    return new TenantAwareApplication($kernel);\n\n};\n```\n\nNow you can use the default commands of symfony but with a tenant configuration\n\n```bash\nbin/console d:d:c --tenant=localhost\n```\n\nThe param tenant is the hostname you want to get the configuration\n\n### Configuration\n\nAdded configuration of your database in `.env` and `config/packages/doctrine.yaml`\n\n```.env\n# .env\nDATABASE_HOST=\"localhost\"\nDATABASE_USER=\"root\"\nDATABASE_PASSWORD=\"\"\nDATABASE_NAME=\"tenant\"\n```\n\n```yaml\ndoctrine:\n    dbal:\n        driver: 'pdo_mysql'\n        server_version: '8'\n        use_savepoints: true\n        host: '%env(resolve:DATABASE_HOST)%'\n        port: 3306\n        user: '%env(resolve:DATABASE_USER)%'\n        password: '%env(resolve:DATABASE_URL)%'\n        dbname: '%env(resolve:DATABASE_PASSWORD)%'\n```\n\n### Create tenant database\n\n```bash\nbin/console d:d:c --if-not-exist\nbin/console d:s:u -f\n```\n\nAdd content in your database to manager different hostname (see Tenant Entity)\n\n## Add your Processor\n\n### Add more service\n\nYou can process other services than the database\nYou could want to change an AWS S3 per hostame, or Redis, and or RabbitMQ\n\nJust copy `TenantAwareBundle/DependencyInjection/Compiler/Processor/DummyProcessor.php`\n\nAnd put in your `DependencyInjection/Compiler/Processor` namespace\n\nAdd in your processor what you want to repace\n\n```php\n\u003c?php\n\n// src/DependencyInjection/DependencyInjection/Compiler/Processor/DummyProcessor.php\n\nnamespace App\\DependencyInjection\\Compiler\\Processor;\n\n// use this as an exemple to create your own replacement configuration\nclass MyProcessor extends ProcessorAbstract\n{\n    public function process()\n    {\n        // get current definition\n        $definition = $this-\u003econtainer-\u003egetDefinition('doctrine.dbal.default_connection');\n        $configuration = $definition-\u003egetArguments();\n\n        // update it from the tenant information\n        $configuration[0][\"host\"] = $this-\u003etenant-\u003egetDatabaseHost();\n        $configuration[0][\"dbname\"] = $this-\u003etenant-\u003egetDatabaseName();\n        $configuration[0][\"user\"] = $this-\u003etenant-\u003egetDatabaseUser();\n        $configuration[0][\"password\"] = $this-\u003etenant-\u003egetDatabasePassword();\n\n        // replace the current configuration everything is in the cache now\n        $definition-\u003ereplaceArgument(0, $configuration[0]);\n    }\n}\n```\n\nUpdate the configuration\n\n```yaml\ntenant_aware:\n    processors:\n        - App\\DependencyInjection\\Compiler\\Processor\\MyProcessor\n```\n\nYou can add all the processors you want.\n\nYou also can replace the Entity Tenant to put the fields you need to manage your tenants.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunkymed%2Ftenant-aware-bundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffunkymed%2Ftenant-aware-bundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunkymed%2Ftenant-aware-bundle/lists"}