Created
November 13, 2019 09:57
-
-
Save chopstik/9fcfc21de0a657986c5974fdf2abd402 to your computer and use it in GitHub Desktop.
Change database in CakePHP 3 based on request data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Based on an article by @markstory