Skip to content

Instantly share code, notes, and snippets.

@nadavkav
Last active September 25, 2021 09:12
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 nadavkav/dd12d171995bb3e8888aa2b016114ef4 to your computer and use it in GitHub Desktop.
Save nadavkav/dd12d171995bb3e8888aa2b016114ef4 to your computer and use it in GitHub Desktop.
Fix logstore_standard_log.other field data format (JSON_UNESCAPED_UNICODE)
<?php
/**
* When using standard JSON format instead of PHP serialised data in the 'other' database field,
* Non English (Hebrew) letters are save in \uFFFF Unicode hexa human unreadable format.
* We need to fix this, to allow human-readable output when using block "configurable reports".
*
* @package logstore_standard_log
* @copyright 2021 Nadav Kavalerchik <nadav.kavalerchik@weizmann.ac.il>
* @auther Nadav Kavalerchik
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require_once (__DIR__.'/../../../../../config.php');
require_once("{$CFG->libdir}/clilib.php");
raise_memory_limit(MEMORY_UNLIMITED);
list($options, $unrecognized) = cli_get_params(
array(
'help' => false,
'convertto' => 'json_unescaped_unicode',
'source' => 'json',
'debug' => 'off',
'customsql' => '',
'execute' => false
),
array(
'h' => 'help',
'c' => 'convertto',
's' => 'source',
'd' => 'debug',
'e' => 'execute',
)
);
if ($options['help'] || empty($options['convertto'])) {
$help = <<<EOT
When using standard JSON format instead of PHP serialised data in the 'other' database field,
Non English (Hebrew) letters are save in \uFFFF Unicode Hexadecimal human unreadable format.
We need to fix this, to allow human-readable output when using SQL "configurable reports" block.
Options:
-h, --help Print out this help
-c, --convertto Convert other field data to "json_unescaped_unicode" or "serialize"
-s, --source Convert from "json" or "serialize" (disabled in code, as we auto detect)
-d, --debug Debug "on"
--customsql Added at the end of the SQL query (like "ORDER BY id DESC LIMIT 30" OR "WHERE id=29921")
-e, --execute Update logstore_standard_log.other DB field data.
Example:
\$sudo -u www-data /usr/bin/php admin/cli/fix_other_field_data.php -c=json_unescaped_unicode -d=on -e
EOT;
echo $help;
die;
}
// Get current logstore_standard other field type (jsonformat) state.
$otherdatatype = get_config('logstore_standard','jsonformat');
// Fix all table entries. (can take a long time!)
$stdlog = $DB->get_recordset_sql('SELECT id, other FROM {logstore_standard_log} '.$options['customsql']);
foreach ($stdlog as $entry) {
$fixvalue = '';
$intype = '';
if (unserialize($entry->other) !== false) { // Try to detect type of data format.
//if ($otherdatatype) { // Assume we wish to convert to current format.
//if ($options['source'] === 'serialize') { // User decide.
$rawvalue = unserialize($entry->other);
$intype = 'serialized';
} else {
$rawvalue = json_decode($entry->other);
$intype = 'json';
}
if ($options['convertto'] === 'json_unescaped_unicode') {
$fixvalue = json_encode($rawvalue, JSON_UNESCAPED_UNICODE);
if ($options['debug'] === 'on') {
echo 'ID = '.$entry->id.PHP_EOL;
echo 'IN('.$intype.') = '. $entry->other . PHP_EOL;
echo 'OUT(json_unescaped_unicode) = '. $fixvalue . PHP_EOL;
}
}
if ($options['convertto'] === 'serialize') {
$fixvalue = serialize($rawvalue);
if ($options['debug'] === 'on') {
echo 'ID = '.$entry->id.PHP_EOL;
echo 'IN('.$intype.') = '. $entry->other . PHP_EOL;
echo 'OUT(serialize) = '. $fixvalue . PHP_EOL;
}
}
if (!empty($fixvalue) && $options['execute']) {
$ok = $DB->set_field('logstore_standard_log', 'other', $fixvalue, ['id' => $entry->id]);
if ($options['debug'] === 'on') {
echo 'Fixed' . PHP_EOL;
}
}
echo PHP_EOL;
}
$stdlog->close();
echo '==='.PHP_EOL.'Finished updating '.count($stdlog). ' logstore_standard_log entries'.PHP_EOL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment