Skip to content

Instantly share code, notes, and snippets.

@chopstik
Created November 13, 2019 09:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chopstik/9fcfc21de0a657986c5974fdf2abd402 to your computer and use it in GitHub Desktop.
Save chopstik/9fcfc21de0a657986c5974fdf2abd402 to your computer and use it in GitHub Desktop.
Change database in CakePHP 3 based on request data
<?php
/*
* Allow development users to switch between databases
* ...add to \App\Application::middleware
* */
$middlewareQueue->add(function (ServerRequest $request, Response $response, $next) {
$isPreviouslyAliased = false;
// restore the alias `db_alias`
if (Configure::restore('db_alias', '_cake_session_')) {
$dbAliasStored = Configure::read('App.db_alias');
$isPreviouslyAliased = !empty($dbAliasStored);
}
// post in a `db_alias` from a form or set within other controller logic
$dbAliasRequested = $request->getData('db_alias');
$isRequested = (null !== $dbAliasRequested);
// a test, implementing only in dev environment
$isDevelopment = Configure::read('App.environment') === 'development';
if ($isDevelopment && ($isPreviouslyAliased || $isRequested)) {
// presidence given to request data, before any stored alias.
if ($isRequested) {
$dbAliastoUse = $dbAliasRequested;
} elseif ($isPreviouslyAliased) {
$dbAliastoUse = $dbAliasStored;
} else {
$dbAliastoUse = 'stage';
}
// create a new dynamic db configuration, cloning a single `default` db config from config/app.php
$defaultDbConfig = ConnectionManager::getConfig('default');
$aliasedDbConfig = $defaultDbConfig;
$aliasedDbConfig['database'] = $dbAliastoUse;
$aliasedDbConfig['name'] = $dbAliastoUse;
ConnectionManager::setConfig($dbAliastoUse, $aliasedDbConfig);
$dbConnections = ConnectionManager::configured();
if (in_array($dbAliastoUse, $dbConnections)) {
// alias it to the `default` db config
ConnectionManager::alias($dbAliastoUse, 'default');
// store the `db_alias` alias for future non-async requests
Configure::store('db_alias', '_cake_session_', ['App.db_alias' => $dbAliastoUse]);
}
}
return $next($request, $response);
});
// In a logout or similar event listener, drop the db alias
if (Configure::restore('db_alias', '_cake_session_')) {
$dbAliasStored = Configure::read('App.db_alias');
if (!empty($dbAliasStored)) {
ConnectionManager::dropAlias($dbAliasStored);
}
}
@chopstik
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment