setDescription('Fix Biest #7789');
$this->addArgument('table', InputArgument::REQUIRED, 'database table');
$this->addArgument('column', InputArgument::REQUIRED, 'table column');
$this->addArgument('where', InputArgument::OPTIONAL, 'where clause');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
ini_set('default_charset', 'utf-8');
$io = new SymfonyStyle($input, $output);
$table = $input->getArgument('table');
$column = $input->getArgument('column');
$where = $input->getArgument('where');
$db = \DBManager::get();
$io->title($table);
// get primary keys
$result = $db->query("SHOW KEYS FROM $table WHERE Key_name = 'PRIMARY'");
$keys = [];
while ($data = $result->fetch(\PDO::FETCH_ASSOC)) {
$keys[] = $data['Column_name'];
}
// retrieve and convert data
$result = $db->query(
'SELECT `' . implode('`,`', $keys) . "`, `$column` FROM `$table` WHERE " . ($where ?: '1')
);
while ($data = $result->fetch(\PDO::FETCH_ASSOC)) {
$content = unserialize(\legacy_studip_utf8decode($data[$column]));
if ($content === false) {
// try to fix string length denotations
$fixed = preg_replace_callback(
'/s:([0-9]+):\"(.*?)\";/s',
function ($matches) {
return 's:' . strlen($matches[2]) . ':"' . $matches[2] . '";';
},
$data[$column]
);
$content = unserialize(\legacy_studip_utf8decode($fixed));
}
if ($content !== false) {
// encode all data
$json = json_encode($this->legacy_studip_utf8encode($content), true);
$query = "UPDATE `$table` SET `$column` = " . $db->quote($json) . "\n WHERE ";
$where_query = [];
foreach ($keys as $key) {
$where_query[] = "`$key` = " . $db->quote($data[$key]);
}
$q = $query . implode(' AND ', $where_query);
$db->exec($q);
$io->writeln("$q");
} else {
$io->writeln(sprintf('Could not convert: %s', print_r($data, 1)));
}
}
return Command::SUCCESS;
}
private function legacy_studip_utf8encode($data)
{
if (is_array($data)) {
$new_data = [];
foreach ($data as $key => $value) {
$key = $this->legacy_studip_utf8encode($key);
$new_data[$key] = $this->legacy_studip_utf8encode($value);
}
return $new_data;
}
if (!\preg_match('/[\200-\377]/', $data) && !\preg_match("'[0-9]+;'", $data)) {
return $data;
} else {
return \mb_decode_numericentity(
\mb_convert_encoding($data, 'UTF-8', 'WINDOWS-1252'),
[0x100, 0xffff, 0, 0xffff],
'UTF-8'
);
}
}
}