Commit d7b595ab authored by Nigel McNie's avatar Nigel McNie
Browse files

Ensure all config values for LEAP2A export/import are json_encoded in wrapper arrays.

It turns out I was relying on a nasty behaviour quirk of json_decode in PHP,
namely that it'll just pass strings through - in some cases. This is horribly
out of touch with the JSON specification, see these PHP bugs:

http://bugs.php.net/bug.php?id=38680 (where they broke it)
http://bugs.php.net/bug.php?id=46518

 (people complaining about it)

The solution is to wrap all configuration fields when exporting as LEAP in an
array and then json_encode that. json_decode will handle that properly in all
versions of PHP.
Signed-off-by: default avatarNigel McNie <nigel@catalyst.net.nz>
parent 0b3a10b6
......@@ -176,22 +176,22 @@ class PluginArtefactInternal extends PluginArtefact {
foreach ($configdata['artefactids'] as $id) {
$result['fields'][] = $cache[$owner][$id]->artefacttype;
}
$result['fields'] = json_encode($result['fields']);
$result['fields'] = json_encode(array($result['fields']));
}
// Email addresses are not entries in leap2a (they're elements on
// the persondata element), so we export the actual address here
// instead of an artefact ID.
if (!empty($configdata['email']) && isset($cache[$owner][$configdata['email']])) {
$result['email'] = $cache[$owner][$configdata['email']]->title;
$result['email'] = json_encode(array($cache[$owner][$configdata['email']]->title));
}
if (!empty($configdata['profileicon'])) {
$result['artefactid'] = intval($configdata['profileicon']);
$result['artefactid'] = json_encode(array(intval($configdata['profileicon'])));
}
if (isset($configdata['introtext'])) {
$result['introtext'] = $configdata['introtext'];
$result['introtext'] = json_encode(array($configdata['introtext']));
}
}
......
......@@ -287,8 +287,6 @@ abstract class PluginBlocktype extends Plugin {
* @return array The configuration required to import the block again later
*/
public static function export_blockinstance_config(BlockInstance $bi) {
// TODO: check the quoting of json_encoded quotes in output
// TODO: encode artefactids properly
$configdata = $bi->get('configdata');
if (is_array($configdata)) {
......@@ -299,10 +297,6 @@ abstract class PluginBlocktype extends Plugin {
unset($configdata['id']);
unset($configdata['change']);
unset($configdata['new']);
foreach ($configdata as $key => &$value) {
$value = json_encode($value);
}
}
else {
$configdata = array();
......@@ -311,6 +305,31 @@ abstract class PluginBlocktype extends Plugin {
return $configdata;
}
/**
* Exports configuration data the format required for LEAP2A export.
*
* This format is XML, and as the exporter can't generate complicated XML
* structures, we have to json_encode all the values.
*
* Furthermore, because of how json_encode and json_decode "work" in PHP,
* we make double sure that our values are all inside arrays. See the
* craziness that is PHP bugs 38680 and 46518 for more information.
*
* The array is assumed to be there when importing, so if you're overriding
* this method and don't wrap any values in an array, you can expect import
* to growl at you and not import your config.
*
* @param BlockInstance $bi The block instance to export config for
* @return array The configuration required to import the block again later
*/
public static function export_blockinstance_config_leap(BlockInstance $bi) {
$configdata = call_static_method(generate_class_name('blocktype', $bi->get('blocktype')), 'export_blockinstance_config', $bi);
foreach ($configdata as $key => &$value) {
$value = json_encode(array($value));
}
return $configdata;
}
/**
* Creates a block instance from a given configuration.
*
......
......@@ -267,9 +267,9 @@ class PluginExportLeap extends PluginExport {
foreach ($config['columns'] as &$column) {
foreach ($column as &$blockinstance) {
if (isset($blockinstance['config']['artefactid'])) {
// json_encoded value of null is the string 'null', don't include these
if ($blockinstance['config']['artefactid'] != 'null') {
$blockinstance['config']['artefactid'] = 'portfolio:artefact' . $blockinstance['config']['artefactid'];
$id = json_decode($blockinstance['config']['artefactid']);
if ($id[0] != null) {
$blockinstance['config']['artefactid'] = json_encode(array('portfolio:artefact' . $id[0]));
}
else {
$blockinstance['config']['artefactid'] = null;
......@@ -277,7 +277,7 @@ class PluginExportLeap extends PluginExport {
}
else if (isset($blockinstance['config']['artefactids'])) {
$ids = json_decode($blockinstance['config']['artefactids']);
$blockinstance['config']['artefactids'] = json_encode(array_map(array($this, 'prepend_artefact_identifier'), $ids));
$blockinstance['config']['artefactids'] = json_encode(array(array_map(array($this, 'prepend_artefact_identifier'), $ids[0])));
}
}
}
......
......@@ -643,7 +643,14 @@ class PluginImportLeap extends PluginImport {
'config' => array()
);
foreach ($configelements as $element) {
$config['columns'][$col][$row]['config'][$element->getName()] = json_decode((string)$element);
$value = json_decode((string)$element);
if (is_array($value) && isset($value[0])) {
$config['columns'][$col][$row]['config'][$element->getName()] = $value[0];
}
else {
$this->trace(" Value for {$element->getName()} is not an array, ignoring (value follows below)");
$this->trace($value);
}
}
$row++;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment