Skip to content

Instantly share code, notes, and snippets.

@adinan-cenci
Last active April 9, 2024 17:57
Show Gist options
  • Save adinan-cenci/d42c8012afc7368a14cb9a2ebba75aa7 to your computer and use it in GitHub Desktop.
Save adinan-cenci/d42c8012afc7368a14cb9a2ebba75aa7 to your computer and use it in GitHub Desktop.
update-uuids.php
<?php
/**
* How to use:
*
* chmod +x update-uuids.php
* php update-uuids.php @site.stager @site.live
*
* It will output a series of sql queries to be run on stager's mysql server.
*
* OBSERVATION: remember to make a backup of stager before executing the commands.
* OBSERVATION: known issues regarding special characters such as diacritics.
*/
/**
* Retrieves the uuid from a json string of settings.
*
* @param string $settings.
* The json settings.
*
* @return string|null
* The uuid string, null if not present.
*/
function getUuid(string $settings): ?string
{
// "uuid";s:36:"b2f44a35-2a68-4a3e-bdb2-6af43398990e";
return preg_match('#"uuid";s:36:"([^"]+)";#', $settings, $matches)
? $matches[1]
: null;
}
/**
* Replaces the uuid in a json settings string for a new one.
*
* @param string $settings
* The json settings.
* @param string $newUuid
* The replacement uuid.
*
* @return string
* $settings with $newUuid in it.
*/
function replaceUuid(string $settings, string $newUuid): string
{
// "uuid";s:36:"b2f44a35-2a68-4a3e-bdb2-6af43398990e";
return preg_replace('#"uuid";s:36:"([^"]+)";#', '"uuid";s:36:"' . $newUuid . '";', $settings);
}
/**
* Return configuration that includes an uuid from the targted environment.
*
* @param string $alias
* The targted environment's drush alias.
*
* @return array
* The configuration as an associative array.
* config.name => json settings
*/
function getConfigFromEnvironment(string $alias): array
{
$command = 'drush ' . $alias . ' sqlq "SELECT c.name, c.data FROM config c WHERE c.data LIKE \'%uuid%\'"';
exec($command, $output);
$config = [];
foreach ($output as $line) {
$keyData = parseConfigTuple($line);
if (count($keyData) == 2) {
$config[$keyData[0]] = $keyData[1];
}
}
return $config;
}
/**
* Parses console output into a key/settings pair.
*
* See getConfigFromEnvironment().
*
* @param string $row
* Console output.
*
* @return array
* An array containing the cofig name and the associated settings.
*/
function parseConfigTuple(string $row): array
{
return preg_split("/\t+/", $row);
}
/**
* Generates a SQL query to update a specified configuration.
*
* @param string $configName
* The targted config's name.
* @param string $settings
* The configuration as a JSON string.
*
* @return string
* A mysql command to update the config.
*/
function generateUpdateSql(string $configName, string $settings): string
{
$settings = str_replace("'", "\'", $settings);
$sql = "UPDATE config c SET c.data = '$settings' WHERE c.name = '$configName';";
return $sql;
}
//===========================================================
if (!isset($argv[1]) || !isset($argv[2])) {
echo "please inform valid aliases as such: php update-uuids.php @site.stager @site.live \n";
die();
}
$to_alias = $argv[1];
$from_alias = $argv[2];
echo "Preparing to generate SQL queries
$to_alias <===== $from_alias\n\n";
sleep(5);
//===========================================================
//===========================================================
echo "retrieving config from $from_alias\n\n";
$from_config = getConfigFromEnvironment($from_alias);
if (!$from_config) {
echo "could not retrieve configuration from $from_alias";
die();
}
//===
echo "retrieving config from $to_alias\n\n";
$to_config = getConfigFromEnvironment($to_alias);
if (!$to_config) {
echo "could not retrieve configuration from $to_alias";
die();
}
sleep(3);
//===========================================================
//===========================================================
$queries = [];
foreach ($from_config as $name => $from_settings) {
$from_uuid = getUuid($from_settings);
// No uuid to begin with, leave it.
if (!$from_uuid) {
continue;
}
// no equivalent present on target, leave it.
if (!isset($to_config[$name])) {
continue;
}
$to_settings = $to_config[$name];
$to_uuid = getuuid($to_settings);
// uuids already match, leave it.
if ($to_uuid == $from_uuid) {
continue;
}
$new_to_settings = replaceUuid($to_settings, $from_uuid);
$queries[] = generateUpdateSql($name, $new_to_settings);
}
if (!$queries) {
echo "nothing to update";
die();
}
echo "open a session to the $to_alias mysql server and execute the following commands:\n";
echo implode("\n", $queries) . "\n\n";
echo "remember to make a backup of stager before executing those queries.";
echo "remember to run drush cr after executing the queries above and before executing drush cim\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment