PHP code example of mrkindy / multi-tenant-wordpress

1. Go to this page and download the library: Download mrkindy/multi-tenant-wordpress library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

mrkindy / multi-tenant-wordpress example snippets


use MrKindy\MultiTenantWordPress\Bootstrap\Bootstrap;
use MrKindy\MultiTenantWordPress\Config\Config;

Bootstrap::boot(new Config(
    controlDatabaseHost: getenv('CONTROL_DB_HOST') ?: 'control-db',
    controlDatabasePort: (int) (getenv('CONTROL_DB_PORT') ?: 3306),
    controlDatabaseName: getenv('CONTROL_DB_NAME') ?: 'wordpress_control',
    controlDatabaseUser: getenv('CONTROL_DB_USER') ?: 'wordpress_control',
    controlDatabasePassword: getenv('CONTROL_DB_PASSWORD') ?: '',
    encryptionKey: getenv('TENANT_ENCRYPTION_KEY') ?: '',
    secretProvider: Config::SECRET_PROVIDER_ENCRYPTED,
    enableDebugging: true,
    cacheProvider: Config::CACHE_PROVIDER_ARRAY,
    trustedDomainSuffixes: ['*.example.com', '*.mrkindy.com'],
    allowLocalhost: false,
    cacheTtlSeconds: 60,
    // Provisioning configuration (optional)
    wpPath: '/var/www/bedrock/web/wp',
    databaseNamePrefix: 'tenant_',
    databaseUserPrefix: 'tenant_',
));

use MrKindy\MultiTenantWordPress\DTO\CreateTenant;
use MrKindy\MultiTenantWordPress\DTO\ProvisioningAdminCredentials;
use MrKindy\MultiTenantWordPress\Encryption\EncryptionService;
use MrKindy\MultiTenantWordPress\Provisioning\DatabaseManager;
use MrKindy\MultiTenantWordPress\Provisioning\DatabaseNameGenerator;
use MrKindy\MultiTenantWordPress\Provisioning\TenantProvisioner;
use MrKindy\MultiTenantWordPress\Provisioning\WordPressBootstrapper;
use MrKindy\MultiTenantWordPress\Provisioning\WordPressInstaller;
use MrKindy\MultiTenantWordPress\Provisioning\DefaultDataSeeder;
use MrKindy\MultiTenantWordPress\Provisioning\AdminAccountSeeder;
use MrKindy\MultiTenantWordPress\Provisioning\AdditionalSeeder;
use MrKindy\MultiTenantWordPress\Repository\PdoTenantRepository;
use MrKindy\MultiTenantWordPress\Secrets\EncryptedSecretProvider;

// Services
$encryption = new EncryptionService($encryptionKey);
$repository = new PdoTenantRepository($controlPdo);
$databaseManager = new DatabaseManager($controlPdo);
$secretProvider = new EncryptedSecretProvider($encryption);
$bootstrapper = new WordPressBootstrapper('/var/www/bedrock');

$provisioner = new TenantProvisioner(
    $repository,
    $secretProvider,
    $databaseManager,
    new WordPressInstaller($bootstrapper),
    new DefaultDataSeeder($bootstrapper),
    new AdminAccountSeeder($bootstrapper),
    new AdditionalSeeder($bootstrapper),
);

// Create tenant with encrypted password
$tenantPassword = bin2hex(random_bytes(32));
$tenant = $repository->create(new CreateTenant(
    domain: 'shop.example.com',
    databaseHost: 'tenant-db.internal',
    databasePort: 3306,
    databaseName: 'tenant_shop',
    databaseUser: 'tenant_shop_user',
    encryptedDatabasePassword: $encryption->encrypt($tenantPassword),
    status: 'pending',
    plan: 'business',
    metadata: [],
));

// Provision
$result = $provisioner->provision(
    $tenant,
    new ProvisioningAdminCredentials(
        username: 'admin',
        email: '[email protected]',
        password: bin2hex(random_bytes(16)),
    )
);

echo "Provisioned: {$result->tenant->domain}\n";
echo "Admin: {$result->adminCredentials->username}\n";

use MrKindy\MultiTenantWordPress\Events\TenantCreated;
use MrKindy\MultiTenantWordPress\Provisioning\ProvisionTenantListener;
use MrKindy\MultiTenantWordPress\Queue\SynchronousJobDispatcher;

// Create event dispatcher (or use Laravel/Symfony)
$dispatcher = new InMemoryEventDispatcher();

// Subscribe listener
$listener = new ProvisionTenantListener(
    new SynchronousJobDispatcher(), // Replace with your queue
);
$dispatcher->subscribe(TenantCreated::class, $listener);

// Dispatch event after creating tenant
$dispatcher->dispatch(new TenantCreated($tenant));

use MrKindy\MultiTenantWordPress\DTO\CreateTenant;
use MrKindy\MultiTenantWordPress\DTO\UpdateTenant;
use MrKindy\MultiTenantWordPress\Repository\PdoTenantRepository;

$repository = new PdoTenantRepository($writerPdo);

$tenant = $repository->create(new CreateTenant(
    domain: 'shop.example.com',
    databaseHost: 'tenant-db-42.internal',
    databasePort: 3306,
    databaseName: 'tenant_42',
    databaseUser: 'tenant_42_user',
    encryptedDatabasePassword: 'TENANT_42_DATABASE_PASSWORD',
    status: 'active',
    plan: 'business',
    metadata: ['uploads_path' => '/srv/uploads/tenant-42'],
));

$tenant = $repository->update(new UpdateTenant(
    id: $tenant->id,
    domain: 'shop.example.com',
    databaseHost: 'tenant-db-42.internal',
    databasePort: 3306,
    databaseName: 'tenant_42',
    databaseUser: 'tenant_42_user',
    encryptedDatabasePassword: 'TENANT_42_DATABASE_PASSWORD',
    status: 'suspended',
    plan: 'business',
    metadata: ['uploads_path' => '/srv/uploads/tenant-42'],
));

$deleted = $repository->delete('42');

use MrKindy\MultiTenantWordPress\Config\Config;

$config = new Config(
    // ... other settings ...
    storageBasePath: '/var/www/tenants',
    storageFolderLength: 32,
);

$tenant = $repository->findByDomain('shop.example.com');
$storagePath = $tenant->storageFolderPath;  // /var/www/tenants/tenant_42_a7x9k2m8pQ3LwRtZvBnJy/

// In your wp-config.php or application configuration
define('UPLOADS', $tenant->storageFolderPath . '/uploads');



$config = new Config(
    // Control database settings...
    encryptionKey: getenv('TENANT_ENCRYPTION_KEY') ?: '',
    secretProvider: Config::SECRET_PROVIDER_AWS,
    awsRegion: 'eu-central-1',
    awsSecretPasswordKey: 'password',
);

$key = EncryptionService::generateKey();
$encryption = new EncryptionService($key);

$ciphertext = $encryption->encrypt('secret');
$plaintext = $encryption->decrypt($ciphertext);

try {
    Bootstrap::boot($config);
} catch (InvalidDomainException | TenantNotFoundException) {
    http_response_code(404);
    exit('Site not found.');
} catch (TenantSuspendedException) {
    http_response_code(403);
    exit('Site unavailable.');
} catch (Throwable) {
    http_response_code(503);
    exit('Service temporarily unavailable.');
}
sql
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP ON tenant_db.* TO 'tenant_user'@'%';