private function renderArray($array, $prefixLines)
{
$isAssociativeArray = Piwik::isAssociativeArray($array);
// check if array contains arrays, and if not wrap the result in an extra <row> element
// (only check if this is the root renderArray call)
// NOTE: this is for backwards compatibility. before, array's were added to a new DataTable.
// if the array had arrays, they were added as multiple rows, otherwise it was treated as
// one row. removing will change API output.
$wrapInRow = $prefixLines === "\t" && self::shouldWrapArrayBeforeRendering($array, $wrapSingleValues = false, $isAssociativeArray);
// render the array
$result = "";
if ($wrapInRow) {
$result .= "{$prefixLines}<row>\n";
$prefixLines .= "\t";
}
foreach ($array as $key => $value) {
// based on the type of array & the key, determine how this node will look
if ($isAssociativeArray) {
if (strpos($key, '=') !== false) {
list($keyAttributeName, $key) = explode('=', $key, 2);
$prefix = "<row {$keyAttributeName}=\"{$key}\">";
$suffix = "</row>";
$emptyNode = "<row {$keyAttributeName}=\"{$key}\">";
} elseif (!self::isValidXmlTagName($key)) {
$prefix = "<row key=\"{$key}\">";
$suffix = "</row>";
$emptyNode = "<row key=\"{$key}\"/>";
} else {
$prefix = "<{$key}>";
$suffix = "</{$key}>";
$emptyNode = "<{$key} />";
}
} else {
$prefix = "<row>";
$suffix = "</row>";
$emptyNode = "<row/>";
}
// render the array item
if (is_array($value) || $value instanceof \stdClass) {
$result .= $prefixLines . $prefix . "\n";
$result .= $this->renderArray((array) $value, $prefixLines . "\t");
$result .= $prefixLines . $suffix . "\n";
} elseif ($value instanceof DataTable || $value instanceof Map) {
if ($value->getRowsCount() == 0) {
$result .= $prefixLines . $emptyNode . "\n";
} else {
$result .= $prefixLines . $prefix . "\n";
if ($value instanceof Map) {
$result .= $this->renderDataTableMap($value, $this->getArrayFromDataTable($value), $prefixLines);
} elseif ($value instanceof Simple) {
$result .= $this->renderDataTableSimple($this->getArrayFromDataTable($value), $prefixLines);
} else {
$result .= $this->renderDataTable($this->getArrayFromDataTable($value), $prefixLines);
}
$result .= $prefixLines . $suffix . "\n";
}
} else {
$xmlValue = self::formatValueXml($value);
if (strlen($xmlValue) != 0) {
$result .= $prefixLines . $prefix . $xmlValue . $suffix . "\n";
} else {
$result .= $prefixLines . $emptyNode . "\n";
}
}
}
if ($wrapInRow) {
$result .= substr($prefixLines, 0, strlen($prefixLines) - 1) . "</row>\n";
}
return $result;
}