diff --git a/composer.json b/composer.json
index 8a9a63e..0638006 100644
--- a/composer.json
+++ b/composer.json
@@ -32,7 +32,7 @@
},
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "1.2.x-dev"
},
"installer-name": "components"
},
diff --git a/src/SilbinaryWolf/ArrayListExportable.php b/src/SilbinaryWolf/ArrayListExportable.php
new file mode 100644
index 0000000..0e1ad15
--- /dev/null
+++ b/src/SilbinaryWolf/ArrayListExportable.php
@@ -0,0 +1,30 @@
+ [...]))
+ *
+ * And because ArrayList doens't implement '__set_state', executing the code throws errors.
+ * So we work around this by using an ArrayListExportable to produce:
+ *
+ * ArrayListExportable::__set_state(array('items' => [...]))
+ *
+ * And implement '__set_state' to return a constructed ArrayList.
+ */
+class ArrayListExportable
+{
+ public function __construct($array = array())
+ {
+ // need to store items for var_export to recurse
+ $this->items = $array;
+ }
+
+ public static function __set_state ($array)
+ {
+ // when executed, we naruto-style body-replace with in an ArrayList
+ return new ArrayList($array['items']);
+ }
+}
diff --git a/src/SilbinaryWolf/Components/ComponentService.php b/src/SilbinaryWolf/Components/ComponentService.php
index c4f7b2a..1350634 100644
--- a/src/SilbinaryWolf/Components/ComponentService.php
+++ b/src/SilbinaryWolf/Components/ComponentService.php
@@ -90,7 +90,8 @@ public function generateTemplateCode(array $res, $parser)
}
foreach ($jsonData as $propertyName => $value) {
if (is_array($value)) {
- $value = 'new '.'ArrayList'.'('.var_export($value, true).')';
+ // export valid template logic for nested data
+ $value = self::exportNestedDataForTemplates($value);
}
$phpCodeValueParts[] = "\$_props['".$propertyName."'][] = ".$value.";";
}
@@ -185,6 +186,33 @@ public function generateTemplateCode(array $res, $parser)
return $result;
}
+ /**
+ * Recursively replace nonassociative arrays with ArrayListExportable and
+ * output with 'var_export' to produce template logic for the nested data.
+ *
+ * @param array $array The nested data to export
+ * @param bool $root Ignore this
+ * @return string Executable template logic
+ */
+ private static function exportNestedDataForTemplates(array $array, $root = true)
+ {
+ // depth first
+ foreach ($array as $prop => &$value) {
+ if (is_array($value)) {
+ $value = self::exportNestedDataForTemplates($value, false);
+ }
+ }
+ unset($value);
+
+ // json data expected to be keyed with ints, over the usual strings
+ if (isset($array[0])) {
+ // replace array with exportable array list
+ $array = new ArrayListExportable($array);
+ }
+
+ return $root ? var_export($array, true) : $array;
+ }
+
/**
* @return DBComponentField|SS_List|DataObject|ArrayData
*/
diff --git a/tests/ComponentTest.php b/tests/ComponentTest.php
index 48238de..2f6bb6d 100644
--- a/tests/ComponentTest.php
+++ b/tests/ComponentTest.php
@@ -528,6 +528,113 @@ public function testJSONPropertyErrorHandling()
}
}
+ /**
+ * Test iterating nested arrays in templates
+ */
+ public function testJSONDeeplyNested()
+ {
+ $template = <<